From 0acd4d8b5c887b0ca4d8ffbb17fc259c68df8ddd Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:55:02 +0100 Subject: [PATCH 1/5] Pristine zlib-ng 2.0.7 sources, from tarball --- .../zlib-ng-2.0.7/.gitattributes | 6 + .../.github/workflows/analyze.yml | 78 +++ .../zlib-ng-2.0.7/.github/workflows/cmake.yml | 508 ++++++++++++++++++ .../.github/workflows/codeql.yml | 41 ++ .../.github/workflows/configure.yml | 192 +++++++ .../.github/workflows/libpng.yml | 51 ++ .../zlib-ng-2.0.7/.github/workflows/nmake.yml | 68 +++ .../zlib-ng-2.0.7/.github/workflows/pigz.yml | 131 +++++ .../.github/workflows/pkgcheck.yml | 154 ++++++ .../.github/workflows/release.yml | 100 ++++ internal-complibs/zlib-ng-2.0.7/.gitignore | 88 +++ .../zlib-ng-2.0.7/crc32_comb_tbl._h | 300 ----------- internal-complibs/zlib-ng-2.0.7/crc32_tbl._h | 444 --------------- .../zlib-ng-2.0.7/inffixed_tbl._h | 94 ---- internal-complibs/zlib-ng-2.0.7/trees_tbl._h | 132 ----- internal-complibs/zlib-ng-2.0.7/zconf.h | 201 ------- .../zlib-ng-2.0.7/zconf.h.included | 201 ------- 17 files changed, 1417 insertions(+), 1372 deletions(-) create mode 100644 internal-complibs/zlib-ng-2.0.7/.gitattributes create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml create mode 100644 internal-complibs/zlib-ng-2.0.7/.gitignore delete mode 100644 internal-complibs/zlib-ng-2.0.7/crc32_comb_tbl._h delete mode 100644 internal-complibs/zlib-ng-2.0.7/crc32_tbl._h delete mode 100644 internal-complibs/zlib-ng-2.0.7/inffixed_tbl._h delete mode 100644 internal-complibs/zlib-ng-2.0.7/trees_tbl._h delete mode 100644 internal-complibs/zlib-ng-2.0.7/zconf.h delete mode 100644 internal-complibs/zlib-ng-2.0.7/zconf.h.included diff --git a/internal-complibs/zlib-ng-2.0.7/.gitattributes b/internal-complibs/zlib-ng-2.0.7/.gitattributes new file mode 100644 index 000000000..3b35744b0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.gitattributes @@ -0,0 +1,6 @@ +* text=auto +*.c text +*.h text +Makefile text +configure text eol=lf +testCVEinputs.sh text eol=lf diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml new file mode 100644 index 000000000..cbdea0e50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml @@ -0,0 +1,78 @@ +name: Static Analysis +on: [push, pull_request] +jobs: + static-analysis: + name: GCC + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y gcc-10 + + - name: Generate project files + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CC: gcc-10 + CFLAGS: + -fanalyzer + -Werror + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-malloc-leak + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-tainted-array-index + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release > /dev/null + + Clang: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y clang-tools + + - name: Generate project files + run: | + scan-build --status-bugs \ + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CI: true + + - name: Compile source code + run: | + scan-build --status-bugs \ + cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml new file mode 100644 index 000000000..456f7bb1f --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml @@ -0,0 +1,508 @@ +name: CMake +on: [push, pull_request] +env: + TERM: xterm-256color + GTEST_COLOR: 1 +jobs: + cmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + + - name: Ubuntu GCC ASAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_SANITIZER=Address + codecov: ubuntu_gcc + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_sprefix + + - name: Ubuntu GCC Compat Symbol Prefix + os: ubuntu-latest + compiler: gcc + cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_compat_sprefix + + - name: Ubuntu GCC -O3 OSB + os: ubuntu-latest + compiler: gcc + build-dir: ../build + build-src-dir: ../zlib-ng + codecov: ubuntu_gcc_osb + cflags: -O3 + + - name: Ubuntu GCC -O1 No Unaligned UBSAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_o1 + cflags: -O1 + + - name: Ubuntu GCC 32-bit + os: ubuntu-latest + compiler: gcc + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 + packages: gcc-multilib g++-multilib + codecov: ubuntu_gcc_m32 + + - name: Ubuntu GCC No CTZLL + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF + codecov: ubuntu_gcc_no_ctzll + + - name: Ubuntu GCC No CTZ + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF + codecov: ubuntu_gcc_no_ctz + + - name: Ubuntu GCC No AVX2 UBSAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_avx2 + + - name: Ubuntu GCC No SSE2 UBSAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse2 + + - name: Ubuntu GCC No SSE4 UBSAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_SSE4=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse4 + + - name: Ubuntu GCC No PCLMULQDQ UBSAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_pclmulqdq + + - name: Ubuntu GCC Compat No Opt ASAN + os: ubuntu-latest + compiler: gcc + cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address + codecov: ubuntu_gcc_compat_no_opt + cflags: -DNOT_TWEAK_COMPILER + + - name: Ubuntu GCC ARM SF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf + + - name: Ubuntu GCC ARM SF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf_compat_no_opt + + - name: Ubuntu GCC ARM HF No ACLE ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_acle + + - name: Ubuntu GCC ARM HF No NEON No ACLE ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_ACLE=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_neon + + - name: Ubuntu GCC ARM HF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_compat_no_opt + + - name: Ubuntu GCC AARCH64 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64 + + - name: Ubuntu GCC AARCH64 No ACLE UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_acle + + - name: Ubuntu GCC AARCH64 No NEON UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_neon + + - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_compat_no_opt + + - name: Ubuntu GCC PPC + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc_no_power8 + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake + packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross + ldflags: -static + codecov: ubuntu_gcc_ppc64 + + - name: Ubuntu GCC PPC64LE + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross + codecov: ubuntu_gcc_ppc64le + + - name: Ubuntu GCC SPARC64 + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake + packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross + ldflags: -static + codecov: ubuntu_gcc_sparc64 + + - name: Ubuntu GCC S390X ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X No vectorized CRC32 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x_no_crc32 + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC ASAN + os: z15 + compiler: gcc + cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC Compat UBSAN + os: z15 + compiler: gcc + cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc_compat + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu Clang S390X DFLTCC MSAN + os: z15 + compiler: clang-11 + cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu MinGW i686 + os: ubuntu-22.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake + packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 + ldflags: -static + codecov: ubuntu_gcc_mingw_i686 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu MinGW x86_64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake + packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 + ldflags: -static + codecov: ubuntu_gcc_mingw_x86_64 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu 20.04 Clang + os: ubuntu-20.04 + compiler: clang-6.0 + packages: clang-6.0 + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang + + - name: Ubuntu Clang Inflate Strict + os: ubuntu-latest + compiler: clang-11 + cmake-args: -DWITH_INFLATE_STRICT=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_strict + + - name: Ubuntu Clang Inflate Allow Invalid Dist + os: ubuntu-latest + compiler: clang-11 + cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_allow_invalid_dist + + - name: Ubuntu Clang Reduced Memory + os: ubuntu-latest + compiler: clang-11 + cmake-args: -DWITH_REDUCED_MEM=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_reduced_mem + + - name: Ubuntu Clang Memory Map + os: ubuntu-latest + compiler: clang-11 + cflags: -DUSE_MMAP + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_mmap + + - name: Ubuntu Clang Debug + os: ubuntu-latest + compiler: clang-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_debug + build-config: Debug + + - name: Ubuntu Clang MSAN + os: ubuntu-latest + compiler: clang-11 + cmake-args: -GNinja -DWITH_SANITIZER=Memory + packages: ninja-build clang-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + # https://github.com/llvm/llvm-project/issues/55785 + msan-options: use_sigaltstack=0 + + - name: Windows MSVC 2022 v143 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 + + - name: Windows MSVC 2022 v143 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 + + - name: Windows MSVC 2022 v142 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 + + - name: Windows MSVC 2022 v142 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 + + - name: Windows MSVC 2022 v141 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 + + - name: Windows MSVC 2022 v141 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 + + - name: Windows MSVC 2019 v140 Win32 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 + + - name: Windows MSVC 2019 v140 Win64 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 + + - name: Windows MSVC ARM No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM + + - name: Windows MSVC ARM64 No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + + - name: Windows GCC + os: windows-latest + compiler: gcc + cmake-args: -G Ninja + codecov: win64_gcc + + - name: Windows GCC Compat No Opt + os: windows-latest + compiler: gcc + cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF + codecov: win64_gcc_compat_no_opt + + - name: macOS Clang ASAN + os: macos-latest + compiler: clang + cmake-args: -DWITH_SANITIZER=Address + codecov: macos_clang + + - name: macOS GCC UBSAN + os: macos-latest + compiler: gcc-10 + cmake-args: -DWITH_SANITIZER=Undefined + packages: gcc@10 + gcov-exec: gcov-10 + codecov: macos_gcc + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs + # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. + if: contains(matrix.name, 'MinGW') == false + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add repositories (Wine) + if: contains(matrix.packages, 'wine32') + run: sudo dpkg --add-architecture i386 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} + + - name: Install packages (Windows) + if: runner.os == 'Windows' + run: | + # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. + # zlib-ng does not need perl, so simply remove it. + choco uninstall --no-progress strawberryperl + choco install --no-progress ninja ${{ matrix.packages }} + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Initialize Wine + # Prevent parallel test jobs from initializing Wine at the same time + if: contains(matrix.packages, 'wine') + run: wineboot --init + + - name: Generate project files + shell: bash + # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources + run: | + cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=ON \ + -DWITH_MAINTAINER_WARNINGS=ON \ + ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} + + - name: Run test cases + # Don't run tests on Windows ARM + if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: ${{ matrix.build-dir || '.' }} + env: + ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 + + - name: Generate coverage report + if: matrix.codecov + shell: bash + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root ${{ matrix.build-src-dir || '.' }} \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + directory: ${{ matrix.build-src-dir || '.' }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml new file mode 100644 index 000000000..1cfa4d7fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + schedule: + - cron: "27 17 * * 0" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ cpp ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml new file mode 100644 index 000000000..6fa2e3c69 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml @@ -0,0 +1,192 @@ +name: Configure +on: [push, pull_request] +jobs: + configure: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + configure-args: --warn + + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + configure-args: --warn + + - name: Ubuntu GCC OSB + os: ubuntu-latest + compiler: gcc + configure-args: --warn + build-dir: ../build + build-src-dir: ../zlib-ng + + - name: Ubuntu GCC Compat No Opt + os: ubuntu-latest + compiler: gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + + - name: Ubuntu GCC ARM SF + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM SF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No ACLE + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-acle + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No NEON + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-neon --without-acle + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No ACLE + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-acle + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No NEON + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-neon + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 Compat No Opt + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + compiler: powerpc64-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + compiler: powerpc64le-linux-gnu-gcc + configure-args: --warn + chost: powerpc64le-linux-gnu + packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross + + - name: Ubuntu GCC S390X + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X DFLTCC + os: z15 + compiler: gcc + configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu GCC S390X DFLTCC Compat + os: z15 + compiler: gcc + configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: macOS GCC + os: macOS-latest + compiler: gcc-11 + configure-args: --warn + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Generate project files + run: | + mkdir ${{ matrix.build-dir || '.not-used' }} + cd ${{ matrix.build-dir || '.' }} + ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CHOST: ${{ matrix.chost }} + EMU_RUN: ${{ matrix.emu-run }} + CI: true + + - name: Compile source code + run: make -j2 + working-directory: ${{ matrix.build-dir }} + + - name: Run test cases + run: make test + working-directory: ${{ matrix.build-dir }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (configure) + path: | + **/Makefile + ${{ matrix.build-dir || '.' }}/configure.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml new file mode 100644 index 000000000..c5fea574f --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml @@ -0,0 +1,51 @@ +name: Libpng +on: [push, pull_request] +jobs: + libpng: + name: Ubuntu Clang + runs-on: ubuntu-latest + steps: + - name: Checkout repository (zlib-ng) + uses: actions/checkout@v3 + + - name: Generate project files (zlib-ng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_COMPAT=ON \ + -DZLIB_ENABLE_TESTS=OFF + env: + CC: clang + CFLAGS: -fPIC + CI: true + + - name: Compile source code (zlib-ng) + run: cmake --build . -j2 --config Release + + - name: Checkout repository (libpng) + uses: actions/checkout@v3 + with: + repository: glennrp/libpng + path: libpng + + - name: Generate project files (libpng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DPNG_TESTS=ON \ + -DPNG_STATIC=OFF \ + -DZLIB_INCLUDE_DIR=.. \ + -DZLIB_LIBRARY=$PWD/../libz.a + working-directory: libpng + env: + CC: clang + CI: true + + - name: Compile source code (libpng) + run: cmake --build . -j2 --config Release + working-directory: libpng + + - name: Run test cases (libpng) + run: ctest -j2 -C Release --output-on-failure --max-width 120 + working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml new file mode 100644 index 000000000..38e669093 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml @@ -0,0 +1,68 @@ +name: NMake +on: [push, pull_request] +jobs: + nmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows NMake x86 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86 + + - name: Windows NMake x64 compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes + + - name: Windows NMake x64 Symbol Prefix + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 Symbol Prefix Compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + + - name: Windows NMake ARM No Test + os: windows-2022 + makefile: win32/Makefile.arm + arch: x86_arm + + - name: Windows NMake ARM64 No Test + os: windows-2022 + makefile: win32/Makefile.a64 + arch: x86_arm64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup development environment + uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + + - name: Compile source code + shell: cmd + run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} + + - name: Run test cases + shell: cmd + # Don't run tests on Windows ARM + if: contains(matrix.arch, 'arm') == false + run: | + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml new file mode 100644 index 000000000..be4e1ce50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml @@ -0,0 +1,131 @@ +name: Pigz +on: [push, pull_request] +jobs: + pigz: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz + + - name: Ubuntu Clang No Optim + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_optim + cmake-args: -DWITH_OPTIM=OFF + + # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 + - name: Ubuntu Clang No Threads + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_threads + cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_pigz_aarch64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Generate project files + run: | + cmake ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_ROOT=../.. \ + -DWITH_CODE_COVERAGE=ON \ + -DWITH_MAINTAINER_WARNINGS=ON + working-directory: test/pigz + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} + working-directory: test/pigz + + - name: Run test cases + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: test/pigz + + - name: Generate coverage report + if: matrix.codecov + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root . \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml new file mode 100644 index 000000000..a335c1f04 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml @@ -0,0 +1,154 @@ +name: Package Check +on: [push, pull_request] +jobs: + pkgcheck: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + + - name: Ubuntu GCC -m32 + os: ubuntu-latest + compiler: gcc + packages: gcc-multilib g++-multilib + cmake-args: -DCMAKE_C_FLAGS=-m32 + cflags: -m32 + ldflags: -m32 + + - name: Ubuntu GCC ARM SF + os: ubuntu-latest + chost: arm-linux-gnueabi + compiler: arm-linux-gnueabi-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake + packages: qemu gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + chost: aarch64-linux-gnu + compiler: aarch64-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake + packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + chost: powerpc-linux-gnu + compiler: powerpc-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + chost: powerpc64le-linux-gnu + compiler: powerpc64le-linux-gnu-gcc + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross + + - name: macOS Clang + os: macOS-11 + compiler: clang + + - name: macOS Clang Native + os: macOS-11 + compiler: clang + cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON + configure-args: --native + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ + abigail-tools \ + diffoscope \ + ninja-build + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja diffoscope ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Select Xcode version (macOS) + # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports + # AppleClang linking with libtool using -D argument + # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 + if: runner.os == 'macOS' + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '11.7.0' + + - name: Compare builds + run: sh test/pkgcheck.sh + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Compare builds (compat) + run: sh test/pkgcheck.sh --zlib-compat + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --refresh-if + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI (compat) + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --zlib-compat --refresh-if + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} + path: | + **/*.abi + btmp1/configure.log + btmp1/CMakeFiles/CMakeOutput.log + btmp1/CMakeFiles/CMakeError.log + btmp2/configure.log + btmp2/CMakeFiles/CMakeOutput.log + btmp2/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml new file mode 100644 index 000000000..b64933cc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release +on: + push: + tags: + - '*' +jobs: + release: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows MSVC Win32 + os: windows-latest + compiler: cl + cmake-args: -A Win32 + deploy-name: win-x86 + + - name: Windows MSVC Win32 Compat + os: windows-latest + compiler: cl + cmake-args: -A Win32 -DZLIB_COMPAT=ON + deploy-name: win-x86-compat + + - name: Windows MSVC Win64 + os: windows-latest + compiler: cl + cmake-args: -A x64 + deploy-name: win-x86-64 + + - name: Windows MSVC Win64 Compat + os: windows-latest + compiler: cl + cmake-args: -A x64 -DZLIB_COMPAT=ON + deploy-name: win-x86-64-compat + + - name: Windows MSVC ARM + os: windows-latest + compiler: cl + cmake-args: -A ARM + deploy-name: win-arm + + - name: Windows MSVC ARM Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM -DZLIB_COMPAT=ON + deploy-name: win-arm-compat + + - name: Windows MSVC ARM64 + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + deploy-name: win-arm64 + + - name: Windows MSVC ARM64 Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM64 -DZLIB_COMPAT=ON + deploy-name: win-arm64-compat + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set environment variables + shell: bash + run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + + - name: Generate project files + shell: bash + run: | + cmake . ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DZLIB_ENABLE_TESTS=ON \ + -DCMAKE_INSTALL_PREFIX=out \ + -DINSTALL_UTILS=ON + env: + CC: ${{ matrix.compiler }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release --target install + + - name: Package release (Windows) + if: runner.os == 'Windows' + run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md + working-directory: out + + - name: Upload release (Windows) + uses: svenstaro/upload-release-action@v2 + if: runner.os == 'Windows' + with: + asset_name: zlib-ng-${{ matrix.deploy-name }}.zip + file: zlib-ng-${{ matrix.deploy-name }}.zip + tag: ${{env.tag}} + repo_token: ${{ secrets.GITHUB_TOKEN }} + overwrite: true + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.0.7/.gitignore b/internal-complibs/zlib-ng-2.0.7/.gitignore new file mode 100644 index 000000000..bf420e572 --- /dev/null +++ b/internal-complibs/zlib-ng-2.0.7/.gitignore @@ -0,0 +1,88 @@ +*.diff +*.patch +*.orig +*.rej + +*~ +*.a +*.lo +*.o +*.dylib + +*.gcda +*.gcno +*.gcov + +/adler32_test +/adler32_testsh +/crc32_test +/crc32_testsh +/example +/example64 +/examplesh +/libz.so* +/libz-ng.so* +/makefixed +/minigzip +/minigzip64 +/minigzipsh +/switchlevels +/zlib.pc +/zlib-ng.pc +/CVE-2003-0107 + +.DS_Store +*_fuzzer +*.obj +*.exe +*.pdb +*.exp +*.lib +*.dll +*.res +foo.gz +*.manifest +*.opensdf +*.sln +*.sdf +*.vcxproj +*.vcxproj.filters +.vs + +CMakeCache.txt +CMakeFiles +Testing +/*.cmake +*.stackdump +*._h +zconf.h +zconf.h.cmakein +zconf.h.included +zconf-ng.h +zconf-ng.h.cmakein +ztest* + +configure.log +a.out + +/Makefile +/arch/arm/Makefile +/arch/generic/Makefile +/arch/power/Makefile +/arch/x86/Makefile +.kdev4 +*.kdev4 + +/Debug +/example.dir +/minigzip.dir +/zlib.dir +/zlibstatic.dir +/win32/Debug +/build/ +/build[.-]*/ +/btmp[12]/ +/pkgtmp[12]/ + +/.idea +/cmake-build-debug diff --git a/internal-complibs/zlib-ng-2.0.7/crc32_comb_tbl._h b/internal-complibs/zlib-ng-2.0.7/crc32_comb_tbl._h deleted file mode 100644 index 43818c3e0..000000000 --- a/internal-complibs/zlib-ng-2.0.7/crc32_comb_tbl._h +++ /dev/null @@ -1,300 +0,0 @@ -#ifndef CRC32_COMB_TBL_H_ -#define CRC32_COMB_TBL_H_ - -/* crc32_comb_tbl.h -- zero operators table for CRC combine - * Generated automatically by makecrct.c - */ - -static const uint32_t crc_comb[32][32] = -{ - { - 0x77073096, 0xee0e612c, 0x076dc419, 0x0edb8832, 0x1db71064, - 0x3b6e20c8, 0x76dc4190, 0xedb88320, 0x00000001, 0x00000002, - 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, - 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, - 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, - 0x00400000, 0x00800000 - }, - { - 0x191b3141, 0x32366282, 0x646cc504, 0xc8d98a08, 0x4ac21251, - 0x958424a2, 0xf0794f05, 0x3b83984b, 0x77073096, 0xee0e612c, - 0x076dc419, 0x0edb8832, 0x1db71064, 0x3b6e20c8, 0x76dc4190, - 0xedb88320, 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, - 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, - 0x00004000, 0x00008000 - }, - { - 0xb8bc6765, 0xaa09c88b, 0x8f629757, 0xc5b428ef, 0x5019579f, - 0xa032af3e, 0x9b14583d, 0xed59b63b, 0x01c26a37, 0x0384d46e, - 0x0709a8dc, 0x0e1351b8, 0x1c26a370, 0x384d46e0, 0x709a8dc0, - 0xe1351b80, 0x191b3141, 0x32366282, 0x646cc504, 0xc8d98a08, - 0x4ac21251, 0x958424a2, 0xf0794f05, 0x3b83984b, 0x77073096, - 0xee0e612c, 0x076dc419, 0x0edb8832, 0x1db71064, 0x3b6e20c8, - 0x76dc4190, 0xedb88320 - }, - { - 0xccaa009e, 0x4225077d, 0x844a0efa, 0xd3e51bb5, 0x7cbb312b, - 0xf9766256, 0x299dc2ed, 0x533b85da, 0xa6770bb4, 0x979f1129, - 0xf44f2413, 0x33ef4e67, 0x67de9cce, 0xcfbd399c, 0x440b7579, - 0x8816eaf2, 0xcb5cd3a5, 0x4dc8a10b, 0x9b914216, 0xec53826d, - 0x03d6029b, 0x07ac0536, 0x0f580a6c, 0x1eb014d8, 0x3d6029b0, - 0x7ac05360, 0xf580a6c0, 0x30704bc1, 0x60e09782, 0xc1c12f04, - 0x58f35849, 0xb1e6b092 - }, - { - 0xae689191, 0x87a02563, 0xd4314c87, 0x73139f4f, 0xe6273e9e, - 0x173f7b7d, 0x2e7ef6fa, 0x5cfdedf4, 0xb9fbdbe8, 0xa886b191, - 0x8a7c6563, 0xcf89cc87, 0x44629f4f, 0x88c53e9e, 0xcafb7b7d, - 0x4e87f0bb, 0x9d0fe176, 0xe16ec4ad, 0x19ac8f1b, 0x33591e36, - 0x66b23c6c, 0xcd6478d8, 0x41b9f7f1, 0x8373efe2, 0xdd96d985, - 0x605cb54b, 0xc0b96a96, 0x5a03d36d, 0xb407a6da, 0xb37e4bf5, - 0xbd8d91ab, 0xa06a2517 - }, - { - 0xf1da05aa, 0x38c50d15, 0x718a1a2a, 0xe3143454, 0x1d596ee9, - 0x3ab2ddd2, 0x7565bba4, 0xeacb7748, 0x0ee7e8d1, 0x1dcfd1a2, - 0x3b9fa344, 0x773f4688, 0xee7e8d10, 0x078c1c61, 0x0f1838c2, - 0x1e307184, 0x3c60e308, 0x78c1c610, 0xf1838c20, 0x38761e01, - 0x70ec3c02, 0xe1d87804, 0x18c1f649, 0x3183ec92, 0x6307d924, - 0xc60fb248, 0x576e62d1, 0xaedcc5a2, 0x86c88d05, 0xd6e01c4b, - 0x76b13ed7, 0xed627dae - }, - { - 0x8f352d95, 0xc51b5d6b, 0x5147bc97, 0xa28f792e, 0x9e6ff41d, - 0xe7aeee7b, 0x142cdab7, 0x2859b56e, 0x50b36adc, 0xa166d5b8, - 0x99bcad31, 0xe8085c23, 0x0b61be07, 0x16c37c0e, 0x2d86f81c, - 0x5b0df038, 0xb61be070, 0xb746c6a1, 0xb5fc8b03, 0xb0881047, - 0xba6126cf, 0xafb34bdf, 0x841791ff, 0xd35e25bf, 0x7dcd4d3f, - 0xfb9a9a7e, 0x2c4432bd, 0x5888657a, 0xb110caf4, 0xb95093a9, - 0xa9d02113, 0x88d14467 - }, - { - 0x33fff533, 0x67ffea66, 0xcfffd4cc, 0x448eafd9, 0x891d5fb2, - 0xc94bb925, 0x49e6740b, 0x93cce816, 0xfce8d66d, 0x22a0aa9b, - 0x45415536, 0x8a82aa6c, 0xce745299, 0x4799a373, 0x8f3346e6, - 0xc5178b8d, 0x515e115b, 0xa2bc22b6, 0x9e09432d, 0xe763801b, - 0x15b60677, 0x2b6c0cee, 0x56d819dc, 0xadb033b8, 0x80116131, - 0xdb53c423, 0x6dd68e07, 0xdbad1c0e, 0x6c2b3e5d, 0xd8567cba, - 0x6bddff35, 0xd7bbfe6a - }, - { - 0xce3371cb, 0x4717e5d7, 0x8e2fcbae, 0xc72e911d, 0x552c247b, - 0xaa5848f6, 0x8fc197ad, 0xc4f2291b, 0x52955477, 0xa52aa8ee, - 0x9124579d, 0xf939a97b, 0x290254b7, 0x5204a96e, 0xa40952dc, - 0x9363a3f9, 0xfdb641b3, 0x201d8527, 0x403b0a4e, 0x8076149c, - 0xdb9d2f79, 0x6c4b58b3, 0xd896b166, 0x6a5c648d, 0xd4b8c91a, - 0x72009475, 0xe40128ea, 0x13735795, 0x26e6af2a, 0x4dcd5e54, - 0x9b9abca8, 0xec447f11 - }, - { - 0x1072db28, 0x20e5b650, 0x41cb6ca0, 0x8396d940, 0xdc5cb4c1, - 0x63c86fc3, 0xc790df86, 0x5450b94d, 0xa8a1729a, 0x8a33e375, - 0xcf16c0ab, 0x455c8717, 0x8ab90e2e, 0xce031a1d, 0x4777327b, - 0x8eee64f6, 0xc6adcfad, 0x562a991b, 0xac553236, 0x83db622d, - 0xdcc7c21b, 0x62fe8277, 0xc5fd04ee, 0x508b0f9d, 0xa1161f3a, - 0x995d3835, 0xe9cb762b, 0x08e7ea17, 0x11cfd42e, 0x239fa85c, - 0x473f50b8, 0x8e7ea170 - }, - { - 0xf891f16f, 0x2a52e49f, 0x54a5c93e, 0xa94b927c, 0x89e622b9, - 0xc8bd4333, 0x4a0b8027, 0x9417004e, 0xf35f06dd, 0x3dcf0bfb, - 0x7b9e17f6, 0xf73c2fec, 0x35095999, 0x6a12b332, 0xd4256664, - 0x733bca89, 0xe6779512, 0x179e2c65, 0x2f3c58ca, 0x5e78b194, - 0xbcf16328, 0xa293c011, 0x9e568663, 0xe7dc0a87, 0x14c9134f, - 0x2992269e, 0x53244d3c, 0xa6489a78, 0x97e032b1, 0xf4b16323, - 0x3213c007, 0x6427800e - }, - { - 0x88b6ba63, 0xca1c7287, 0x4f49e34f, 0x9e93c69e, 0xe6568b7d, - 0x17dc10bb, 0x2fb82176, 0x5f7042ec, 0xbee085d8, 0xa6b00df1, - 0x96111da3, 0xf7533d07, 0x35d77c4f, 0x6baef89e, 0xd75df13c, - 0x75cae439, 0xeb95c872, 0x0c5a96a5, 0x18b52d4a, 0x316a5a94, - 0x62d4b528, 0xc5a96a50, 0x5023d2e1, 0xa047a5c2, 0x9bfe4dc5, - 0xec8d9dcb, 0x026a3dd7, 0x04d47bae, 0x09a8f75c, 0x1351eeb8, - 0x26a3dd70, 0x4d47bae0 - }, - { - 0x5ad8a92c, 0xb5b15258, 0xb013a2f1, 0xbb5643a3, 0xaddd8107, - 0x80ca044f, 0xdae50edf, 0x6ebb1bff, 0xdd7637fe, 0x619d69bd, - 0xc33ad37a, 0x5d04a0b5, 0xba09416a, 0xaf638495, 0x85b60f6b, - 0xd01d1897, 0x7b4b376f, 0xf6966ede, 0x365ddbfd, 0x6cbbb7fa, - 0xd9776ff4, 0x699fd9a9, 0xd33fb352, 0x7d0e60e5, 0xfa1cc1ca, - 0x2f4885d5, 0x5e910baa, 0xbd221754, 0xa13528e9, 0x991b5793, - 0xe947a967, 0x09fe548f - }, - { - 0xb566f6e2, 0xb1bceb85, 0xb808d14b, 0xab60a4d7, 0x8db04fef, - 0xc011999f, 0x5b52357f, 0xb6a46afe, 0xb639d3bd, 0xb702a13b, - 0xb5744437, 0xb1998e2f, 0xb8421a1f, 0xabf5327f, 0x8c9b62bf, - 0xc247c33f, 0x5ffe803f, 0xbffd007e, 0xa48b06bd, 0x92670b3b, - 0xffbf1037, 0x240f262f, 0x481e4c5e, 0x903c98bc, 0xfb083739, - 0x2d616833, 0x5ac2d066, 0xb585a0cc, 0xb07a47d9, 0xbb8589f3, - 0xac7a15a7, 0x83852d0f - }, - { - 0x9d9129bf, 0xe053553f, 0x1bd7ac3f, 0x37af587e, 0x6f5eb0fc, - 0xdebd61f8, 0x660bc5b1, 0xcc178b62, 0x435e1085, 0x86bc210a, - 0xd6094455, 0x77638eeb, 0xeec71dd6, 0x06ff3ded, 0x0dfe7bda, - 0x1bfcf7b4, 0x37f9ef68, 0x6ff3ded0, 0xdfe7bda0, 0x64be7d01, - 0xc97cfa02, 0x4988f245, 0x9311e48a, 0xfd52cf55, 0x21d498eb, - 0x43a931d6, 0x875263ac, 0xd5d5c119, 0x70da8473, 0xe1b508e6, - 0x181b178d, 0x30362f1a - }, - { - 0x2ee43a2c, 0x5dc87458, 0xbb90e8b0, 0xac50d721, 0x83d0a803, - 0xdcd05647, 0x62d1aacf, 0xc5a3559e, 0x5037ad7d, 0xa06f5afa, - 0x9bafb3b5, 0xec2e612b, 0x032dc417, 0x065b882e, 0x0cb7105c, - 0x196e20b8, 0x32dc4170, 0x65b882e0, 0xcb7105c0, 0x4d930dc1, - 0x9b261b82, 0xed3d3145, 0x010b64cb, 0x0216c996, 0x042d932c, - 0x085b2658, 0x10b64cb0, 0x216c9960, 0x42d932c0, 0x85b26580, - 0xd015cd41, 0x7b5a9cc3 - }, - { - 0x1b4511ee, 0x368a23dc, 0x6d1447b8, 0xda288f70, 0x6f2018a1, - 0xde403142, 0x67f164c5, 0xcfe2c98a, 0x44b49555, 0x89692aaa, - 0xc9a35315, 0x4837a06b, 0x906f40d6, 0xfbaf87ed, 0x2c2e099b, - 0x585c1336, 0xb0b8266c, 0xba014a99, 0xaf739373, 0x859620a7, - 0xd05d470f, 0x7bcb885f, 0xf79710be, 0x345f273d, 0x68be4e7a, - 0xd17c9cf4, 0x79883fa9, 0xf3107f52, 0x3d51f8e5, 0x7aa3f1ca, - 0xf547e394, 0x31fec169 - }, - { - 0xbce15202, 0xa2b3a245, 0x9e1642cb, 0xe75d83d7, 0x15ca01ef, - 0x2b9403de, 0x572807bc, 0xae500f78, 0x87d118b1, 0xd4d33723, - 0x72d76807, 0xe5aed00e, 0x102ca65d, 0x20594cba, 0x40b29974, - 0x816532e8, 0xd9bb6391, 0x6807c163, 0xd00f82c6, 0x7b6e03cd, - 0xf6dc079a, 0x36c90975, 0x6d9212ea, 0xdb2425d4, 0x6d394de9, - 0xda729bd2, 0x6f9431e5, 0xdf2863ca, 0x6521c1d5, 0xca4383aa, - 0x4ff60115, 0x9fec022a - }, - { - 0xff08e5ef, 0x2560cd9f, 0x4ac19b3e, 0x9583367c, 0xf0776ab9, - 0x3b9fd333, 0x773fa666, 0xee7f4ccc, 0x078f9fd9, 0x0f1f3fb2, - 0x1e3e7f64, 0x3c7cfec8, 0x78f9fd90, 0xf1f3fb20, 0x3896f001, - 0x712de002, 0xe25bc004, 0x1fc68649, 0x3f8d0c92, 0x7f1a1924, - 0xfe343248, 0x271962d1, 0x4e32c5a2, 0x9c658b44, 0xe3ba10c9, - 0x1c0527d3, 0x380a4fa6, 0x70149f4c, 0xe0293e98, 0x1b237b71, - 0x3646f6e2, 0x6c8dedc4 - }, - { - 0x6f76172e, 0xdeec2e5c, 0x66a95af9, 0xcd52b5f2, 0x41d46da5, - 0x83a8db4a, 0xdc20b0d5, 0x633067eb, 0xc660cfd6, 0x57b099ed, - 0xaf6133da, 0x85b361f5, 0xd017c5ab, 0x7b5e8d17, 0xf6bd1a2e, - 0x360b321d, 0x6c16643a, 0xd82cc874, 0x6b2896a9, 0xd6512d52, - 0x77d35ce5, 0xefa6b9ca, 0x043c75d5, 0x0878ebaa, 0x10f1d754, - 0x21e3aea8, 0x43c75d50, 0x878ebaa0, 0xd46c7301, 0x73a9e043, - 0xe753c086, 0x15d6874d - }, - { - 0x56f5cab9, 0xadeb9572, 0x80a62ca5, 0xda3d5f0b, 0x6f0bb857, - 0xde1770ae, 0x675fe71d, 0xcebfce3a, 0x460e9a35, 0x8c1d346a, - 0xc34b6e95, 0x5de7db6b, 0xbbcfb6d6, 0xacee6bed, 0x82add19b, - 0xde2aa577, 0x67244caf, 0xce48995e, 0x47e034fd, 0x8fc069fa, - 0xc4f1d5b5, 0x5292ad2b, 0xa5255a56, 0x913bb2ed, 0xf906639b, - 0x297dc177, 0x52fb82ee, 0xa5f705dc, 0x909f0df9, 0xfa4f1db3, - 0x2fef3d27, 0x5fde7a4e - }, - { - 0x385993ac, 0x70b32758, 0xe1664eb0, 0x19bd9b21, 0x337b3642, - 0x66f66c84, 0xcdecd908, 0x40a8b451, 0x815168a2, 0xd9d3d705, - 0x68d6a84b, 0xd1ad5096, 0x782ba76d, 0xf0574eda, 0x3bdf9bf5, - 0x77bf37ea, 0xef7e6fd4, 0x058dd9e9, 0x0b1bb3d2, 0x163767a4, - 0x2c6ecf48, 0x58dd9e90, 0xb1bb3d20, 0xb8077c01, 0xab7ffe43, - 0x8d8efac7, 0xc06cf3cf, 0x5ba8e1df, 0xb751c3be, 0xb5d2813d, - 0xb0d4043b, 0xbad90e37 - }, - { - 0xb4247b20, 0xb339f001, 0xbd02e643, 0xa174cac7, 0x999893cf, - 0xe84021df, 0x0bf145ff, 0x17e28bfe, 0x2fc517fc, 0x5f8a2ff8, - 0xbf145ff0, 0xa559b9a1, 0x91c27503, 0xf8f5ec47, 0x2a9adecf, - 0x5535bd9e, 0xaa6b7b3c, 0x8fa7f039, 0xc43ee633, 0x530cca27, - 0xa619944e, 0x97422edd, 0xf5f55bfb, 0x309bb1b7, 0x6137636e, - 0xc26ec6dc, 0x5fac8bf9, 0xbf5917f2, 0xa5c329a5, 0x90f7550b, - 0xfa9fac57, 0x2e4e5eef - }, - { - 0x695186a7, 0xd2a30d4e, 0x7e371cdd, 0xfc6e39ba, 0x23ad7535, - 0x475aea6a, 0x8eb5d4d4, 0xc61aafe9, 0x57445993, 0xae88b326, - 0x8660600d, 0xd7b1c65b, 0x74128af7, 0xe82515ee, 0x0b3b2d9d, - 0x16765b3a, 0x2cecb674, 0x59d96ce8, 0xb3b2d9d0, 0xbc14b5e1, - 0xa3586d83, 0x9dc1dd47, 0xe0f2bccf, 0x1a947fdf, 0x3528ffbe, - 0x6a51ff7c, 0xd4a3fef8, 0x7236fbb1, 0xe46df762, 0x13aae885, - 0x2755d10a, 0x4eaba214 - }, - { - 0x66bc001e, 0xcd78003c, 0x41810639, 0x83020c72, 0xdd751ea5, - 0x619b3b0b, 0xc3367616, 0x5d1dea6d, 0xba3bd4da, 0xaf06aff5, - 0x857c59ab, 0xd189b517, 0x78626c6f, 0xf0c4d8de, 0x3af8b7fd, - 0x75f16ffa, 0xebe2dff4, 0x0cb4b9a9, 0x19697352, 0x32d2e6a4, - 0x65a5cd48, 0xcb4b9a90, 0x4de63361, 0x9bcc66c2, 0xece9cbc5, - 0x02a291cb, 0x05452396, 0x0a8a472c, 0x15148e58, 0x2a291cb0, - 0x54523960, 0xa8a472c0 - }, - { - 0xb58b27b3, 0xb0674927, 0xbbbf940f, 0xac0e2e5f, 0x836d5aff, - 0xddabb3bf, 0x6026613f, 0xc04cc27e, 0x5be882bd, 0xb7d1057a, - 0xb4d30cb5, 0xb2d71f2b, 0xbedf3817, 0xa6cf766f, 0x96efea9f, - 0xf6aed37f, 0x362ca0bf, 0x6c59417e, 0xd8b282fc, 0x6a1403b9, - 0xd4280772, 0x732108a5, 0xe642114a, 0x17f524d5, 0x2fea49aa, - 0x5fd49354, 0xbfa926a8, 0xa4234b11, 0x93379063, 0xfd1e2687, - 0x214d4b4f, 0x429a969e - }, - { - 0xfe273162, 0x273f6485, 0x4e7ec90a, 0x9cfd9214, 0xe28a2269, - 0x1e654293, 0x3cca8526, 0x79950a4c, 0xf32a1498, 0x3d252f71, - 0x7a4a5ee2, 0xf494bdc4, 0x32587dc9, 0x64b0fb92, 0xc961f724, - 0x49b2e809, 0x9365d012, 0xfdbaa665, 0x20044a8b, 0x40089516, - 0x80112a2c, 0xdb535219, 0x6dd7a273, 0xdbaf44e6, 0x6c2f8f8d, - 0xd85f1f1a, 0x6bcf3875, 0xd79e70ea, 0x744de795, 0xe89bcf2a, - 0x0a469815, 0x148d302a - }, - { - 0xd3c98813, 0x7ce21667, 0xf9c42cce, 0x28f95fdd, 0x51f2bfba, - 0xa3e57f74, 0x9cbbf8a9, 0xe206f713, 0x1f7ce867, 0x3ef9d0ce, - 0x7df3a19c, 0xfbe74338, 0x2cbf8031, 0x597f0062, 0xb2fe00c4, - 0xbe8d07c9, 0xa66b09d3, 0x97a715e7, 0xf43f2d8f, 0x330f5d5f, - 0x661ebabe, 0xcc3d757c, 0x430becb9, 0x8617d972, 0xd75eb4a5, - 0x75cc6f0b, 0xeb98de16, 0x0c40ba6d, 0x188174da, 0x3102e9b4, - 0x6205d368, 0xc40ba6d0 - }, - { - 0xf7d6deb4, 0x34dcbb29, 0x69b97652, 0xd372eca4, 0x7d94df09, - 0xfb29be12, 0x2d227a65, 0x5a44f4ca, 0xb489e994, 0xb262d569, - 0xbfb4ac93, 0xa4185f67, 0x9341b88f, 0xfdf2775f, 0x2095e8ff, - 0x412bd1fe, 0x8257a3fc, 0xdfde41b9, 0x64cd8533, 0xc99b0a66, - 0x4847128d, 0x908e251a, 0xfa6d4c75, 0x2fab9eab, 0x5f573d56, - 0xbeae7aac, 0xa62df319, 0x972ae073, 0xf524c6a7, 0x31388b0f, - 0x6271161e, 0xc4e22c3c - }, - { - 0xedb88320, 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, - 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, - 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, - 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000 - }, - { - 0x76dc4190, 0xedb88320, 0x00000001, 0x00000002, 0x00000004, - 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, - 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, - 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, - 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000 - }, - { - 0x1db71064, 0x3b6e20c8, 0x76dc4190, 0xedb88320, 0x00000001, - 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, - 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, - 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, - 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, - 0x04000000, 0x08000000 - } -}; - -#endif /* CRC32_COMB_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.0.7/crc32_tbl._h b/internal-complibs/zlib-ng-2.0.7/crc32_tbl._h deleted file mode 100644 index ee2030c6c..000000000 --- a/internal-complibs/zlib-ng-2.0.7/crc32_tbl._h +++ /dev/null @@ -1,444 +0,0 @@ -#ifndef CRC32_TBL_H_ -#define CRC32_TBL_H_ - -/* crc32_tbl.h -- tables for rapid CRC calculation - * Generated automatically by makecrct.c - */ - -static const uint32_t crc_table[8][256] = -{ - { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, - 0x2d02ef8d - }, - { - 0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, - 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, - 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, - 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, - 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, - 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, - 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, - 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, - 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, - 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, - 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, - 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, - 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, - 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, - 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, - 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, - 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, - 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, - 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, - 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, - 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, - 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, - 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, - 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, - 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, - 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, - 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, - 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, - 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, - 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, - 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, - 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, - 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, - 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, - 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, - 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, - 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, - 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, - 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, - 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, - 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, - 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, - 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, - 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, - 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, - 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, - 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, - 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, - 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, - 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, - 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, - 0x9324fd72 - }, - { - 0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, - 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, - 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, - 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, - 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, - 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, - 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, - 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, - 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, - 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, - 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, - 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, - 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, - 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, - 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, - 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, - 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, - 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, - 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, - 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, - 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, - 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, - 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, - 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, - 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, - 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, - 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, - 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, - 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, - 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, - 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, - 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, - 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, - 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, - 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, - 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, - 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, - 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, - 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, - 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, - 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, - 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, - 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, - 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, - 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, - 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, - 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, - 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, - 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, - 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, - 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, - 0xbe9834ed - }, - { - 0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, - 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, - 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, - 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, - 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, - 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, - 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, - 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, - 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, - 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, - 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, - 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, - 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, - 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, - 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, - 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, - 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, - 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, - 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, - 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, - 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, - 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, - 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, - 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, - 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, - 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, - 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, - 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, - 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, - 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, - 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, - 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, - 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, - 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, - 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, - 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, - 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, - 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, - 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, - 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, - 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, - 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, - 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, - 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, - 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, - 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, - 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, - 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, - 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, - 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, - 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, - 0xde0506f1 - }, - { - 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, - 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, - 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, - 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, - 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, - 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, - 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, - 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, - 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, - 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, - 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, - 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, - 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, - 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, - 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, - 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, - 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, - 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, - 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, - 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, - 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, - 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, - 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, - 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, - 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, - 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, - 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, - 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, - 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, - 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, - 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, - 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, - 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, - 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, - 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, - 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, - 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, - 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, - 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, - 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, - 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, - 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, - 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, - 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, - 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, - 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, - 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, - 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, - 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, - 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, - 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, - 0x8def022d - }, - { - 0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, - 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, - 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, - 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, - 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, - 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, - 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, - 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, - 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, - 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, - 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, - 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, - 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, - 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, - 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, - 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, - 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, - 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, - 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, - 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, - 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, - 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, - 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, - 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, - 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, - 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, - 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, - 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, - 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, - 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, - 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, - 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, - 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, - 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, - 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, - 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, - 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, - 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, - 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, - 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, - 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, - 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, - 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, - 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, - 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, - 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, - 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, - 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, - 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, - 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, - 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, - 0x72fd2493 - }, - { - 0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, - 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, - 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, - 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, - 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, - 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, - 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, - 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, - 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, - 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, - 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, - 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, - 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, - 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, - 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, - 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, - 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, - 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, - 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, - 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, - 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, - 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, - 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, - 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, - 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, - 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, - 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, - 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, - 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, - 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, - 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, - 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, - 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, - 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, - 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, - 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, - 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, - 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, - 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, - 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, - 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, - 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, - 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, - 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, - 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, - 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, - 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, - 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, - 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, - 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, - 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, - 0xed3498be - }, - { - 0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, - 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, - 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, - 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, - 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, - 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, - 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, - 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, - 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, - 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, - 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, - 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, - 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, - 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, - 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, - 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, - 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, - 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, - 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, - 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, - 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, - 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, - 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, - 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, - 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, - 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, - 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, - 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, - 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, - 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, - 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, - 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, - 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, - 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, - 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, - 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, - 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, - 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, - 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, - 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, - 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, - 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, - 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, - 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, - 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, - 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, - 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, - 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, - 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, - 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, - 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, - 0xf10605de - } -}; - -#endif /* CRC32_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.0.7/inffixed_tbl._h b/internal-complibs/zlib-ng-2.0.7/inffixed_tbl._h deleted file mode 100644 index 7292fa06e..000000000 --- a/internal-complibs/zlib-ng-2.0.7/inffixed_tbl._h +++ /dev/null @@ -1,94 +0,0 @@ -/* inffixed_tbl.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - -/* WARNING: this file should *not* be used by applications. - * It is part of the implementation of this library and is - * subject to change. Applications should only use zlib.h. - */ - -static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} -}; - -static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} -}; diff --git a/internal-complibs/zlib-ng-2.0.7/trees_tbl._h b/internal-complibs/zlib-ng-2.0.7/trees_tbl._h deleted file mode 100644 index a4c68a566..000000000 --- a/internal-complibs/zlib-ng-2.0.7/trees_tbl._h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef TREES_TBL_H_ -#define TREES_TBL_H_ - -/* header created automatically with maketrees.c */ - -Z_INTERNAL const ct_data static_ltree[L_CODES+2] = { -{{ 12},{8}}, {{140},{8}}, {{ 76},{8}}, {{204},{8}}, {{ 44},{8}}, -{{172},{8}}, {{108},{8}}, {{236},{8}}, {{ 28},{8}}, {{156},{8}}, -{{ 92},{8}}, {{220},{8}}, {{ 60},{8}}, {{188},{8}}, {{124},{8}}, -{{252},{8}}, {{ 2},{8}}, {{130},{8}}, {{ 66},{8}}, {{194},{8}}, -{{ 34},{8}}, {{162},{8}}, {{ 98},{8}}, {{226},{8}}, {{ 18},{8}}, -{{146},{8}}, {{ 82},{8}}, {{210},{8}}, {{ 50},{8}}, {{178},{8}}, -{{114},{8}}, {{242},{8}}, {{ 10},{8}}, {{138},{8}}, {{ 74},{8}}, -{{202},{8}}, {{ 42},{8}}, {{170},{8}}, {{106},{8}}, {{234},{8}}, -{{ 26},{8}}, {{154},{8}}, {{ 90},{8}}, {{218},{8}}, {{ 58},{8}}, -{{186},{8}}, {{122},{8}}, {{250},{8}}, {{ 6},{8}}, {{134},{8}}, -{{ 70},{8}}, {{198},{8}}, {{ 38},{8}}, {{166},{8}}, {{102},{8}}, -{{230},{8}}, {{ 22},{8}}, {{150},{8}}, {{ 86},{8}}, {{214},{8}}, -{{ 54},{8}}, {{182},{8}}, {{118},{8}}, {{246},{8}}, {{ 14},{8}}, -{{142},{8}}, {{ 78},{8}}, {{206},{8}}, {{ 46},{8}}, {{174},{8}}, -{{110},{8}}, {{238},{8}}, {{ 30},{8}}, {{158},{8}}, {{ 94},{8}}, -{{222},{8}}, {{ 62},{8}}, {{190},{8}}, {{126},{8}}, {{254},{8}}, -{{ 1},{8}}, {{129},{8}}, {{ 65},{8}}, {{193},{8}}, {{ 33},{8}}, -{{161},{8}}, {{ 97},{8}}, {{225},{8}}, {{ 17},{8}}, {{145},{8}}, -{{ 81},{8}}, {{209},{8}}, {{ 49},{8}}, {{177},{8}}, {{113},{8}}, -{{241},{8}}, {{ 9},{8}}, {{137},{8}}, {{ 73},{8}}, {{201},{8}}, -{{ 41},{8}}, {{169},{8}}, {{105},{8}}, {{233},{8}}, {{ 25},{8}}, -{{153},{8}}, {{ 89},{8}}, {{217},{8}}, {{ 57},{8}}, {{185},{8}}, -{{121},{8}}, {{249},{8}}, {{ 5},{8}}, {{133},{8}}, {{ 69},{8}}, -{{197},{8}}, {{ 37},{8}}, {{165},{8}}, {{101},{8}}, {{229},{8}}, -{{ 21},{8}}, {{149},{8}}, {{ 85},{8}}, {{213},{8}}, {{ 53},{8}}, -{{181},{8}}, {{117},{8}}, {{245},{8}}, {{ 13},{8}}, {{141},{8}}, -{{ 77},{8}}, {{205},{8}}, {{ 45},{8}}, {{173},{8}}, {{109},{8}}, -{{237},{8}}, {{ 29},{8}}, {{157},{8}}, {{ 93},{8}}, {{221},{8}}, -{{ 61},{8}}, {{189},{8}}, {{125},{8}}, {{253},{8}}, {{ 19},{9}}, -{{275},{9}}, {{147},{9}}, {{403},{9}}, {{ 83},{9}}, {{339},{9}}, -{{211},{9}}, {{467},{9}}, {{ 51},{9}}, {{307},{9}}, {{179},{9}}, -{{435},{9}}, {{115},{9}}, {{371},{9}}, {{243},{9}}, {{499},{9}}, -{{ 11},{9}}, {{267},{9}}, {{139},{9}}, {{395},{9}}, {{ 75},{9}}, -{{331},{9}}, {{203},{9}}, {{459},{9}}, {{ 43},{9}}, {{299},{9}}, -{{171},{9}}, {{427},{9}}, {{107},{9}}, {{363},{9}}, {{235},{9}}, -{{491},{9}}, {{ 27},{9}}, {{283},{9}}, {{155},{9}}, {{411},{9}}, -{{ 91},{9}}, {{347},{9}}, {{219},{9}}, {{475},{9}}, {{ 59},{9}}, -{{315},{9}}, {{187},{9}}, {{443},{9}}, {{123},{9}}, {{379},{9}}, -{{251},{9}}, {{507},{9}}, {{ 7},{9}}, {{263},{9}}, {{135},{9}}, -{{391},{9}}, {{ 71},{9}}, {{327},{9}}, {{199},{9}}, {{455},{9}}, -{{ 39},{9}}, {{295},{9}}, {{167},{9}}, {{423},{9}}, {{103},{9}}, -{{359},{9}}, {{231},{9}}, {{487},{9}}, {{ 23},{9}}, {{279},{9}}, -{{151},{9}}, {{407},{9}}, {{ 87},{9}}, {{343},{9}}, {{215},{9}}, -{{471},{9}}, {{ 55},{9}}, {{311},{9}}, {{183},{9}}, {{439},{9}}, -{{119},{9}}, {{375},{9}}, {{247},{9}}, {{503},{9}}, {{ 15},{9}}, -{{271},{9}}, {{143},{9}}, {{399},{9}}, {{ 79},{9}}, {{335},{9}}, -{{207},{9}}, {{463},{9}}, {{ 47},{9}}, {{303},{9}}, {{175},{9}}, -{{431},{9}}, {{111},{9}}, {{367},{9}}, {{239},{9}}, {{495},{9}}, -{{ 31},{9}}, {{287},{9}}, {{159},{9}}, {{415},{9}}, {{ 95},{9}}, -{{351},{9}}, {{223},{9}}, {{479},{9}}, {{ 63},{9}}, {{319},{9}}, -{{191},{9}}, {{447},{9}}, {{127},{9}}, {{383},{9}}, {{255},{9}}, -{{511},{9}}, {{ 0},{7}}, {{ 64},{7}}, {{ 32},{7}}, {{ 96},{7}}, -{{ 16},{7}}, {{ 80},{7}}, {{ 48},{7}}, {{112},{7}}, {{ 8},{7}}, -{{ 72},{7}}, {{ 40},{7}}, {{104},{7}}, {{ 24},{7}}, {{ 88},{7}}, -{{ 56},{7}}, {{120},{7}}, {{ 4},{7}}, {{ 68},{7}}, {{ 36},{7}}, -{{100},{7}}, {{ 20},{7}}, {{ 84},{7}}, {{ 52},{7}}, {{116},{7}}, -{{ 3},{8}}, {{131},{8}}, {{ 67},{8}}, {{195},{8}}, {{ 35},{8}}, -{{163},{8}}, {{ 99},{8}}, {{227},{8}} -}; - -Z_INTERNAL const ct_data static_dtree[D_CODES] = { -{{ 0},{5}}, {{16},{5}}, {{ 8},{5}}, {{24},{5}}, {{ 4},{5}}, -{{20},{5}}, {{12},{5}}, {{28},{5}}, {{ 2},{5}}, {{18},{5}}, -{{10},{5}}, {{26},{5}}, {{ 6},{5}}, {{22},{5}}, {{14},{5}}, -{{30},{5}}, {{ 1},{5}}, {{17},{5}}, {{ 9},{5}}, {{25},{5}}, -{{ 5},{5}}, {{21},{5}}, {{13},{5}}, {{29},{5}}, {{ 3},{5}}, -{{19},{5}}, {{11},{5}}, {{27},{5}}, {{ 7},{5}}, {{23},{5}} -}; - -const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const unsigned char Z_INTERNAL zng_length_code[MAX_MATCH-MIN_MATCH+1] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -Z_INTERNAL const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -Z_INTERNAL const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - -#endif /* TREES_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.0.7/zconf.h b/internal-complibs/zlib-ng-2.0.7/zconf.h deleted file mode 100644 index 1c03f294f..000000000 --- a/internal-complibs/zlib-ng-2.0.7/zconf.h +++ /dev/null @@ -1,201 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifndef ZCONF_H -#define ZCONF_H - -#if !defined(_WIN32) && defined(__WIN32__) -# define _WIN32 -#endif - -#ifdef __STDC_VERSION__ -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif - -/* Clang macro for detecting declspec support - * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute - */ -#ifndef __has_declspec_attribute -# define __has_declspec_attribute(x) 0 -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# define MAX_MEM_LEVEL 9 -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - -/* Type declarations */ - - -#ifndef OF /* function prototypes */ -# define OF(args) args -#endif - -#ifdef ZLIB_INTERNAL -# define Z_INTERNAL ZLIB_INTERNAL -#endif - -/* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) -# ifdef Z_INTERNAL -# define Z_EXTERN extern __declspec(dllexport) -# else -# define Z_EXTERN extern __declspec(dllimport) -# endif -#endif - -/* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -#if defined(ZLIB_WINAPI) && defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define Z_EXPORT WINAPI -# define Z_EXPORTVA WINAPIV -#endif - -#ifndef Z_EXTERN -# define Z_EXTERN extern -#endif -#ifndef Z_EXPORT -# define Z_EXPORT -#endif -#ifndef Z_EXPORTVA -# define Z_EXPORTVA -#endif - -/* For backwards compatibility */ - -#ifndef ZEXTERN -# define ZEXTERN Z_EXTERN -#endif -#ifndef ZEXPORT -# define ZEXPORT Z_EXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA Z_EXPORTVA -#endif - -/* Legacy zlib typedefs for backwards compatibility. Don't assume stdint.h is defined. */ -typedef unsigned char Byte; -typedef Byte Bytef; - -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef char charf; -typedef int intf; -typedef uInt uIntf; -typedef uLong uLongf; - -typedef void const *voidpc; -typedef void *voidpf; -typedef void *voidp; - -typedef unsigned int z_crc_t; - -#if 1 /* was set to #if 1 by configure/cmake/etc */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ -typedef PTRDIFF_TYPE ptrdiff_t; -#endif - -#include /* for off_t */ - -#include /* for wchar_t and NULL */ - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(__MSYS__) -# define z_off64_t _off64_t -# elif defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -#endif /* ZCONF_H */ diff --git a/internal-complibs/zlib-ng-2.0.7/zconf.h.included b/internal-complibs/zlib-ng-2.0.7/zconf.h.included deleted file mode 100644 index 1c03f294f..000000000 --- a/internal-complibs/zlib-ng-2.0.7/zconf.h.included +++ /dev/null @@ -1,201 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#ifndef ZCONF_H -#define ZCONF_H - -#if !defined(_WIN32) && defined(__WIN32__) -# define _WIN32 -#endif - -#ifdef __STDC_VERSION__ -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif -#endif - -/* Clang macro for detecting declspec support - * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute - */ -#ifndef __has_declspec_attribute -# define __has_declspec_attribute(x) 0 -#endif - -#if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const -#else -# define z_const -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# define MAX_MEM_LEVEL 9 -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - (1 << (windowBits+2)) + (1 << (memLevel+9)) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus about 7 kilobytes - for small objects. -*/ - -/* Type declarations */ - - -#ifndef OF /* function prototypes */ -# define OF(args) args -#endif - -#ifdef ZLIB_INTERNAL -# define Z_INTERNAL ZLIB_INTERNAL -#endif - -/* If building or using zlib as a DLL, define ZLIB_DLL. - * This is not mandatory, but it offers a little performance increase. - */ -#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) -# ifdef Z_INTERNAL -# define Z_EXTERN extern __declspec(dllexport) -# else -# define Z_EXTERN extern __declspec(dllimport) -# endif -#endif - -/* If building or using zlib with the WINAPI/WINAPIV calling convention, - * define ZLIB_WINAPI. - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. - */ -#if defined(ZLIB_WINAPI) && defined(_WIN32) -# ifndef WIN32_LEAN_AND_MEAN -# define WIN32_LEAN_AND_MEAN -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define Z_EXPORT WINAPI -# define Z_EXPORTVA WINAPIV -#endif - -#ifndef Z_EXTERN -# define Z_EXTERN extern -#endif -#ifndef Z_EXPORT -# define Z_EXPORT -#endif -#ifndef Z_EXPORTVA -# define Z_EXPORTVA -#endif - -/* For backwards compatibility */ - -#ifndef ZEXTERN -# define ZEXTERN Z_EXTERN -#endif -#ifndef ZEXPORT -# define ZEXPORT Z_EXPORT -#endif -#ifndef ZEXPORTVA -# define ZEXPORTVA Z_EXPORTVA -#endif - -/* Legacy zlib typedefs for backwards compatibility. Don't assume stdint.h is defined. */ -typedef unsigned char Byte; -typedef Byte Bytef; - -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef char charf; -typedef int intf; -typedef uInt uIntf; -typedef uLong uLongf; - -typedef void const *voidpc; -typedef void *voidpf; -typedef void *voidp; - -typedef unsigned int z_crc_t; - -#if 1 /* was set to #if 1 by configure/cmake/etc */ -# define Z_HAVE_UNISTD_H -#endif - -#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ -typedef PTRDIFF_TYPE ptrdiff_t; -#endif - -#include /* for off_t */ - -#include /* for wchar_t and NULL */ - -/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and - * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even - * though the former does not conform to the LFS document), but considering - * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as - * equivalently requesting no 64-bit operations - */ -#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE -#endif - -#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifndef z_off_t -# define z_off_t off_t -# endif -#endif - -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 -#endif - -#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 -#endif - -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 -#endif - -#if !defined(SEEK_SET) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ -#endif - -#ifndef z_off_t -# define z_off_t long -#endif - -#if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t -#else -# if defined(__MSYS__) -# define z_off64_t _off64_t -# elif defined(_WIN32) && !defined(__GNUC__) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif -#endif - -#endif /* ZCONF_H */ From 6fe0691b8ad45e7a2ca12242c701c30d743bca4e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:01:23 +0100 Subject: [PATCH 2/5] Remove .git* files --- .../zlib-ng-2.0.7/.gitattributes | 6 - .../.github/workflows/analyze.yml | 78 --- .../zlib-ng-2.0.7/.github/workflows/cmake.yml | 508 ------------------ .../.github/workflows/codeql.yml | 41 -- .../.github/workflows/configure.yml | 192 ------- .../.github/workflows/libpng.yml | 51 -- .../zlib-ng-2.0.7/.github/workflows/nmake.yml | 68 --- .../zlib-ng-2.0.7/.github/workflows/pigz.yml | 131 ----- .../.github/workflows/pkgcheck.yml | 154 ------ .../.github/workflows/release.yml | 100 ---- internal-complibs/zlib-ng-2.0.7/.gitignore | 88 --- 11 files changed, 1417 deletions(-) delete mode 100644 internal-complibs/zlib-ng-2.0.7/.gitattributes delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml delete mode 100644 internal-complibs/zlib-ng-2.0.7/.gitignore diff --git a/internal-complibs/zlib-ng-2.0.7/.gitattributes b/internal-complibs/zlib-ng-2.0.7/.gitattributes deleted file mode 100644 index 3b35744b0..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.gitattributes +++ /dev/null @@ -1,6 +0,0 @@ -* text=auto -*.c text -*.h text -Makefile text -configure text eol=lf -testCVEinputs.sh text eol=lf diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml deleted file mode 100644 index cbdea0e50..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/analyze.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Static Analysis -on: [push, pull_request] -jobs: - static-analysis: - name: GCC - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y gcc-10 - - - name: Generate project files - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CC: gcc-10 - CFLAGS: - -fanalyzer - -Werror - -Wanalyzer-double-fclose - -Wanalyzer-double-free - -Wanalyzer-exposure-through-output-file - -Wanalyzer-file-leak - -Wanalyzer-free-of-non-heap - -Wanalyzer-malloc-leak - -Wanalyzer-null-argument - -Wanalyzer-null-dereference - -Wanalyzer-possible-null-argument - -Wanalyzer-possible-null-dereference - -Wanalyzer-stale-setjmp-buffer - -Wanalyzer-tainted-array-index - -Wanalyzer-unsafe-call-within-signal-handler - -Wanalyzer-use-after-free - -Wanalyzer-use-of-pointer-in-stale-stack-frame - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release > /dev/null - - Clang: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y clang-tools - - - name: Generate project files - run: | - scan-build --status-bugs \ - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CI: true - - - name: Compile source code - run: | - scan-build --status-bugs \ - cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml deleted file mode 100644 index 456f7bb1f..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/cmake.yml +++ /dev/null @@ -1,508 +0,0 @@ -name: CMake -on: [push, pull_request] -env: - TERM: xterm-256color - GTEST_COLOR: 1 -jobs: - cmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - - - name: Ubuntu GCC ASAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_SANITIZER=Address - codecov: ubuntu_gcc - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_sprefix - - - name: Ubuntu GCC Compat Symbol Prefix - os: ubuntu-latest - compiler: gcc - cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_compat_sprefix - - - name: Ubuntu GCC -O3 OSB - os: ubuntu-latest - compiler: gcc - build-dir: ../build - build-src-dir: ../zlib-ng - codecov: ubuntu_gcc_osb - cflags: -O3 - - - name: Ubuntu GCC -O1 No Unaligned UBSAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_o1 - cflags: -O1 - - - name: Ubuntu GCC 32-bit - os: ubuntu-latest - compiler: gcc - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 - packages: gcc-multilib g++-multilib - codecov: ubuntu_gcc_m32 - - - name: Ubuntu GCC No CTZLL - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF - codecov: ubuntu_gcc_no_ctzll - - - name: Ubuntu GCC No CTZ - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF - codecov: ubuntu_gcc_no_ctz - - - name: Ubuntu GCC No AVX2 UBSAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_avx2 - - - name: Ubuntu GCC No SSE2 UBSAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse2 - - - name: Ubuntu GCC No SSE4 UBSAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_SSE4=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse4 - - - name: Ubuntu GCC No PCLMULQDQ UBSAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_pclmulqdq - - - name: Ubuntu GCC Compat No Opt ASAN - os: ubuntu-latest - compiler: gcc - cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address - codecov: ubuntu_gcc_compat_no_opt - cflags: -DNOT_TWEAK_COMPILER - - - name: Ubuntu GCC ARM SF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf - - - name: Ubuntu GCC ARM SF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf_compat_no_opt - - - name: Ubuntu GCC ARM HF No ACLE ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_acle - - - name: Ubuntu GCC ARM HF No NEON No ACLE ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_ACLE=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_neon - - - name: Ubuntu GCC ARM HF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_compat_no_opt - - - name: Ubuntu GCC AARCH64 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64 - - - name: Ubuntu GCC AARCH64 No ACLE UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_acle - - - name: Ubuntu GCC AARCH64 No NEON UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_neon - - - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_compat_no_opt - - - name: Ubuntu GCC PPC - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc_no_power8 - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake - packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross - ldflags: -static - codecov: ubuntu_gcc_ppc64 - - - name: Ubuntu GCC PPC64LE - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross - codecov: ubuntu_gcc_ppc64le - - - name: Ubuntu GCC SPARC64 - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake - packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross - ldflags: -static - codecov: ubuntu_gcc_sparc64 - - - name: Ubuntu GCC S390X ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X No vectorized CRC32 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x_no_crc32 - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC ASAN - os: z15 - compiler: gcc - cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC Compat UBSAN - os: z15 - compiler: gcc - cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc_compat - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu Clang S390X DFLTCC MSAN - os: z15 - compiler: clang-11 - cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu MinGW i686 - os: ubuntu-22.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake - packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 - ldflags: -static - codecov: ubuntu_gcc_mingw_i686 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu MinGW x86_64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake - packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 - ldflags: -static - codecov: ubuntu_gcc_mingw_x86_64 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu 20.04 Clang - os: ubuntu-20.04 - compiler: clang-6.0 - packages: clang-6.0 - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang - - - name: Ubuntu Clang Inflate Strict - os: ubuntu-latest - compiler: clang-11 - cmake-args: -DWITH_INFLATE_STRICT=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_strict - - - name: Ubuntu Clang Inflate Allow Invalid Dist - os: ubuntu-latest - compiler: clang-11 - cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_allow_invalid_dist - - - name: Ubuntu Clang Reduced Memory - os: ubuntu-latest - compiler: clang-11 - cmake-args: -DWITH_REDUCED_MEM=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_reduced_mem - - - name: Ubuntu Clang Memory Map - os: ubuntu-latest - compiler: clang-11 - cflags: -DUSE_MMAP - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_mmap - - - name: Ubuntu Clang Debug - os: ubuntu-latest - compiler: clang-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_debug - build-config: Debug - - - name: Ubuntu Clang MSAN - os: ubuntu-latest - compiler: clang-11 - cmake-args: -GNinja -DWITH_SANITIZER=Memory - packages: ninja-build clang-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - # https://github.com/llvm/llvm-project/issues/55785 - msan-options: use_sigaltstack=0 - - - name: Windows MSVC 2022 v143 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 - - - name: Windows MSVC 2022 v143 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 - - - name: Windows MSVC 2022 v142 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 - - - name: Windows MSVC 2022 v142 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 - - - name: Windows MSVC 2022 v141 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 - - - name: Windows MSVC 2022 v141 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 - - - name: Windows MSVC 2019 v140 Win32 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 - - - name: Windows MSVC 2019 v140 Win64 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 - - - name: Windows MSVC ARM No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM - - - name: Windows MSVC ARM64 No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - - - name: Windows GCC - os: windows-latest - compiler: gcc - cmake-args: -G Ninja - codecov: win64_gcc - - - name: Windows GCC Compat No Opt - os: windows-latest - compiler: gcc - cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF - codecov: win64_gcc_compat_no_opt - - - name: macOS Clang ASAN - os: macos-latest - compiler: clang - cmake-args: -DWITH_SANITIZER=Address - codecov: macos_clang - - - name: macOS GCC UBSAN - os: macos-latest - compiler: gcc-10 - cmake-args: -DWITH_SANITIZER=Undefined - packages: gcc@10 - gcov-exec: gcov-10 - codecov: macos_gcc - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs - # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. - if: contains(matrix.name, 'MinGW') == false - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add repositories (Wine) - if: contains(matrix.packages, 'wine32') - run: sudo dpkg --add-architecture i386 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} - - - name: Install packages (Windows) - if: runner.os == 'Windows' - run: | - # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. - # zlib-ng does not need perl, so simply remove it. - choco uninstall --no-progress strawberryperl - choco install --no-progress ninja ${{ matrix.packages }} - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Initialize Wine - # Prevent parallel test jobs from initializing Wine at the same time - if: contains(matrix.packages, 'wine') - run: wineboot --init - - - name: Generate project files - shell: bash - # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources - run: | - cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=ON \ - -DWITH_MAINTAINER_WARNINGS=ON \ - ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} - - - name: Run test cases - # Don't run tests on Windows ARM - if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: ${{ matrix.build-dir || '.' }} - env: - ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 - - - name: Generate coverage report - if: matrix.codecov - shell: bash - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root ${{ matrix.build-src-dir || '.' }} \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - directory: ${{ matrix.build-src-dir || '.' }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml deleted file mode 100644 index 1cfa4d7fa..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/codeql.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "develop" ] - pull_request: - branches: [ "develop" ] - schedule: - - cron: "27 17 * * 0" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ cpp ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - queries: +security-and-quality - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml deleted file mode 100644 index 6fa2e3c69..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/configure.yml +++ /dev/null @@ -1,192 +0,0 @@ -name: Configure -on: [push, pull_request] -jobs: - configure: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - configure-args: --warn - - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - configure-args: --warn - - - name: Ubuntu GCC OSB - os: ubuntu-latest - compiler: gcc - configure-args: --warn - build-dir: ../build - build-src-dir: ../zlib-ng - - - name: Ubuntu GCC Compat No Opt - os: ubuntu-latest - compiler: gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - - - name: Ubuntu GCC ARM SF - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM SF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No ACLE - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-acle - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No NEON - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-neon --without-acle - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No ACLE - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-acle - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No NEON - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-neon - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 Compat No Opt - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - compiler: powerpc64-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - compiler: powerpc64le-linux-gnu-gcc - configure-args: --warn - chost: powerpc64le-linux-gnu - packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross - - - name: Ubuntu GCC S390X - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X DFLTCC - os: z15 - compiler: gcc - configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu GCC S390X DFLTCC Compat - os: z15 - compiler: gcc - configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: macOS GCC - os: macOS-latest - compiler: gcc-11 - configure-args: --warn - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Generate project files - run: | - mkdir ${{ matrix.build-dir || '.not-used' }} - cd ${{ matrix.build-dir || '.' }} - ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CHOST: ${{ matrix.chost }} - EMU_RUN: ${{ matrix.emu-run }} - CI: true - - - name: Compile source code - run: make -j2 - working-directory: ${{ matrix.build-dir }} - - - name: Run test cases - run: make test - working-directory: ${{ matrix.build-dir }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (configure) - path: | - **/Makefile - ${{ matrix.build-dir || '.' }}/configure.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml deleted file mode 100644 index c5fea574f..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/libpng.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Libpng -on: [push, pull_request] -jobs: - libpng: - name: Ubuntu Clang - runs-on: ubuntu-latest - steps: - - name: Checkout repository (zlib-ng) - uses: actions/checkout@v3 - - - name: Generate project files (zlib-ng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_COMPAT=ON \ - -DZLIB_ENABLE_TESTS=OFF - env: - CC: clang - CFLAGS: -fPIC - CI: true - - - name: Compile source code (zlib-ng) - run: cmake --build . -j2 --config Release - - - name: Checkout repository (libpng) - uses: actions/checkout@v3 - with: - repository: glennrp/libpng - path: libpng - - - name: Generate project files (libpng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DPNG_TESTS=ON \ - -DPNG_STATIC=OFF \ - -DZLIB_INCLUDE_DIR=.. \ - -DZLIB_LIBRARY=$PWD/../libz.a - working-directory: libpng - env: - CC: clang - CI: true - - - name: Compile source code (libpng) - run: cmake --build . -j2 --config Release - working-directory: libpng - - - name: Run test cases (libpng) - run: ctest -j2 -C Release --output-on-failure --max-width 120 - working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml deleted file mode 100644 index 38e669093..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/nmake.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: NMake -on: [push, pull_request] -jobs: - nmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows NMake x86 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86 - - - name: Windows NMake x64 compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes - - - name: Windows NMake x64 Symbol Prefix - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 Symbol Prefix Compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - - - name: Windows NMake ARM No Test - os: windows-2022 - makefile: win32/Makefile.arm - arch: x86_arm - - - name: Windows NMake ARM64 No Test - os: windows-2022 - makefile: win32/Makefile.a64 - arch: x86_arm64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup development environment - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: ${{ matrix.arch }} - - - name: Compile source code - shell: cmd - run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} - - - name: Run test cases - shell: cmd - # Don't run tests on Windows ARM - if: contains(matrix.arch, 'arm') == false - run: | - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml deleted file mode 100644 index be4e1ce50..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pigz.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Pigz -on: [push, pull_request] -jobs: - pigz: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz - - - name: Ubuntu Clang No Optim - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_optim - cmake-args: -DWITH_OPTIM=OFF - - # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 - - name: Ubuntu Clang No Threads - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_threads - cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_pigz_aarch64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Generate project files - run: | - cmake ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_ROOT=../.. \ - -DWITH_CODE_COVERAGE=ON \ - -DWITH_MAINTAINER_WARNINGS=ON - working-directory: test/pigz - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} - working-directory: test/pigz - - - name: Run test cases - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: test/pigz - - - name: Generate coverage report - if: matrix.codecov - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root . \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml deleted file mode 100644 index a335c1f04..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/pkgcheck.yml +++ /dev/null @@ -1,154 +0,0 @@ -name: Package Check -on: [push, pull_request] -jobs: - pkgcheck: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - - - name: Ubuntu GCC -m32 - os: ubuntu-latest - compiler: gcc - packages: gcc-multilib g++-multilib - cmake-args: -DCMAKE_C_FLAGS=-m32 - cflags: -m32 - ldflags: -m32 - - - name: Ubuntu GCC ARM SF - os: ubuntu-latest - chost: arm-linux-gnueabi - compiler: arm-linux-gnueabi-gcc - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake - packages: qemu gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - chost: aarch64-linux-gnu - compiler: aarch64-linux-gnu-gcc - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake - packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - chost: powerpc-linux-gnu - compiler: powerpc-linux-gnu-gcc - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - chost: powerpc64le-linux-gnu - compiler: powerpc64le-linux-gnu-gcc - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross - - - name: macOS Clang - os: macOS-11 - compiler: clang - - - name: macOS Clang Native - os: macOS-11 - compiler: clang - cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON - configure-args: --native - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ - abigail-tools \ - diffoscope \ - ninja-build - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja diffoscope ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Select Xcode version (macOS) - # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports - # AppleClang linking with libtool using -D argument - # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 - if: runner.os == 'macOS' - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '11.7.0' - - - name: Compare builds - run: sh test/pkgcheck.sh - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Compare builds (compat) - run: sh test/pkgcheck.sh --zlib-compat - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --refresh-if - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI (compat) - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --zlib-compat --refresh-if - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} - path: | - **/*.abi - btmp1/configure.log - btmp1/CMakeFiles/CMakeOutput.log - btmp1/CMakeFiles/CMakeError.log - btmp2/configure.log - btmp2/CMakeFiles/CMakeOutput.log - btmp2/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml deleted file mode 100644 index b64933cc7..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.github/workflows/release.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Release -on: - push: - tags: - - '*' -jobs: - release: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows MSVC Win32 - os: windows-latest - compiler: cl - cmake-args: -A Win32 - deploy-name: win-x86 - - - name: Windows MSVC Win32 Compat - os: windows-latest - compiler: cl - cmake-args: -A Win32 -DZLIB_COMPAT=ON - deploy-name: win-x86-compat - - - name: Windows MSVC Win64 - os: windows-latest - compiler: cl - cmake-args: -A x64 - deploy-name: win-x86-64 - - - name: Windows MSVC Win64 Compat - os: windows-latest - compiler: cl - cmake-args: -A x64 -DZLIB_COMPAT=ON - deploy-name: win-x86-64-compat - - - name: Windows MSVC ARM - os: windows-latest - compiler: cl - cmake-args: -A ARM - deploy-name: win-arm - - - name: Windows MSVC ARM Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM -DZLIB_COMPAT=ON - deploy-name: win-arm-compat - - - name: Windows MSVC ARM64 - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - deploy-name: win-arm64 - - - name: Windows MSVC ARM64 Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM64 -DZLIB_COMPAT=ON - deploy-name: win-arm64-compat - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set environment variables - shell: bash - run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - - - name: Generate project files - shell: bash - run: | - cmake . ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DZLIB_ENABLE_TESTS=ON \ - -DCMAKE_INSTALL_PREFIX=out \ - -DINSTALL_UTILS=ON - env: - CC: ${{ matrix.compiler }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release --target install - - - name: Package release (Windows) - if: runner.os == 'Windows' - run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md - working-directory: out - - - name: Upload release (Windows) - uses: svenstaro/upload-release-action@v2 - if: runner.os == 'Windows' - with: - asset_name: zlib-ng-${{ matrix.deploy-name }}.zip - file: zlib-ng-${{ matrix.deploy-name }}.zip - tag: ${{env.tag}} - repo_token: ${{ secrets.GITHUB_TOKEN }} - overwrite: true - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.0.7/.gitignore b/internal-complibs/zlib-ng-2.0.7/.gitignore deleted file mode 100644 index bf420e572..000000000 --- a/internal-complibs/zlib-ng-2.0.7/.gitignore +++ /dev/null @@ -1,88 +0,0 @@ -*.diff -*.patch -*.orig -*.rej - -*~ -*.a -*.lo -*.o -*.dylib - -*.gcda -*.gcno -*.gcov - -/adler32_test -/adler32_testsh -/crc32_test -/crc32_testsh -/example -/example64 -/examplesh -/libz.so* -/libz-ng.so* -/makefixed -/minigzip -/minigzip64 -/minigzipsh -/switchlevels -/zlib.pc -/zlib-ng.pc -/CVE-2003-0107 - -.DS_Store -*_fuzzer -*.obj -*.exe -*.pdb -*.exp -*.lib -*.dll -*.res -foo.gz -*.manifest -*.opensdf -*.sln -*.sdf -*.vcxproj -*.vcxproj.filters -.vs - -CMakeCache.txt -CMakeFiles -Testing -/*.cmake -*.stackdump -*._h -zconf.h -zconf.h.cmakein -zconf.h.included -zconf-ng.h -zconf-ng.h.cmakein -ztest* - -configure.log -a.out - -/Makefile -/arch/arm/Makefile -/arch/generic/Makefile -/arch/power/Makefile -/arch/x86/Makefile -.kdev4 -*.kdev4 - -/Debug -/example.dir -/minigzip.dir -/zlib.dir -/zlibstatic.dir -/win32/Debug -/build/ -/build[.-]*/ -/btmp[12]/ -/pkgtmp[12]/ - -/.idea -/cmake-build-debug From d3b225997c6330dc35ceb313f843980a3473bdad Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:11:34 +0100 Subject: [PATCH 3/5] Pristine new zlib-ng sources, from tarball --- .../zlib-ng-2.1.0-beta1/.codecov.yaml | 27 + .../zlib-ng-2.1.0-beta1/.gitattributes | 8 + .../zlib-ng-2.1.0-beta1/.github/FUNDING.yml | 1 + .../.github/workflows/analyze.yml | 78 + .../.github/workflows/cmake.yml | 609 ++ .../.github/workflows/codeql.yml | 41 + .../.github/workflows/configure.yml | 238 + .../.github/workflows/fuzz.yml | 36 + .../.github/workflows/libpng.yml | 51 + .../.github/workflows/link.yml | 66 + .../.github/workflows/nmake.yml | 68 + .../.github/workflows/pigz.yml | 131 + .../.github/workflows/pkgcheck.yml | 176 + .../.github/workflows/release.yml | 100 + .../zlib-ng-2.1.0-beta1/.gitignore | 97 + .../zlib-ng-2.1.0-beta1/.shellcheckrc | 1 + .../zlib-ng-2.1.0-beta1/CMakeLists.txt | 1250 +++ .../zlib-ng-2.1.0-beta1/FAQ.zlib | 374 + .../zlib-ng-2.1.0-beta1/INDEX.md | 36 + .../zlib-ng-2.1.0-beta1/LICENSE.md | 19 + .../zlib-ng-2.1.0-beta1/Makefile.in | 395 + .../zlib-ng-2.1.0-beta1/PORTING.md | 79 + .../zlib-ng-2.1.0-beta1/README.md | 240 + .../zlib-ng-2.1.0-beta1/adler32.c | 115 + .../zlib-ng-2.1.0-beta1/adler32_fold.c | 16 + .../zlib-ng-2.1.0-beta1/adler32_fold.h | 11 + .../zlib-ng-2.1.0-beta1/adler32_p.h | 70 + .../zlib-ng-2.1.0-beta1/arch/.gitignore | 2 + .../zlib-ng-2.1.0-beta1/arch/arm/Makefile.in | 77 + .../arch/arm/adler32_neon.c | 215 + .../arch/arm/arm_features.c | 82 + .../arch/arm/arm_features.h | 15 + .../arch/arm/chunkset_neon.c | 101 + .../arch/arm/compare256_neon.c | 59 + .../zlib-ng-2.1.0-beta1/arch/arm/crc32_acle.c | 98 + .../arch/arm/insert_string_acle.c | 26 + .../arch/arm/neon_intrins.h | 57 + .../arch/arm/slide_hash_neon.c | 46 + .../arch/generic/Makefile.in | 21 + .../arch/generic/chunk_permute_table.h | 53 + .../arch/power/Makefile.in | 93 + .../arch/power/adler32_power8.c | 153 + .../arch/power/adler32_vmx.c | 181 + .../arch/power/chunkset_power8.c | 55 + .../arch/power/compare256_power9.c | 66 + .../arch/power/crc32_constants.h | 1123 ++ .../arch/power/crc32_power8.c | 589 + .../arch/power/fallback_builtins.h | 31 + .../arch/power/power_features.c | 42 + .../arch/power/power_features.h | 18 + .../arch/power/slide_hash_power8.c | 12 + .../arch/power/slide_hash_vmx.c | 10 + .../arch/power/slide_ppc_tpl.h | 31 + .../zlib-ng-2.1.0-beta1/arch/s390/Makefile.in | 54 + .../zlib-ng-2.1.0-beta1/arch/s390/README.md | 284 + .../zlib-ng-2.1.0-beta1/arch/s390/crc32-vx.c | 222 + .../arch/s390/dfltcc_common.c | 40 + .../arch/s390/dfltcc_common.h | 44 + .../arch/s390/dfltcc_deflate.c | 404 + .../arch/s390/dfltcc_deflate.h | 60 + .../arch/s390/dfltcc_detail.h | 312 + .../arch/s390/dfltcc_inflate.c | 205 + .../arch/s390/dfltcc_inflate.h | 70 + .../arch/s390/s390_features.c | 14 + .../arch/s390/s390_features.h | 10 + .../actions-runner.Dockerfile | 45 + .../actions-runner.service | 24 + .../fs/usr/bin/actions-runner | 40 + .../self-hosted-builder/fs/usr/bin/entrypoint | 30 + .../qemu-user-static.service | 11 + .../zlib-ng-2.1.0-beta1/arch/x86/Makefile.in | 147 + .../arch/x86/adler32_avx2.c | 17 + .../arch/x86/adler32_avx2_p.h | 32 + .../arch/x86/adler32_avx2_tpl.h | 141 + .../arch/x86/adler32_avx512.c | 16 + .../arch/x86/adler32_avx512_p.h | 46 + .../arch/x86/adler32_avx512_tpl.h | 106 + .../arch/x86/adler32_avx512_vnni.c | 225 + .../arch/x86/adler32_sse42.c | 121 + .../arch/x86/adler32_ssse3.c | 156 + .../arch/x86/adler32_ssse3_p.h | 29 + .../arch/x86/chunkset_avx2.c | 135 + .../arch/x86/chunkset_sse2.c | 56 + .../arch/x86/chunkset_ssse3.c | 103 + .../arch/x86/compare256_avx2.c | 63 + .../arch/x86/compare256_sse2.c | 96 + .../arch/x86/crc32_fold_pclmulqdq_tpl.h | 186 + .../arch/x86/crc32_fold_vpclmulqdq_tpl.h | 116 + .../arch/x86/crc32_pclmulqdq.c | 30 + .../arch/x86/crc32_pclmulqdq_tpl.h | 363 + .../arch/x86/crc32_vpclmulqdq.c | 17 + .../arch/x86/insert_string_sse42.c | 50 + .../arch/x86/slide_hash_avx2.c | 39 + .../arch/x86/slide_hash_sse2.c | 62 + .../arch/x86/x86_features.c | 97 + .../arch/x86/x86_features.h | 24 + .../zlib-ng-2.1.0-beta1/chunkset.c | 42 + .../zlib-ng-2.1.0-beta1/chunkset_tpl.h | 200 + .../zlib-ng-2.1.0-beta1/cmake/detect-arch.c | 111 + .../cmake/detect-arch.cmake | 101 + .../cmake/detect-coverage.cmake | 46 + .../cmake/detect-install-dirs.cmake | 43 + .../cmake/detect-intrinsics.cmake | 524 + .../cmake/detect-sanitizer.cmake | 166 + .../cmake/fallback-macros.cmake | 19 + .../cmake/toolchain-aarch64.cmake | 24 + .../cmake/toolchain-arm.cmake | 29 + .../cmake/toolchain-armhf.cmake | 25 + .../cmake/toolchain-mingw-i686.cmake | 35 + .../cmake/toolchain-mingw-x86_64.cmake | 34 + .../cmake/toolchain-powerpc.cmake | 25 + .../cmake/toolchain-powerpc64.cmake | 25 + .../cmake/toolchain-powerpc64le.cmake | 25 + .../cmake/toolchain-s390x.cmake | 25 + .../cmake/toolchain-sparc64.cmake | 25 + .../zlib-ng-2.1.0-beta1/compare256.c | 180 + .../zlib-ng-2.1.0-beta1/compress.c | 98 + .../zlib-ng-2.1.0-beta1/configure | 2316 ++++ .../zlib-ng-2.1.0-beta1/cpu_features.c | 21 + .../zlib-ng-2.1.0-beta1/cpu_features.h | 270 + .../zlib-ng-2.1.0-beta1/crc32_braid.c | 267 + .../zlib-ng-2.1.0-beta1/crc32_braid_comb.c | 57 + .../zlib-ng-2.1.0-beta1/crc32_braid_comb_p.h | 42 + .../zlib-ng-2.1.0-beta1/crc32_braid_p.h | 50 + .../zlib-ng-2.1.0-beta1/crc32_braid_tbl.h | 9446 +++++++++++++++++ .../zlib-ng-2.1.0-beta1/crc32_fold.c | 33 + .../zlib-ng-2.1.0-beta1/crc32_fold.h | 21 + .../zlib-ng-2.1.0-beta1/deflate.c | 1427 +++ .../zlib-ng-2.1.0-beta1/deflate.h | 403 + .../zlib-ng-2.1.0-beta1/deflate_fast.c | 102 + .../zlib-ng-2.1.0-beta1/deflate_huff.c | 45 + .../zlib-ng-2.1.0-beta1/deflate_medium.c | 293 + .../zlib-ng-2.1.0-beta1/deflate_p.h | 116 + .../zlib-ng-2.1.0-beta1/deflate_quick.c | 127 + .../zlib-ng-2.1.0-beta1/deflate_rle.c | 80 + .../zlib-ng-2.1.0-beta1/deflate_slow.c | 143 + .../zlib-ng-2.1.0-beta1/deflate_stored.c | 186 + .../zlib-ng-2.1.0-beta1/doc/algorithm.txt | 209 + .../zlib-ng-2.1.0-beta1/doc/crc-doc.1.0.pdf | Bin 0 -> 776142 bytes .../zlib-ng-2.1.0-beta1/doc/crc-pclmulqdq.pdf | Bin 0 -> 384202 bytes .../zlib-ng-2.1.0-beta1/doc/rfc1950.txt | 619 ++ .../zlib-ng-2.1.0-beta1/doc/rfc1951.txt | 955 ++ .../zlib-ng-2.1.0-beta1/doc/rfc1952.txt | 675 ++ .../zlib-ng-2.1.0-beta1/doc/txtvsbin.txt | 107 + .../zlib-ng-2.1.0-beta1/fallback_builtins.h | 133 + .../zlib-ng-2.1.0-beta1/functable.c | 336 + .../zlib-ng-2.1.0-beta1/functable.h | 41 + .../zlib-ng-2.1.0-beta1/gzguts.h | 145 + internal-complibs/zlib-ng-2.1.0-beta1/gzlib.c | 525 + .../zlib-ng-2.1.0-beta1/gzread.c.in | 602 ++ .../zlib-ng-2.1.0-beta1/gzwrite.c | 526 + .../zlib-ng-2.1.0-beta1/infback.c | 511 + .../zlib-ng-2.1.0-beta1/inffast_tpl.h | 326 + .../zlib-ng-2.1.0-beta1/inffixed_tbl.h | 94 + .../zlib-ng-2.1.0-beta1/inflate.c | 1408 +++ .../zlib-ng-2.1.0-beta1/inflate.h | 140 + .../zlib-ng-2.1.0-beta1/inflate_p.h | 225 + .../zlib-ng-2.1.0-beta1/inftrees.c | 295 + .../zlib-ng-2.1.0-beta1/inftrees.h | 66 + .../zlib-ng-2.1.0-beta1/insert_string.c | 21 + .../zlib-ng-2.1.0-beta1/insert_string_roll.c | 24 + .../zlib-ng-2.1.0-beta1/insert_string_tpl.h | 108 + .../zlib-ng-2.1.0-beta1/match_tpl.h | 289 + .../zlib-ng-2.1.0-beta1/slide_hash.c | 52 + .../zlib-ng-2.1.0-beta1/test/.gitignore | 5 + .../zlib-ng-2.1.0-beta1/test/CMakeLists.txt | 257 + .../test/CVE-2002-0059/test.gz | Bin 0 -> 4610 bytes .../test/CVE-2004-0797/test.gz | Bin 0 -> 52 bytes .../test/CVE-2005-1849/test.gz | Bin 0 -> 52 bytes .../test/CVE-2005-2096/test.gz | Bin 0 -> 52 bytes .../test/CVE-2018-25032/default.txt | 1 + .../test/CVE-2018-25032/fixed.txt | 1 + .../zlib-ng-2.1.0-beta1/test/GH-361/test.txt | 4 + .../zlib-ng-2.1.0-beta1/test/GH-364/test.bin | Bin 0 -> 8 bytes .../test/GH-382/defneg3.dat | 1 + .../zlib-ng-2.1.0-beta1/test/GH-751/test.txt | 1 + .../test/GH-979/pigz-2.6.tar.gz | Bin 0 -> 106840 bytes .../zlib-ng-2.1.0-beta1/test/Makefile.in | 82 + .../zlib-ng-2.1.0-beta1/test/README.md | 37 + .../zlib-ng-2.1.0-beta1/test/abi/ignore | 12 + ...c2a18c1281fc-aarch64-unknown-linux-gnu.abi | 1286 +++ ...c2a18c1281fc-arm-unknown-linux-gnueabi.abi | 1276 +++ ...a18c1281fc-arm-unknown-linux-gnueabihf.abi | 1276 +++ ...c2a18c1281fc-powerpc-unknown-linux-gnu.abi | 1286 +++ ...a18c1281fc-powerpc64-unknown-linux-gnu.abi | 1268 +++ ...8c1281fc-powerpc64le-unknown-linux-gnu.abi | 1268 +++ ...06c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi | 1263 +++ ...e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi | 1281 +++ ...4baf80882311-aarch64-unknown-linux-gnu.abi | 1904 ++++ ...4baf80882311-arm-unknown-linux-gnueabi.abi | 1889 ++++ ...af80882311-arm-unknown-linux-gnueabihf.abi | 1881 ++++ ...4baf80882311-powerpc-unknown-linux-gnu.abi | 1895 ++++ ...af80882311-powerpc64-unknown-linux-gnu.abi | 1894 ++++ ...80882311-powerpc64le-unknown-linux-gnu.abi | 1886 ++++ ...5e4baf80882311-x86_64-pc-linux-gnu-m32.abi | 2032 ++++ ...3c155e4baf80882311-x86_64-pc-linux-gnu.abi | 2064 ++++ .../zlib-ng-2.1.0-beta1/test/abicheck.md | 59 + .../zlib-ng-2.1.0-beta1/test/abicheck.sh | 163 + .../add-subdirectory-project/CMakeLists.txt | 13 + .../test/add-subdirectory-project/main.c | 7 + .../test/benchmarks/CMakeLists.txt | 107 + .../test/benchmarks/README.md | 47 + .../test/benchmarks/benchmark_adler32.cc | 89 + .../test/benchmarks/benchmark_adler32_copy.cc | 118 + .../test/benchmarks/benchmark_compare256.cc | 84 + .../test/benchmarks/benchmark_crc32.cc | 69 + .../test/benchmarks/benchmark_main.cc | 28 + .../test/benchmarks/benchmark_png_decode.cc | 126 + .../test/benchmarks/benchmark_png_encode.cc | 54 + .../test/benchmarks/benchmark_png_shared.h | 146 + .../test/benchmarks/benchmark_slidehash.cc | 86 + .../test/cmake/compress-and-verify.cmake | 264 + .../test/cmake/run-and-compare.cmake | 72 + .../test/cmake/run-and-redirect.cmake | 54 + .../test/cmake/test-cves.cmake | 33 + .../test/cmake/test-data.cmake | 67 + .../test/cmake/test-issues.cmake | 68 + .../test/cmake/test-tools.cmake | 61 + .../test/data/fireworks.jpg | Bin 0 -> 123093 bytes .../zlib-ng-2.1.0-beta1/test/data/lcet10.txt | 7519 +++++++++++++ .../test/data/paper-100k.pdf | Bin 0 -> 102400 bytes .../zlib-ng-2.1.0-beta1/test/example.c | 1016 ++ .../test/fuzz/CMakeLists.txt | 49 + .../test/fuzz/fuzzer_checksum.c | 81 + .../test/fuzz/fuzzer_compress.c | 82 + .../test/fuzz/fuzzer_example_dict.c | 164 + .../test/fuzz/fuzzer_example_flush.c | 119 + .../test/fuzz/fuzzer_example_large.c | 137 + .../test/fuzz/fuzzer_example_small.c | 118 + .../test/fuzz/fuzzer_minigzip.c | 325 + .../test/fuzz/standalone_fuzz_target_runner.c | 37 + .../zlib-ng-2.1.0-beta1/test/gh1235.c | 39 + .../zlib-ng-2.1.0-beta1/test/infcover.c | 686 ++ .../zlib-ng-2.1.0-beta1/test/minideflate.c | 359 + .../zlib-ng-2.1.0-beta1/test/minigzip.c | 378 + .../test/pigz/CMakeLists.txt | 211 + .../zlib-ng-2.1.0-beta1/test/pkgcheck.sh | 176 + .../zlib-ng-2.1.0-beta1/test/switchlevels.c | 167 + .../zlib-ng-2.1.0-beta1/test/test_adler32.cc | 386 + .../test/test_aligned_alloc.cc | 48 + .../test/test_compare256.cc | 83 + .../zlib-ng-2.1.0-beta1/test/test_compress.cc | 33 + .../test/test_compress_bound.cc | 59 + .../test/test_compress_dual.cc | 28 + .../test/test_cpu_features.h | 8 + .../zlib-ng-2.1.0-beta1/test/test_crc32.cc | 222 + .../test/test_cve-2003-0107.cc | 28 + .../test/test_deflate_bound.cc | 99 + .../test/test_deflate_concurrency.cc | 170 + .../test/test_deflate_copy.cc | 60 + .../test/test_deflate_dict.cc | 54 + .../test/test_deflate_hash_head_0.cc | 83 + .../test/test_deflate_header.cc | 71 + .../test/test_deflate_params.cc | 143 + .../test/test_deflate_pending.cc | 66 + .../test/test_deflate_prime.cc | 91 + .../test/test_deflate_quick_bi_valid.cc | 80 + .../test/test_deflate_quick_block_open.cc | 94 + .../test/test_deflate_tune.cc | 56 + .../zlib-ng-2.1.0-beta1/test/test_dict.cc | 96 + .../zlib-ng-2.1.0-beta1/test/test_gzio.cc | 105 + .../test/test_inflate_adler32.cc | 50 + .../test/test_inflate_sync.cc | 75 + .../test/test_large_buffers.cc | 87 + .../zlib-ng-2.1.0-beta1/test/test_main.cc | 19 + .../zlib-ng-2.1.0-beta1/test/test_raw.cc | 58 + .../zlib-ng-2.1.0-beta1/test/test_shared.h | 18 + .../zlib-ng-2.1.0-beta1/test/test_shared_ng.h | 23 + .../test/test_small_buffers.cc | 69 + .../test/test_small_window.cc | 67 + .../zlib-ng-2.1.0-beta1/test/test_version.cc | 27 + .../zlib-ng-2.1.0-beta1/tools/config.sub | 17 + .../zlib-ng-2.1.0-beta1/tools/makecrct.c | 250 + .../zlib-ng-2.1.0-beta1/tools/makefixed.c | 89 + .../zlib-ng-2.1.0-beta1/tools/maketrees.c | 147 + internal-complibs/zlib-ng-2.1.0-beta1/trees.c | 818 ++ internal-complibs/zlib-ng-2.1.0-beta1/trees.h | 40 + .../zlib-ng-2.1.0-beta1/trees_emit.h | 227 + .../zlib-ng-2.1.0-beta1/trees_tbl.h | 132 + .../zlib-ng-2.1.0-beta1/uncompr.c | 80 + .../zlib-ng-2.1.0-beta1/win32/Makefile.a64 | 243 + .../zlib-ng-2.1.0-beta1/win32/Makefile.arm | 255 + .../zlib-ng-2.1.0-beta1/win32/Makefile.msc | 266 + .../zlib-ng-2.1.0-beta1/win32/replace.vbs | 15 + .../zlib-ng-2.1.0-beta1/win32/zlib-ng.def.in | 60 + .../zlib-ng-2.1.0-beta1/win32/zlib-ng1.rc | 36 + .../zlib-ng-2.1.0-beta1/win32/zlib.def.in | 64 + .../zlib-ng-2.1.0-beta1/win32/zlib1.rc | 36 + .../win32/zlibcompat.def.in | 97 + .../zlib-ng-2.1.0-beta1/zbuild.h | 253 + .../zlib-ng-2.1.0-beta1/zconf-ng.h.in | 176 + .../zlib-ng-2.1.0-beta1/zconf.h.in | 201 + .../zlib-ng-2.1.0-beta1/zendian.h | 60 + .../zlib-ng-2.1.0-beta1/zlib-ng.h.in | 1869 ++++ .../zlib-ng-2.1.0-beta1/zlib-ng.map | 111 + .../zlib-ng-2.1.0-beta1/zlib.h.in | 1855 ++++ .../zlib-ng-2.1.0-beta1/zlib.map | 97 + .../zlib-ng-2.1.0-beta1/zlib.pc.cmakein | 14 + .../zlib-ng-2.1.0-beta1/zlib.pc.in | 14 + .../zlib_name_mangling-ng.h.in | 178 + .../zlib_name_mangling.h.empty | 8 + .../zlib_name_mangling.h.in | 170 + internal-complibs/zlib-ng-2.1.0-beta1/zutil.c | 159 + internal-complibs/zlib-ng-2.1.0-beta1/zutil.h | 148 + .../zlib-ng-2.1.0-beta1/zutil_p.h | 71 + .../zlib-ng-2.1.1-beta2/.codecov.yaml | 27 + .../zlib-ng-2.1.1-beta2/.gitattributes | 8 + .../zlib-ng-2.1.1-beta2/.github/FUNDING.yml | 1 + .../.github/workflows/analyze.yml | 78 + .../.github/workflows/cmake.yml | 623 ++ .../.github/workflows/codeql.yml | 41 + .../.github/workflows/configure.yml | 238 + .../.github/workflows/fuzz.yml | 36 + .../.github/workflows/libpng.yml | 51 + .../.github/workflows/link.yml | 66 + .../.github/workflows/nmake.yml | 68 + .../.github/workflows/pigz.yml | 131 + .../.github/workflows/pkgcheck.yml | 176 + .../.github/workflows/release.yml | 100 + .../zlib-ng-2.1.1-beta2/.gitignore | 97 + .../zlib-ng-2.1.1-beta2/.shellcheckrc | 1 + .../zlib-ng-2.1.1-beta2/CMakeLists.txt | 1268 +++ .../zlib-ng-2.1.1-beta2/FAQ.zlib | 374 + .../zlib-ng-2.1.1-beta2/INDEX.md | 36 + .../zlib-ng-2.1.1-beta2/LICENSE.md | 19 + .../zlib-ng-2.1.1-beta2/Makefile.in | 395 + .../zlib-ng-2.1.1-beta2/PORTING.md | 79 + .../zlib-ng-2.1.1-beta2/README.md | 216 + .../zlib-ng-2.1.1-beta2/adler32.c | 115 + .../zlib-ng-2.1.1-beta2/adler32_fold.c | 16 + .../zlib-ng-2.1.1-beta2/adler32_fold.h | 11 + .../zlib-ng-2.1.1-beta2/adler32_p.h | 70 + .../zlib-ng-2.1.1-beta2/arch/.gitignore | 2 + .../zlib-ng-2.1.1-beta2/arch/arm/Makefile.in | 77 + .../arch/arm/adler32_neon.c | 215 + .../arch/arm/arm_features.c | 82 + .../arch/arm/arm_features.h | 15 + .../arch/arm/chunkset_neon.c | 101 + .../arch/arm/compare256_neon.c | 59 + .../zlib-ng-2.1.1-beta2/arch/arm/crc32_acle.c | 98 + .../arch/arm/insert_string_acle.c | 26 + .../arch/arm/neon_intrins.h | 57 + .../arch/arm/slide_hash_neon.c | 46 + .../arch/generic/Makefile.in | 21 + .../arch/generic/chunk_permute_table.h | 53 + .../arch/power/Makefile.in | 93 + .../arch/power/adler32_power8.c | 153 + .../arch/power/adler32_vmx.c | 181 + .../arch/power/chunkset_power8.c | 55 + .../arch/power/compare256_power9.c | 66 + .../arch/power/crc32_constants.h | 1123 ++ .../arch/power/crc32_power8.c | 589 + .../arch/power/fallback_builtins.h | 31 + .../arch/power/power_features.c | 42 + .../arch/power/power_features.h | 18 + .../arch/power/slide_hash_power8.c | 12 + .../arch/power/slide_hash_vmx.c | 10 + .../arch/power/slide_ppc_tpl.h | 31 + .../zlib-ng-2.1.1-beta2/arch/riscv/README.md | 45 + .../arch/riscv/riscv_features.c | 15 + .../arch/riscv/riscv_features.h | 18 + .../zlib-ng-2.1.1-beta2/arch/s390/Makefile.in | 54 + .../zlib-ng-2.1.1-beta2/arch/s390/README.md | 284 + .../zlib-ng-2.1.1-beta2/arch/s390/crc32-vx.c | 222 + .../arch/s390/dfltcc_common.c | 40 + .../arch/s390/dfltcc_common.h | 44 + .../arch/s390/dfltcc_deflate.c | 404 + .../arch/s390/dfltcc_deflate.h | 60 + .../arch/s390/dfltcc_detail.h | 312 + .../arch/s390/dfltcc_inflate.c | 205 + .../arch/s390/dfltcc_inflate.h | 70 + .../arch/s390/s390_features.c | 14 + .../arch/s390/s390_features.h | 10 + .../actions-runner.Dockerfile | 45 + .../actions-runner.service | 24 + .../fs/usr/bin/actions-runner | 40 + .../self-hosted-builder/fs/usr/bin/entrypoint | 30 + .../qemu-user-static.service | 11 + .../zlib-ng-2.1.1-beta2/arch/x86/Makefile.in | 147 + .../arch/x86/adler32_avx2.c | 17 + .../arch/x86/adler32_avx2_p.h | 32 + .../arch/x86/adler32_avx2_tpl.h | 141 + .../arch/x86/adler32_avx512.c | 16 + .../arch/x86/adler32_avx512_p.h | 46 + .../arch/x86/adler32_avx512_tpl.h | 106 + .../arch/x86/adler32_avx512_vnni.c | 225 + .../arch/x86/adler32_sse42.c | 121 + .../arch/x86/adler32_ssse3.c | 156 + .../arch/x86/adler32_ssse3_p.h | 29 + .../arch/x86/chunkset_avx2.c | 135 + .../arch/x86/chunkset_sse2.c | 56 + .../arch/x86/chunkset_ssse3.c | 103 + .../arch/x86/compare256_avx2.c | 63 + .../arch/x86/compare256_sse2.c | 96 + .../arch/x86/crc32_fold_pclmulqdq_tpl.h | 186 + .../arch/x86/crc32_fold_vpclmulqdq_tpl.h | 107 + .../arch/x86/crc32_pclmulqdq.c | 30 + .../arch/x86/crc32_pclmulqdq_tpl.h | 363 + .../arch/x86/crc32_vpclmulqdq.c | 17 + .../arch/x86/insert_string_sse42.c | 50 + .../arch/x86/slide_hash_avx2.c | 39 + .../arch/x86/slide_hash_sse2.c | 62 + .../arch/x86/x86_features.c | 97 + .../arch/x86/x86_features.h | 24 + .../zlib-ng-2.1.1-beta2/chunkset.c | 42 + .../zlib-ng-2.1.1-beta2/chunkset_tpl.h | 200 + .../zlib-ng-2.1.1-beta2/cmake/detect-arch.c | 111 + .../cmake/detect-arch.cmake | 101 + .../cmake/detect-coverage.cmake | 46 + .../cmake/detect-install-dirs.cmake | 43 + .../cmake/detect-intrinsics.cmake | 548 + .../cmake/detect-sanitizer.cmake | 166 + .../cmake/fallback-macros.cmake | 19 + .../cmake/toolchain-aarch64.cmake | 24 + .../cmake/toolchain-arm.cmake | 29 + .../cmake/toolchain-armhf.cmake | 25 + .../cmake/toolchain-mingw-i686.cmake | 35 + .../cmake/toolchain-mingw-x86_64.cmake | 34 + .../cmake/toolchain-powerpc.cmake | 25 + .../cmake/toolchain-powerpc64.cmake | 25 + .../cmake/toolchain-powerpc64le.cmake | 25 + .../cmake/toolchain-riscv.cmake | 28 + .../cmake/toolchain-s390x.cmake | 25 + .../cmake/toolchain-sparc64.cmake | 25 + .../zlib-ng-2.1.1-beta2/compare256.c | 180 + .../zlib-ng-2.1.1-beta2/compare256_rle.h | 134 + .../zlib-ng-2.1.1-beta2/compress.c | 98 + .../zlib-ng-2.1.1-beta2/configure | 2318 ++++ .../zlib-ng-2.1.1-beta2/cpu_features.c | 23 + .../zlib-ng-2.1.1-beta2/cpu_features.h | 274 + .../zlib-ng-2.1.1-beta2/crc32_braid.c | 267 + .../zlib-ng-2.1.1-beta2/crc32_braid_comb.c | 57 + .../zlib-ng-2.1.1-beta2/crc32_braid_comb_p.h | 42 + .../zlib-ng-2.1.1-beta2/crc32_braid_p.h | 50 + .../zlib-ng-2.1.1-beta2/crc32_braid_tbl.h | 9446 +++++++++++++++++ .../zlib-ng-2.1.1-beta2/crc32_fold.c | 33 + .../zlib-ng-2.1.1-beta2/crc32_fold.h | 21 + .../zlib-ng-2.1.1-beta2/deflate.c | 1427 +++ .../zlib-ng-2.1.1-beta2/deflate.h | 403 + .../zlib-ng-2.1.1-beta2/deflate_fast.c | 102 + .../zlib-ng-2.1.1-beta2/deflate_huff.c | 45 + .../zlib-ng-2.1.1-beta2/deflate_medium.c | 293 + .../zlib-ng-2.1.1-beta2/deflate_p.h | 116 + .../zlib-ng-2.1.1-beta2/deflate_quick.c | 129 + .../zlib-ng-2.1.1-beta2/deflate_rle.c | 85 + .../zlib-ng-2.1.1-beta2/deflate_slow.c | 143 + .../zlib-ng-2.1.1-beta2/deflate_stored.c | 186 + .../zlib-ng-2.1.1-beta2/doc/algorithm.txt | 209 + .../zlib-ng-2.1.1-beta2/doc/crc-doc.1.0.pdf | Bin 0 -> 776142 bytes .../zlib-ng-2.1.1-beta2/doc/crc-pclmulqdq.pdf | Bin 0 -> 384202 bytes .../zlib-ng-2.1.1-beta2/doc/rfc1950.txt | 619 ++ .../zlib-ng-2.1.1-beta2/doc/rfc1951.txt | 955 ++ .../zlib-ng-2.1.1-beta2/doc/rfc1952.txt | 675 ++ .../zlib-ng-2.1.1-beta2/doc/txtvsbin.txt | 107 + .../zlib-ng-2.1.1-beta2/fallback_builtins.h | 133 + .../zlib-ng-2.1.1-beta2/functable.c | 336 + .../zlib-ng-2.1.1-beta2/functable.h | 41 + .../zlib-ng-2.1.1-beta2/gzguts.h | 145 + internal-complibs/zlib-ng-2.1.1-beta2/gzlib.c | 525 + .../zlib-ng-2.1.1-beta2/gzread.c.in | 602 ++ .../zlib-ng-2.1.1-beta2/gzwrite.c | 526 + .../zlib-ng-2.1.1-beta2/infback.c | 511 + .../zlib-ng-2.1.1-beta2/inffast_tpl.h | 326 + .../zlib-ng-2.1.1-beta2/inffixed_tbl.h | 94 + .../zlib-ng-2.1.1-beta2/inflate.c | 1408 +++ .../zlib-ng-2.1.1-beta2/inflate.h | 140 + .../zlib-ng-2.1.1-beta2/inflate_p.h | 225 + .../zlib-ng-2.1.1-beta2/inftrees.c | 295 + .../zlib-ng-2.1.1-beta2/inftrees.h | 66 + .../zlib-ng-2.1.1-beta2/insert_string.c | 21 + .../zlib-ng-2.1.1-beta2/insert_string_roll.c | 24 + .../zlib-ng-2.1.1-beta2/insert_string_tpl.h | 108 + .../zlib-ng-2.1.1-beta2/match_tpl.h | 289 + .../zlib-ng-2.1.1-beta2/slide_hash.c | 52 + .../zlib-ng-2.1.1-beta2/test/.gitignore | 5 + .../zlib-ng-2.1.1-beta2/test/CMakeLists.txt | 257 + .../test/CVE-2002-0059/test.gz | Bin 0 -> 4610 bytes .../test/CVE-2004-0797/test.gz | Bin 0 -> 52 bytes .../test/CVE-2005-1849/test.gz | Bin 0 -> 52 bytes .../test/CVE-2005-2096/test.gz | Bin 0 -> 52 bytes .../test/CVE-2018-25032/default.txt | 1 + .../test/CVE-2018-25032/fixed.txt | 1 + .../zlib-ng-2.1.1-beta2/test/GH-361/test.txt | 4 + .../zlib-ng-2.1.1-beta2/test/GH-364/test.bin | Bin 0 -> 8 bytes .../test/GH-382/defneg3.dat | 1 + .../zlib-ng-2.1.1-beta2/test/GH-751/test.txt | 1 + .../test/GH-979/pigz-2.6.tar.gz | Bin 0 -> 106840 bytes .../zlib-ng-2.1.1-beta2/test/Makefile.in | 82 + .../zlib-ng-2.1.1-beta2/test/README.md | 37 + .../zlib-ng-2.1.1-beta2/test/abi/ignore | 12 + ...c2a18c1281fc-aarch64-unknown-linux-gnu.abi | 1286 +++ ...c2a18c1281fc-arm-unknown-linux-gnueabi.abi | 1276 +++ ...a18c1281fc-arm-unknown-linux-gnueabihf.abi | 1276 +++ ...c2a18c1281fc-powerpc-unknown-linux-gnu.abi | 1286 +++ ...a18c1281fc-powerpc64-unknown-linux-gnu.abi | 1268 +++ ...8c1281fc-powerpc64le-unknown-linux-gnu.abi | 1268 +++ ...06c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi | 1263 +++ ...e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi | 1281 +++ ...4baf80882311-aarch64-unknown-linux-gnu.abi | 1904 ++++ ...4baf80882311-arm-unknown-linux-gnueabi.abi | 1889 ++++ ...af80882311-arm-unknown-linux-gnueabihf.abi | 1881 ++++ ...4baf80882311-powerpc-unknown-linux-gnu.abi | 1895 ++++ ...af80882311-powerpc64-unknown-linux-gnu.abi | 1894 ++++ ...80882311-powerpc64le-unknown-linux-gnu.abi | 1886 ++++ ...5e4baf80882311-x86_64-pc-linux-gnu-m32.abi | 2032 ++++ ...3c155e4baf80882311-x86_64-pc-linux-gnu.abi | 2064 ++++ .../zlib-ng-2.1.1-beta2/test/abicheck.md | 59 + .../zlib-ng-2.1.1-beta2/test/abicheck.sh | 163 + .../add-subdirectory-project/CMakeLists.txt | 13 + .../test/add-subdirectory-project/main.c | 7 + .../test/benchmarks/CMakeLists.txt | 109 + .../test/benchmarks/README.md | 47 + .../test/benchmarks/benchmark_adler32.cc | 89 + .../test/benchmarks/benchmark_adler32_copy.cc | 118 + .../test/benchmarks/benchmark_compare256.cc | 84 + .../benchmarks/benchmark_compare256_rle.cc | 73 + .../test/benchmarks/benchmark_crc32.cc | 69 + .../test/benchmarks/benchmark_main.cc | 28 + .../test/benchmarks/benchmark_png_decode.cc | 126 + .../test/benchmarks/benchmark_png_encode.cc | 54 + .../test/benchmarks/benchmark_png_shared.h | 146 + .../test/benchmarks/benchmark_slidehash.cc | 86 + .../test/cmake/compress-and-verify.cmake | 286 + .../test/cmake/run-and-compare.cmake | 72 + .../test/cmake/run-and-redirect.cmake | 54 + .../test/cmake/test-cves.cmake | 33 + .../test/cmake/test-data.cmake | 68 + .../test/cmake/test-issues.cmake | 68 + .../test/cmake/test-tools.cmake | 80 + .../test/data/fireworks.jpg | Bin 0 -> 123093 bytes .../zlib-ng-2.1.1-beta2/test/data/lcet10.txt | 7519 +++++++++++++ .../test/data/paper-100k.pdf | Bin 0 -> 102400 bytes .../zlib-ng-2.1.1-beta2/test/example.c | 1016 ++ .../test/fuzz/CMakeLists.txt | 49 + .../test/fuzz/fuzzer_checksum.c | 81 + .../test/fuzz/fuzzer_compress.c | 82 + .../test/fuzz/fuzzer_example_dict.c | 164 + .../test/fuzz/fuzzer_example_flush.c | 119 + .../test/fuzz/fuzzer_example_large.c | 137 + .../test/fuzz/fuzzer_example_small.c | 118 + .../test/fuzz/fuzzer_minigzip.c | 325 + .../test/fuzz/standalone_fuzz_target_runner.c | 37 + .../zlib-ng-2.1.1-beta2/test/gh1235.c | 39 + .../zlib-ng-2.1.1-beta2/test/infcover.c | 686 ++ .../zlib-ng-2.1.1-beta2/test/minideflate.c | 359 + .../zlib-ng-2.1.1-beta2/test/minigzip.c | 378 + .../test/pigz/CMakeLists.txt | 211 + .../zlib-ng-2.1.1-beta2/test/pkgcheck.sh | 176 + .../zlib-ng-2.1.1-beta2/test/switchlevels.c | 167 + .../zlib-ng-2.1.1-beta2/test/test_adler32.cc | 386 + .../test/test_aligned_alloc.cc | 48 + .../test/test_compare256.cc | 83 + .../test/test_compare256_rle.cc | 63 + .../zlib-ng-2.1.1-beta2/test/test_compress.cc | 33 + .../test/test_compress_bound.cc | 59 + .../test/test_compress_dual.cc | 28 + .../test/test_cpu_features.h | 8 + .../zlib-ng-2.1.1-beta2/test/test_crc32.cc | 222 + .../test/test_cve-2003-0107.cc | 28 + .../test/test_deflate_bound.cc | 99 + .../test/test_deflate_concurrency.cc | 170 + .../test/test_deflate_copy.cc | 60 + .../test/test_deflate_dict.cc | 54 + .../test/test_deflate_hash_head_0.cc | 83 + .../test/test_deflate_header.cc | 71 + .../test/test_deflate_params.cc | 143 + .../test/test_deflate_pending.cc | 66 + .../test/test_deflate_prime.cc | 91 + .../test/test_deflate_quick_bi_valid.cc | 80 + .../test/test_deflate_quick_block_open.cc | 94 + .../test/test_deflate_tune.cc | 56 + .../zlib-ng-2.1.1-beta2/test/test_dict.cc | 96 + .../zlib-ng-2.1.1-beta2/test/test_gzio.cc | 105 + .../test/test_inflate_adler32.cc | 50 + .../test/test_inflate_sync.cc | 75 + .../test/test_large_buffers.cc | 87 + .../zlib-ng-2.1.1-beta2/test/test_main.cc | 19 + .../zlib-ng-2.1.1-beta2/test/test_raw.cc | 58 + .../zlib-ng-2.1.1-beta2/test/test_shared.h | 18 + .../zlib-ng-2.1.1-beta2/test/test_shared_ng.h | 23 + .../test/test_small_buffers.cc | 69 + .../test/test_small_window.cc | 67 + .../zlib-ng-2.1.1-beta2/test/test_version.cc | 27 + .../zlib-ng-2.1.1-beta2/tools/config.sub | 17 + .../zlib-ng-2.1.1-beta2/tools/makecrct.c | 250 + .../zlib-ng-2.1.1-beta2/tools/makefixed.c | 89 + .../zlib-ng-2.1.1-beta2/tools/maketrees.c | 147 + internal-complibs/zlib-ng-2.1.1-beta2/trees.c | 818 ++ internal-complibs/zlib-ng-2.1.1-beta2/trees.h | 40 + .../zlib-ng-2.1.1-beta2/trees_emit.h | 227 + .../zlib-ng-2.1.1-beta2/trees_tbl.h | 132 + .../zlib-ng-2.1.1-beta2/uncompr.c | 80 + .../zlib-ng-2.1.1-beta2/win32/Makefile.a64 | 243 + .../zlib-ng-2.1.1-beta2/win32/Makefile.arm | 255 + .../zlib-ng-2.1.1-beta2/win32/Makefile.msc | 266 + .../zlib-ng-2.1.1-beta2/win32/replace.vbs | 15 + .../zlib-ng-2.1.1-beta2/win32/zlib-ng.def.in | 60 + .../zlib-ng-2.1.1-beta2/win32/zlib-ng1.rc | 36 + .../zlib-ng-2.1.1-beta2/win32/zlib.def.in | 64 + .../zlib-ng-2.1.1-beta2/win32/zlib1.rc | 36 + .../win32/zlibcompat.def.in | 97 + .../zlib-ng-2.1.1-beta2/zbuild.h | 248 + .../zlib-ng-2.1.1-beta2/zconf-ng.h.in | 176 + .../zlib-ng-2.1.1-beta2/zconf.h.in | 203 + .../zlib-ng-2.1.1-beta2/zendian.h | 60 + .../zlib-ng-2.1.1-beta2/zlib-ng.h.in | 1867 ++++ .../zlib-ng-2.1.1-beta2/zlib-ng.map | 111 + .../zlib-ng-2.1.1-beta2/zlib.h.in | 1855 ++++ .../zlib-ng-2.1.1-beta2/zlib.map | 97 + .../zlib-ng-2.1.1-beta2/zlib.pc.cmakein | 14 + .../zlib-ng-2.1.1-beta2/zlib.pc.in | 14 + .../zlib_name_mangling-ng.h.in | 178 + .../zlib_name_mangling.h.empty | 8 + .../zlib_name_mangling.h.in | 170 + internal-complibs/zlib-ng-2.1.1-beta2/zutil.c | 159 + internal-complibs/zlib-ng-2.1.1-beta2/zutil.h | 148 + .../zlib-ng-2.1.1-beta2/zutil_p.h | 71 + internal-complibs/zlib-ng-2.1.2/.codecov.yaml | 27 + .../zlib-ng-2.1.2/.gitattributes | 8 + .../zlib-ng-2.1.2/.github/FUNDING.yml | 1 + .../.github/workflows/analyze.yml | 78 + .../zlib-ng-2.1.2/.github/workflows/cmake.yml | 635 ++ .../.github/workflows/codeql.yml | 41 + .../.github/workflows/configure.yml | 252 + .../zlib-ng-2.1.2/.github/workflows/fuzz.yml | 36 + .../.github/workflows/libpng.yml | 51 + .../zlib-ng-2.1.2/.github/workflows/link.yml | 66 + .../zlib-ng-2.1.2/.github/workflows/nmake.yml | 68 + .../zlib-ng-2.1.2/.github/workflows/pigz.yml | 131 + .../.github/workflows/pkgcheck.yml | 192 + .../.github/workflows/release.yml | 100 + internal-complibs/zlib-ng-2.1.2/.gitignore | 97 + internal-complibs/zlib-ng-2.1.2/.shellcheckrc | 1 + .../zlib-ng-2.1.2/CMakeLists.txt | 1268 +++ internal-complibs/zlib-ng-2.1.2/FAQ.zlib | 374 + internal-complibs/zlib-ng-2.1.2/INDEX.md | 36 + internal-complibs/zlib-ng-2.1.2/LICENSE.md | 19 + internal-complibs/zlib-ng-2.1.2/Makefile.in | 395 + internal-complibs/zlib-ng-2.1.2/PORTING.md | 79 + internal-complibs/zlib-ng-2.1.2/README.md | 216 + internal-complibs/zlib-ng-2.1.2/adler32.c | 115 + .../zlib-ng-2.1.2/adler32_fold.c | 16 + .../zlib-ng-2.1.2/adler32_fold.h | 11 + internal-complibs/zlib-ng-2.1.2/adler32_p.h | 70 + .../zlib-ng-2.1.2/arch/.gitignore | 2 + .../zlib-ng-2.1.2/arch/arm/Makefile.in | 77 + .../zlib-ng-2.1.2/arch/arm/adler32_neon.c | 215 + .../zlib-ng-2.1.2/arch/arm/arm_features.c | 82 + .../zlib-ng-2.1.2/arch/arm/arm_features.h | 15 + .../zlib-ng-2.1.2/arch/arm/chunkset_neon.c | 101 + .../zlib-ng-2.1.2/arch/arm/compare256_neon.c | 59 + .../zlib-ng-2.1.2/arch/arm/crc32_acle.c | 98 + .../arch/arm/insert_string_acle.c | 26 + .../zlib-ng-2.1.2/arch/arm/neon_intrins.h | 57 + .../zlib-ng-2.1.2/arch/arm/slide_hash_neon.c | 46 + .../zlib-ng-2.1.2/arch/generic/Makefile.in | 24 + .../arch/generic/chunk_permute_table.h | 53 + .../zlib-ng-2.1.2/arch/power/Makefile.in | 93 + .../zlib-ng-2.1.2/arch/power/adler32_power8.c | 153 + .../zlib-ng-2.1.2/arch/power/adler32_vmx.c | 181 + .../arch/power/chunkset_power8.c | 55 + .../arch/power/compare256_power9.c | 66 + .../arch/power/crc32_constants.h | 1123 ++ .../zlib-ng-2.1.2/arch/power/crc32_power8.c | 589 + .../arch/power/fallback_builtins.h | 31 + .../zlib-ng-2.1.2/arch/power/power_features.c | 42 + .../zlib-ng-2.1.2/arch/power/power_features.h | 18 + .../arch/power/slide_hash_power8.c | 12 + .../zlib-ng-2.1.2/arch/power/slide_hash_vmx.c | 10 + .../zlib-ng-2.1.2/arch/power/slide_ppc_tpl.h | 31 + .../zlib-ng-2.1.2/arch/riscv/README.md | 45 + .../zlib-ng-2.1.2/arch/riscv/riscv_features.c | 15 + .../zlib-ng-2.1.2/arch/riscv/riscv_features.h | 18 + .../zlib-ng-2.1.2/arch/s390/Makefile.in | 54 + .../zlib-ng-2.1.2/arch/s390/README.md | 284 + .../zlib-ng-2.1.2/arch/s390/crc32-vx.c | 222 + .../zlib-ng-2.1.2/arch/s390/dfltcc_common.c | 40 + .../zlib-ng-2.1.2/arch/s390/dfltcc_common.h | 44 + .../zlib-ng-2.1.2/arch/s390/dfltcc_deflate.c | 404 + .../zlib-ng-2.1.2/arch/s390/dfltcc_deflate.h | 60 + .../zlib-ng-2.1.2/arch/s390/dfltcc_detail.h | 312 + .../zlib-ng-2.1.2/arch/s390/dfltcc_inflate.c | 205 + .../zlib-ng-2.1.2/arch/s390/dfltcc_inflate.h | 70 + .../zlib-ng-2.1.2/arch/s390/s390_features.c | 14 + .../zlib-ng-2.1.2/arch/s390/s390_features.h | 10 + .../actions-runner.Dockerfile | 45 + .../actions-runner.service | 24 + .../fs/usr/bin/actions-runner | 40 + .../self-hosted-builder/fs/usr/bin/entrypoint | 30 + .../qemu-user-static.service | 11 + .../zlib-ng-2.1.2/arch/x86/Makefile.in | 147 + .../zlib-ng-2.1.2/arch/x86/adler32_avx2.c | 17 + .../zlib-ng-2.1.2/arch/x86/adler32_avx2_p.h | 32 + .../zlib-ng-2.1.2/arch/x86/adler32_avx2_tpl.h | 141 + .../zlib-ng-2.1.2/arch/x86/adler32_avx512.c | 16 + .../zlib-ng-2.1.2/arch/x86/adler32_avx512_p.h | 46 + .../arch/x86/adler32_avx512_tpl.h | 106 + .../arch/x86/adler32_avx512_vnni.c | 225 + .../zlib-ng-2.1.2/arch/x86/adler32_sse42.c | 121 + .../zlib-ng-2.1.2/arch/x86/adler32_ssse3.c | 156 + .../zlib-ng-2.1.2/arch/x86/adler32_ssse3_p.h | 29 + .../zlib-ng-2.1.2/arch/x86/chunkset_avx2.c | 135 + .../zlib-ng-2.1.2/arch/x86/chunkset_sse2.c | 56 + .../zlib-ng-2.1.2/arch/x86/chunkset_ssse3.c | 103 + .../zlib-ng-2.1.2/arch/x86/compare256_avx2.c | 63 + .../zlib-ng-2.1.2/arch/x86/compare256_sse2.c | 96 + .../arch/x86/crc32_fold_pclmulqdq_tpl.h | 186 + .../arch/x86/crc32_fold_vpclmulqdq_tpl.h | 107 + .../zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq.c | 30 + .../arch/x86/crc32_pclmulqdq_tpl.h | 363 + .../zlib-ng-2.1.2/arch/x86/crc32_vpclmulqdq.c | 17 + .../arch/x86/insert_string_sse42.c | 50 + .../zlib-ng-2.1.2/arch/x86/slide_hash_avx2.c | 39 + .../zlib-ng-2.1.2/arch/x86/slide_hash_sse2.c | 62 + .../zlib-ng-2.1.2/arch/x86/x86_features.c | 97 + .../zlib-ng-2.1.2/arch/x86/x86_features.h | 24 + internal-complibs/zlib-ng-2.1.2/chunkset.c | 42 + .../zlib-ng-2.1.2/chunkset_tpl.h | 200 + .../zlib-ng-2.1.2/cmake/detect-arch.c | 111 + .../zlib-ng-2.1.2/cmake/detect-arch.cmake | 101 + .../zlib-ng-2.1.2/cmake/detect-coverage.cmake | 46 + .../cmake/detect-install-dirs.cmake | 43 + .../cmake/detect-intrinsics.cmake | 548 + .../cmake/detect-sanitizer.cmake | 166 + .../zlib-ng-2.1.2/cmake/fallback-macros.cmake | 19 + .../cmake/toolchain-aarch64.cmake | 24 + .../zlib-ng-2.1.2/cmake/toolchain-arm.cmake | 29 + .../zlib-ng-2.1.2/cmake/toolchain-armhf.cmake | 25 + .../cmake/toolchain-mingw-i686.cmake | 35 + .../cmake/toolchain-mingw-x86_64.cmake | 34 + .../zlib-ng-2.1.2/cmake/toolchain-mips.cmake | 29 + .../cmake/toolchain-mips64.cmake | 29 + .../cmake/toolchain-powerpc.cmake | 25 + .../cmake/toolchain-powerpc64.cmake | 25 + .../cmake/toolchain-powerpc64le.cmake | 25 + .../zlib-ng-2.1.2/cmake/toolchain-riscv.cmake | 28 + .../zlib-ng-2.1.2/cmake/toolchain-s390x.cmake | 25 + .../cmake/toolchain-sparc64.cmake | 25 + internal-complibs/zlib-ng-2.1.2/compare256.c | 180 + .../zlib-ng-2.1.2/compare256_rle.h | 134 + internal-complibs/zlib-ng-2.1.2/compress.c | 98 + internal-complibs/zlib-ng-2.1.2/configure | 2326 ++++ .../zlib-ng-2.1.2/cpu_features.c | 23 + .../zlib-ng-2.1.2/cpu_features.h | 274 + internal-complibs/zlib-ng-2.1.2/crc32_braid.c | 267 + .../zlib-ng-2.1.2/crc32_braid_comb.c | 57 + .../zlib-ng-2.1.2/crc32_braid_comb_p.h | 42 + .../zlib-ng-2.1.2/crc32_braid_p.h | 50 + .../zlib-ng-2.1.2/crc32_braid_tbl.h | 9446 +++++++++++++++++ internal-complibs/zlib-ng-2.1.2/crc32_fold.c | 33 + internal-complibs/zlib-ng-2.1.2/crc32_fold.h | 21 + internal-complibs/zlib-ng-2.1.2/deflate.c | 1427 +++ internal-complibs/zlib-ng-2.1.2/deflate.h | 403 + .../zlib-ng-2.1.2/deflate_fast.c | 102 + .../zlib-ng-2.1.2/deflate_huff.c | 45 + .../zlib-ng-2.1.2/deflate_medium.c | 293 + internal-complibs/zlib-ng-2.1.2/deflate_p.h | 116 + .../zlib-ng-2.1.2/deflate_quick.c | 129 + internal-complibs/zlib-ng-2.1.2/deflate_rle.c | 85 + .../zlib-ng-2.1.2/deflate_slow.c | 143 + .../zlib-ng-2.1.2/deflate_stored.c | 186 + .../zlib-ng-2.1.2/doc/algorithm.txt | 209 + .../zlib-ng-2.1.2/doc/crc-doc.1.0.pdf | Bin 0 -> 776142 bytes .../zlib-ng-2.1.2/doc/crc-pclmulqdq.pdf | Bin 0 -> 384202 bytes .../zlib-ng-2.1.2/doc/rfc1950.txt | 619 ++ .../zlib-ng-2.1.2/doc/rfc1951.txt | 955 ++ .../zlib-ng-2.1.2/doc/rfc1952.txt | 675 ++ .../zlib-ng-2.1.2/doc/txtvsbin.txt | 107 + .../zlib-ng-2.1.2/fallback_builtins.h | 133 + internal-complibs/zlib-ng-2.1.2/functable.c | 336 + internal-complibs/zlib-ng-2.1.2/functable.h | 41 + internal-complibs/zlib-ng-2.1.2/gzguts.h | 145 + internal-complibs/zlib-ng-2.1.2/gzlib.c | 525 + internal-complibs/zlib-ng-2.1.2/gzread.c.in | 602 ++ internal-complibs/zlib-ng-2.1.2/gzwrite.c | 526 + internal-complibs/zlib-ng-2.1.2/infback.c | 511 + internal-complibs/zlib-ng-2.1.2/inffast_tpl.h | 326 + .../zlib-ng-2.1.2/inffixed_tbl.h | 94 + internal-complibs/zlib-ng-2.1.2/inflate.c | 1408 +++ internal-complibs/zlib-ng-2.1.2/inflate.h | 140 + internal-complibs/zlib-ng-2.1.2/inflate_p.h | 225 + internal-complibs/zlib-ng-2.1.2/inftrees.c | 295 + internal-complibs/zlib-ng-2.1.2/inftrees.h | 66 + .../zlib-ng-2.1.2/insert_string.c | 21 + .../zlib-ng-2.1.2/insert_string_roll.c | 24 + .../zlib-ng-2.1.2/insert_string_tpl.h | 108 + internal-complibs/zlib-ng-2.1.2/match_tpl.h | 289 + internal-complibs/zlib-ng-2.1.2/slide_hash.c | 52 + .../zlib-ng-2.1.2/test/.gitignore | 5 + .../zlib-ng-2.1.2/test/CMakeLists.txt | 257 + .../zlib-ng-2.1.2/test/CVE-2002-0059/test.gz | Bin 0 -> 4610 bytes .../zlib-ng-2.1.2/test/CVE-2004-0797/test.gz | Bin 0 -> 52 bytes .../zlib-ng-2.1.2/test/CVE-2005-1849/test.gz | Bin 0 -> 52 bytes .../zlib-ng-2.1.2/test/CVE-2005-2096/test.gz | Bin 0 -> 52 bytes .../test/CVE-2018-25032/default.txt | 1 + .../test/CVE-2018-25032/fixed.txt | 1 + .../zlib-ng-2.1.2/test/GH-361/test.txt | 4 + .../zlib-ng-2.1.2/test/GH-364/test.bin | Bin 0 -> 8 bytes .../zlib-ng-2.1.2/test/GH-382/defneg3.dat | 1 + .../zlib-ng-2.1.2/test/GH-751/test.txt | 1 + .../zlib-ng-2.1.2/test/GH-979/pigz-2.6.tar.gz | Bin 0 -> 106840 bytes .../zlib-ng-2.1.2/test/Makefile.in | 82 + .../zlib-ng-2.1.2/test/README.md | 37 + .../zlib-ng-2.1.2/test/abi/ignore | 12 + ...c2a18c1281fc-aarch64-unknown-linux-gnu.abi | 1286 +++ ...c2a18c1281fc-arm-unknown-linux-gnueabi.abi | 1276 +++ ...a18c1281fc-arm-unknown-linux-gnueabihf.abi | 1276 +++ ...806c2a18c1281fc-mips-unknown-linux-gnu.abi | 1032 ++ ...8c1281fc-mips64-unknown-linux-gnuabi64.abi | 1030 ++ ...c2a18c1281fc-powerpc-unknown-linux-gnu.abi | 1286 +++ ...a18c1281fc-powerpc64-unknown-linux-gnu.abi | 1268 +++ ...8c1281fc-powerpc64le-unknown-linux-gnu.abi | 1268 +++ ...06c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi | 1263 +++ ...e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi | 1281 +++ ...4baf80882311-aarch64-unknown-linux-gnu.abi | 1904 ++++ ...4baf80882311-arm-unknown-linux-gnueabi.abi | 1889 ++++ ...af80882311-arm-unknown-linux-gnueabihf.abi | 1881 ++++ ...55e4baf80882311-mips-unknown-linux-gnu.abi | 1241 +++ ...80882311-mips64-unknown-linux-gnuabi64.abi | 1250 +++ ...4baf80882311-powerpc-unknown-linux-gnu.abi | 1895 ++++ ...af80882311-powerpc64-unknown-linux-gnu.abi | 1894 ++++ ...80882311-powerpc64le-unknown-linux-gnu.abi | 1886 ++++ ...5e4baf80882311-x86_64-pc-linux-gnu-m32.abi | 2032 ++++ ...3c155e4baf80882311-x86_64-pc-linux-gnu.abi | 2064 ++++ .../zlib-ng-2.1.2/test/abicheck.md | 59 + .../zlib-ng-2.1.2/test/abicheck.sh | 163 + .../add-subdirectory-project/CMakeLists.txt | 13 + .../test/add-subdirectory-project/main.c | 7 + .../test/benchmarks/CMakeLists.txt | 109 + .../zlib-ng-2.1.2/test/benchmarks/README.md | 47 + .../test/benchmarks/benchmark_adler32.cc | 89 + .../test/benchmarks/benchmark_adler32_copy.cc | 118 + .../test/benchmarks/benchmark_compare256.cc | 84 + .../benchmarks/benchmark_compare256_rle.cc | 73 + .../test/benchmarks/benchmark_crc32.cc | 69 + .../test/benchmarks/benchmark_main.cc | 28 + .../test/benchmarks/benchmark_png_decode.cc | 126 + .../test/benchmarks/benchmark_png_encode.cc | 54 + .../test/benchmarks/benchmark_png_shared.h | 146 + .../test/benchmarks/benchmark_slidehash.cc | 86 + .../test/cmake/compress-and-verify.cmake | 283 + .../test/cmake/run-and-compare.cmake | 72 + .../test/cmake/run-and-redirect.cmake | 54 + .../zlib-ng-2.1.2/test/cmake/test-cves.cmake | 33 + .../zlib-ng-2.1.2/test/cmake/test-data.cmake | 68 + .../test/cmake/test-issues.cmake | 68 + .../zlib-ng-2.1.2/test/cmake/test-tools.cmake | 80 + .../zlib-ng-2.1.2/test/data/fireworks.jpg | Bin 0 -> 123093 bytes .../zlib-ng-2.1.2/test/data/lcet10.txt | 7519 +++++++++++++ .../zlib-ng-2.1.2/test/data/paper-100k.pdf | Bin 0 -> 102400 bytes .../zlib-ng-2.1.2/test/example.c | 1016 ++ .../zlib-ng-2.1.2/test/fuzz/CMakeLists.txt | 49 + .../zlib-ng-2.1.2/test/fuzz/fuzzer_checksum.c | 81 + .../zlib-ng-2.1.2/test/fuzz/fuzzer_compress.c | 82 + .../test/fuzz/fuzzer_example_dict.c | 164 + .../test/fuzz/fuzzer_example_flush.c | 119 + .../test/fuzz/fuzzer_example_large.c | 137 + .../test/fuzz/fuzzer_example_small.c | 118 + .../zlib-ng-2.1.2/test/fuzz/fuzzer_minigzip.c | 325 + .../test/fuzz/standalone_fuzz_target_runner.c | 37 + internal-complibs/zlib-ng-2.1.2/test/gh1235.c | 39 + .../zlib-ng-2.1.2/test/infcover.c | 686 ++ .../zlib-ng-2.1.2/test/minideflate.c | 359 + .../zlib-ng-2.1.2/test/minigzip.c | 378 + .../zlib-ng-2.1.2/test/pigz/CMakeLists.txt | 211 + .../zlib-ng-2.1.2/test/pkgcheck.sh | 176 + .../zlib-ng-2.1.2/test/switchlevels.c | 167 + .../zlib-ng-2.1.2/test/test_adler32.cc | 386 + .../zlib-ng-2.1.2/test/test_aligned_alloc.cc | 48 + .../zlib-ng-2.1.2/test/test_compare256.cc | 83 + .../zlib-ng-2.1.2/test/test_compare256_rle.cc | 63 + .../zlib-ng-2.1.2/test/test_compress.cc | 33 + .../zlib-ng-2.1.2/test/test_compress_bound.cc | 59 + .../zlib-ng-2.1.2/test/test_compress_dual.cc | 28 + .../zlib-ng-2.1.2/test/test_cpu_features.h | 8 + .../zlib-ng-2.1.2/test/test_crc32.cc | 222 + .../zlib-ng-2.1.2/test/test_cve-2003-0107.cc | 28 + .../zlib-ng-2.1.2/test/test_deflate_bound.cc | 99 + .../test/test_deflate_concurrency.cc | 170 + .../zlib-ng-2.1.2/test/test_deflate_copy.cc | 60 + .../zlib-ng-2.1.2/test/test_deflate_dict.cc | 54 + .../test/test_deflate_hash_head_0.cc | 83 + .../zlib-ng-2.1.2/test/test_deflate_header.cc | 71 + .../zlib-ng-2.1.2/test/test_deflate_params.cc | 143 + .../test/test_deflate_pending.cc | 66 + .../zlib-ng-2.1.2/test/test_deflate_prime.cc | 91 + .../test/test_deflate_quick_bi_valid.cc | 80 + .../test/test_deflate_quick_block_open.cc | 94 + .../zlib-ng-2.1.2/test/test_deflate_tune.cc | 56 + .../zlib-ng-2.1.2/test/test_dict.cc | 96 + .../zlib-ng-2.1.2/test/test_gzio.cc | 105 + .../test/test_inflate_adler32.cc | 50 + .../zlib-ng-2.1.2/test/test_inflate_sync.cc | 75 + .../zlib-ng-2.1.2/test/test_large_buffers.cc | 87 + .../zlib-ng-2.1.2/test/test_main.cc | 19 + .../zlib-ng-2.1.2/test/test_raw.cc | 58 + .../zlib-ng-2.1.2/test/test_shared.h | 18 + .../zlib-ng-2.1.2/test/test_shared_ng.h | 23 + .../zlib-ng-2.1.2/test/test_small_buffers.cc | 69 + .../zlib-ng-2.1.2/test/test_small_window.cc | 67 + .../zlib-ng-2.1.2/test/test_version.cc | 27 + .../zlib-ng-2.1.2/tools/config.sub | 17 + .../zlib-ng-2.1.2/tools/makecrct.c | 250 + .../zlib-ng-2.1.2/tools/makefixed.c | 89 + .../zlib-ng-2.1.2/tools/maketrees.c | 147 + internal-complibs/zlib-ng-2.1.2/trees.c | 818 ++ internal-complibs/zlib-ng-2.1.2/trees.h | 40 + internal-complibs/zlib-ng-2.1.2/trees_emit.h | 227 + internal-complibs/zlib-ng-2.1.2/trees_tbl.h | 132 + internal-complibs/zlib-ng-2.1.2/uncompr.c | 80 + .../zlib-ng-2.1.2/win32/Makefile.a64 | 243 + .../zlib-ng-2.1.2/win32/Makefile.arm | 255 + .../zlib-ng-2.1.2/win32/Makefile.msc | 266 + .../zlib-ng-2.1.2/win32/replace.vbs | 15 + .../zlib-ng-2.1.2/win32/zlib-ng.def.in | 60 + .../zlib-ng-2.1.2/win32/zlib-ng1.rc | 36 + .../zlib-ng-2.1.2/win32/zlib.def.in | 64 + .../zlib-ng-2.1.2/win32/zlib1.rc | 36 + .../zlib-ng-2.1.2/win32/zlibcompat.def.in | 97 + internal-complibs/zlib-ng-2.1.2/zbuild.h | 248 + internal-complibs/zlib-ng-2.1.2/zconf-ng.h.in | 176 + internal-complibs/zlib-ng-2.1.2/zconf.h.in | 203 + internal-complibs/zlib-ng-2.1.2/zendian.h | 60 + internal-complibs/zlib-ng-2.1.2/zlib-ng.h.in | 1867 ++++ internal-complibs/zlib-ng-2.1.2/zlib-ng.map | 111 + internal-complibs/zlib-ng-2.1.2/zlib.h.in | 1855 ++++ internal-complibs/zlib-ng-2.1.2/zlib.map | 97 + .../zlib-ng-2.1.2/zlib.pc.cmakein | 14 + internal-complibs/zlib-ng-2.1.2/zlib.pc.in | 14 + .../zlib-ng-2.1.2/zlib_name_mangling-ng.h.in | 178 + .../zlib-ng-2.1.2/zlib_name_mangling.h.empty | 8 + .../zlib-ng-2.1.2/zlib_name_mangling.h.in | 170 + internal-complibs/zlib-ng-2.1.2/zutil.c | 159 + internal-complibs/zlib-ng-2.1.2/zutil.h | 148 + internal-complibs/zlib-ng-2.1.2/zutil_p.h | 71 + 935 files changed, 269717 insertions(+) create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.codecov.yaml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.shellcheckrc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/FAQ.zlib create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/INDEX.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/LICENSE.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/PORTING.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/README.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/adler32.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/adler32_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/adler32_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/chunkset_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/compare256_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/crc32_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/insert_string_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/neon_intrins.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/slide_hash_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/chunk_permute_table.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/chunkset_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/compare256_power9.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_constants.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_ppc_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/README.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/crc32-vx.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_detail.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.Dockerfile create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.service create mode 100755 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner create mode 100755 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/qemu-user-static.service create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_vnni.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_vpclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_vpclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/insert_string_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/chunkset.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/chunkset_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-coverage.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-install-dirs.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-intrinsics.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-sanitizer.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/fallback-macros.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-aarch64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-arm.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-armhf.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-i686.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-x86_64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64le.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-s390x.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-sparc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/compare256.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/compress.c create mode 100755 internal-complibs/zlib-ng-2.1.0-beta1/configure create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_fast.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_huff.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_medium.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_quick.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_rle.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_slow.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/deflate_stored.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/algorithm.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/crc-doc.1.0.pdf create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/crc-pclmulqdq.pdf create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1950.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1951.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1952.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/doc/txtvsbin.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/functable.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/functable.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/gzguts.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/gzlib.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/gzread.c.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/gzwrite.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/infback.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inffast_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inffixed_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inftrees.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/inftrees.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/insert_string.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/insert_string_roll.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/insert_string_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/match_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/slide_hash.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2002-0059/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2004-0797/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-1849/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-2096/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2018-25032/default.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2018-25032/fixed.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/GH-361/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/GH-364/test.bin create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/GH-382/defneg3.dat create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/GH-751/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/GH-979/pigz-2.6.tar.gz create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/README.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/ignore create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.md create mode 100755 internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/main.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/README.md create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_decode.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_encode.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_slidehash.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/compress-and-verify.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-compare.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-redirect.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-cves.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-data.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-issues.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-tools.cmake create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/data/fireworks.jpg create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/data/lcet10.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/data/paper-100k.pdf create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/example.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_checksum.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_compress.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_dict.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_flush.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_large.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_small.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/standalone_fuzz_target_runner.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/gh1235.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/infcover.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/minideflate.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/pigz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/pkgcheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/switchlevels.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_aligned_alloc.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_dual.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_cve-2003-0107.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_concurrency.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_hash_head_0.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_header.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_params.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_pending.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_prime.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_bi_valid.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_block_open.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_tune.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_gzio.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_sync.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_large_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_raw.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared_ng.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_window.cc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/test/test_version.cc create mode 100755 internal-complibs/zlib-ng-2.1.0-beta1/tools/config.sub create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/tools/makecrct.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/tools/makefixed.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/tools/maketrees.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/trees.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/trees.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/trees_emit.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/trees_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/uncompr.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.a64 create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.arm create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.msc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/replace.vbs create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng.def.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng1.rc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib.def.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib1.rc create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/win32/zlibcompat.def.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zbuild.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zconf-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zconf.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zendian.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.map create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib.map create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.cmakein create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.empty create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.in create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zutil.c create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zutil.h create mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/zutil_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.codecov.yaml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.shellcheckrc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/FAQ.zlib create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/INDEX.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/LICENSE.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/PORTING.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/README.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/adler32.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/adler32_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/adler32_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/chunkset_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/compare256_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/crc32_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/insert_string_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/neon_intrins.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/slide_hash_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/chunk_permute_table.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/chunkset_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/compare256_power9.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_constants.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_ppc_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/README.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/README.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/crc32-vx.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_detail.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.Dockerfile create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.service create mode 100755 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner create mode 100755 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/qemu-user-static.service create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_vnni.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_vpclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_vpclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/insert_string_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/chunkset.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/chunkset_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-coverage.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-install-dirs.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-intrinsics.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-sanitizer.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/fallback-macros.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-aarch64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-arm.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-armhf.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-i686.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-x86_64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64le.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-riscv.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-s390x.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-sparc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/compare256.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/compare256_rle.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/compress.c create mode 100755 internal-complibs/zlib-ng-2.1.1-beta2/configure create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_fast.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_huff.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_medium.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_quick.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_rle.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_slow.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/deflate_stored.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/algorithm.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/crc-doc.1.0.pdf create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/crc-pclmulqdq.pdf create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1950.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1951.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1952.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/doc/txtvsbin.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/functable.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/functable.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/gzguts.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/gzlib.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/gzread.c.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/gzwrite.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/infback.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inffast_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inffixed_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inftrees.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/inftrees.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/insert_string.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/insert_string_roll.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/insert_string_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/match_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/slide_hash.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2002-0059/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2004-0797/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-1849/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-2096/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2018-25032/default.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2018-25032/fixed.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/GH-361/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/GH-364/test.bin create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/GH-382/defneg3.dat create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/GH-751/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/GH-979/pigz-2.6.tar.gz create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/README.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/ignore create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.md create mode 100755 internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/main.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/README.md create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256_rle.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_decode.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_encode.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_slidehash.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/compress-and-verify.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-compare.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-redirect.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-cves.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-data.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-issues.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-tools.cmake create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/data/fireworks.jpg create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/data/lcet10.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/data/paper-100k.pdf create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/example.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_checksum.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_compress.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_dict.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_flush.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_large.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_small.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/standalone_fuzz_target_runner.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/gh1235.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/infcover.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/minideflate.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/pigz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/pkgcheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/switchlevels.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_aligned_alloc.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256_rle.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_dual.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_cve-2003-0107.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_concurrency.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_hash_head_0.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_header.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_params.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_pending.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_prime.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_bi_valid.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_block_open.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_tune.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_gzio.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_sync.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_large_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_raw.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared_ng.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_window.cc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/test/test_version.cc create mode 100755 internal-complibs/zlib-ng-2.1.1-beta2/tools/config.sub create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/tools/makecrct.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/tools/makefixed.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/tools/maketrees.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/trees.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/trees.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/trees_emit.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/trees_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/uncompr.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.a64 create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.arm create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.msc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/replace.vbs create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng.def.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng1.rc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib.def.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib1.rc create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/win32/zlibcompat.def.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zbuild.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zconf-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zconf.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zendian.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.map create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib.map create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.cmakein create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.empty create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.in create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zutil.c create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zutil.h create mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/zutil_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/.codecov.yaml create mode 100644 internal-complibs/zlib-ng-2.1.2/.gitattributes create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml create mode 100644 internal-complibs/zlib-ng-2.1.2/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.2/.shellcheckrc create mode 100644 internal-complibs/zlib-ng-2.1.2/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/FAQ.zlib create mode 100644 internal-complibs/zlib-ng-2.1.2/INDEX.md create mode 100644 internal-complibs/zlib-ng-2.1.2/LICENSE.md create mode 100644 internal-complibs/zlib-ng-2.1.2/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/PORTING.md create mode 100644 internal-complibs/zlib-ng-2.1.2/README.md create mode 100644 internal-complibs/zlib-ng-2.1.2/adler32.c create mode 100644 internal-complibs/zlib-ng-2.1.2/adler32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.2/adler32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.2/adler32_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/adler32_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/chunkset_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/compare256_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/crc32_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/insert_string_acle.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/neon_intrins.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/arm/slide_hash_neon.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/generic/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/generic/chunk_permute_table.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/adler32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/adler32_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/chunkset_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/compare256_power9.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/crc32_constants.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/crc32_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/power_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/power_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_power8.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_vmx.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/power/slide_ppc_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/riscv/README.md create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/README.md create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/crc32-vx.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_detail.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.Dockerfile create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.service create mode 100755 internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner create mode 100755 internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/qemu-user-static.service create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_vnni.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_ssse3.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_vpclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_vpclmulqdq.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/insert_string_sse42.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_avx2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_sse2.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/chunkset.c create mode 100644 internal-complibs/zlib-ng-2.1.2/chunkset_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.c create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-coverage.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-install-dirs.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-intrinsics.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/detect-sanitizer.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/fallback-macros.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-aarch64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-arm.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-armhf.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-i686.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-x86_64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64le.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-riscv.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-s390x.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/cmake/toolchain-sparc64.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/compare256.c create mode 100644 internal-complibs/zlib-ng-2.1.2/compare256_rle.h create mode 100644 internal-complibs/zlib-ng-2.1.2/compress.c create mode 100755 internal-complibs/zlib-ng-2.1.2/configure create mode 100644 internal-complibs/zlib-ng-2.1.2/cpu_features.c create mode 100644 internal-complibs/zlib-ng-2.1.2/cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_braid.c create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_braid_comb.c create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_braid_comb_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_braid_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_braid_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_fold.c create mode 100644 internal-complibs/zlib-ng-2.1.2/crc32_fold.h create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate.h create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_fast.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_huff.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_medium.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_quick.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_rle.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_slow.c create mode 100644 internal-complibs/zlib-ng-2.1.2/deflate_stored.c create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/algorithm.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/crc-doc.1.0.pdf create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/crc-pclmulqdq.pdf create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/rfc1950.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/rfc1951.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/rfc1952.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/doc/txtvsbin.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/fallback_builtins.h create mode 100644 internal-complibs/zlib-ng-2.1.2/functable.c create mode 100644 internal-complibs/zlib-ng-2.1.2/functable.h create mode 100644 internal-complibs/zlib-ng-2.1.2/gzguts.h create mode 100644 internal-complibs/zlib-ng-2.1.2/gzlib.c create mode 100644 internal-complibs/zlib-ng-2.1.2/gzread.c.in create mode 100644 internal-complibs/zlib-ng-2.1.2/gzwrite.c create mode 100644 internal-complibs/zlib-ng-2.1.2/infback.c create mode 100644 internal-complibs/zlib-ng-2.1.2/inffast_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/inffixed_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/inflate.c create mode 100644 internal-complibs/zlib-ng-2.1.2/inflate.h create mode 100644 internal-complibs/zlib-ng-2.1.2/inflate_p.h create mode 100644 internal-complibs/zlib-ng-2.1.2/inftrees.c create mode 100644 internal-complibs/zlib-ng-2.1.2/inftrees.h create mode 100644 internal-complibs/zlib-ng-2.1.2/insert_string.c create mode 100644 internal-complibs/zlib-ng-2.1.2/insert_string_roll.c create mode 100644 internal-complibs/zlib-ng-2.1.2/insert_string_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/match_tpl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/slide_hash.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/.gitignore create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2002-0059/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2004-0797/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2005-1849/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2005-2096/test.gz create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2018-25032/default.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/CVE-2018-25032/fixed.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/GH-361/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/GH-364/test.bin create mode 100644 internal-complibs/zlib-ng-2.1.2/test/GH-382/defneg3.dat create mode 100644 internal-complibs/zlib-ng-2.1.2/test/GH-751/test.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/GH-979/pigz-2.6.tar.gz create mode 100644 internal-complibs/zlib-ng-2.1.2/test/Makefile.in create mode 100644 internal-complibs/zlib-ng-2.1.2/test/README.md create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/ignore create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips64-unknown-linux-gnuabi64.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips64-unknown-linux-gnuabi64.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi create mode 100644 internal-complibs/zlib-ng-2.1.2/test/abicheck.md create mode 100755 internal-complibs/zlib-ng-2.1.2/test/abicheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/main.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/README.md create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256_rle.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_decode.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_encode.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_slidehash.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/compress-and-verify.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-compare.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-redirect.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/test-cves.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/test-data.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/test-issues.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/cmake/test-tools.cmake create mode 100644 internal-complibs/zlib-ng-2.1.2/test/data/fireworks.jpg create mode 100644 internal-complibs/zlib-ng-2.1.2/test/data/lcet10.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/data/paper-100k.pdf create mode 100644 internal-complibs/zlib-ng-2.1.2/test/example.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_checksum.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_compress.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_dict.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_flush.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_large.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_small.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/fuzz/standalone_fuzz_target_runner.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/gh1235.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/infcover.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/minideflate.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/minigzip.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/pigz/CMakeLists.txt create mode 100644 internal-complibs/zlib-ng-2.1.2/test/pkgcheck.sh create mode 100644 internal-complibs/zlib-ng-2.1.2/test/switchlevels.c create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_aligned_alloc.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_compare256.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_compare256_rle.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_compress.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_compress_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_compress_dual.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_cpu_features.h create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_crc32.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_cve-2003-0107.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_bound.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_concurrency.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_copy.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_hash_head_0.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_header.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_params.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_pending.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_prime.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_bi_valid.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_block_open.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_deflate_tune.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_dict.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_gzio.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_inflate_adler32.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_inflate_sync.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_large_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_main.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_raw.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_shared.h create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_shared_ng.h create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_small_buffers.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_small_window.cc create mode 100644 internal-complibs/zlib-ng-2.1.2/test/test_version.cc create mode 100755 internal-complibs/zlib-ng-2.1.2/tools/config.sub create mode 100644 internal-complibs/zlib-ng-2.1.2/tools/makecrct.c create mode 100644 internal-complibs/zlib-ng-2.1.2/tools/makefixed.c create mode 100644 internal-complibs/zlib-ng-2.1.2/tools/maketrees.c create mode 100644 internal-complibs/zlib-ng-2.1.2/trees.c create mode 100644 internal-complibs/zlib-ng-2.1.2/trees.h create mode 100644 internal-complibs/zlib-ng-2.1.2/trees_emit.h create mode 100644 internal-complibs/zlib-ng-2.1.2/trees_tbl.h create mode 100644 internal-complibs/zlib-ng-2.1.2/uncompr.c create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/Makefile.a64 create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/Makefile.arm create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/Makefile.msc create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/replace.vbs create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/zlib-ng.def.in create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/zlib-ng1.rc create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/zlib.def.in create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/zlib1.rc create mode 100644 internal-complibs/zlib-ng-2.1.2/win32/zlibcompat.def.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zbuild.h create mode 100644 internal-complibs/zlib-ng-2.1.2/zconf-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zconf.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zendian.h create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib-ng.map create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib.map create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib.pc.cmakein create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib.pc.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib_name_mangling-ng.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.empty create mode 100644 internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.in create mode 100644 internal-complibs/zlib-ng-2.1.2/zutil.c create mode 100644 internal-complibs/zlib-ng-2.1.2/zutil.h create mode 100644 internal-complibs/zlib-ng-2.1.2/zutil_p.h diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.codecov.yaml b/internal-complibs/zlib-ng-2.1.0-beta1/.codecov.yaml new file mode 100644 index 000000000..fc17c66a9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.codecov.yaml @@ -0,0 +1,27 @@ +codecov: + max_report_age: off + notify: + wait_for_ci: false + require_ci_to_pass: false +comment: + require_base: false + require_head: false +coverage: + status: + project: + default: + threshold: 0.07 +fixes: +- '/home/actions-runner/_work/zlib-ng/zlib-ng::' +- '/home/actions-runner/_work/zlib-ng/zlib-ng/build/::' +ignore: +- usr/include/.* +- /usr/include/.* +- /build/usr/include/.* +- usr/lib/.* +- /usr/lib/.* +- /build/usr/lib/.* +- usr/lib64/.* +- /usr/lib64/.* +- /build/usr/lib64/.* +- _deps/**/* diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes b/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes new file mode 100644 index 000000000..ac21ec459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes @@ -0,0 +1,8 @@ +* text=auto +*.abi text eol=lf +*.c text +*.h text +*.sh text eol=lf +crc32_braid_tbl.h hooks-max-size=1000000 +Makefile text +configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml new file mode 100644 index 000000000..7cd812915 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml @@ -0,0 +1 @@ +github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml new file mode 100644 index 000000000..cbdea0e50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml @@ -0,0 +1,78 @@ +name: Static Analysis +on: [push, pull_request] +jobs: + static-analysis: + name: GCC + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y gcc-10 + + - name: Generate project files + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CC: gcc-10 + CFLAGS: + -fanalyzer + -Werror + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-malloc-leak + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-tainted-array-index + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release > /dev/null + + Clang: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y clang-tools + + - name: Generate project files + run: | + scan-build --status-bugs \ + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CI: true + + - name: Compile source code + run: | + scan-build --status-bugs \ + cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml new file mode 100644 index 000000000..d50a2dcfa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml @@ -0,0 +1,609 @@ +name: CMake +on: [push, pull_request] +env: + TERM: xterm-256color + GTEST_COLOR: 1 +jobs: + cmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SANITIZER=Address + codecov: ubuntu_gcc + + - name: Ubuntu GCC Benchmark + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_BENCHMARKS=ON + codecov: ubuntu_gcc_benchmark + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_sprefix + + - name: Ubuntu GCC Compat Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_compat_sprefix + + - name: Ubuntu GCC -O3 OSB + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng + codecov: ubuntu_gcc_osb + cflags: -O3 + + - name: Ubuntu GCC -O3 OSB add_subdirectory + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng/test/add-subdirectory-project + + - name: Ubuntu GCC -O1 No Unaligned UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_o1 + cflags: -O1 + + - name: Ubuntu GCC 32-bit + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 + packages: gcc-multilib g++-multilib + codecov: ubuntu_gcc_m32 + + - name: Ubuntu GCC No CTZLL + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF + codecov: ubuntu_gcc_no_ctzll + + - name: Ubuntu GCC No CTZ + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF + codecov: ubuntu_gcc_no_ctz + + - name: Ubuntu GCC No AVX2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_avx2 + + - name: Ubuntu GCC No SSE2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse2 + + - name: Ubuntu GCC No SSE4.2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse42 + + - name: Ubuntu GCC No PCLMULQDQ UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_pclmulqdq + + - name: Ubuntu GCC Compat No Opt ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address + codecov: ubuntu_gcc_compat_no_opt + cflags: -DNOT_TWEAK_COMPILER + + - name: Ubuntu GCC ARM SF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf + + - name: Ubuntu GCC ARM SF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf_compat_no_opt + + - name: Ubuntu GCC ARM HF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf + + - name: Ubuntu GCC ARM HF No ACLE ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_acle + + - name: Ubuntu GCC ARM HF No NEON ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_neon + + - name: Ubuntu GCC ARM HF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_compat_no_opt + + - name: Ubuntu GCC AARCH64 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64 + + - name: Ubuntu GCC AARCH64 No ACLE UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_acle + + - name: Ubuntu GCC AARCH64 No NEON UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_neon + + - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_compat_no_opt + + - name: Ubuntu GCC PPC + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc_no_power8 + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake + packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross + ldflags: -static + codecov: ubuntu_gcc_ppc64 + + - name: Ubuntu GCC PPC64LE + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross + codecov: ubuntu_gcc_ppc64le + + - name: Ubuntu GCC SPARC64 + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake + packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross + ldflags: -static + codecov: ubuntu_gcc_sparc64 + + - name: Ubuntu GCC S390X ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X No vectorized CRC32 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x_no_crc32 + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC ASAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC Compat UBSAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc_compat + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu Clang S390X DFLTCC MSAN + os: z15 + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu MinGW i686 + os: ubuntu-22.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake + packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 + ldflags: -static + codecov: ubuntu_gcc_mingw_i686 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu MinGW x86_64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake + packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 + ldflags: -static + codecov: ubuntu_gcc_mingw_x86_64 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu 20.04 Clang + os: ubuntu-20.04 + compiler: clang-6.0 + cxx-compiler: clang++-6.0 + packages: clang-6.0 + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang + + # Check for undefined symbols in the version script for the modern api + - name: Ubuntu Clang Undefined Symbols + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF + build-shared: ON + packages: clang-11 llvm-11 lld + + # Check for undefined symbols in the version script for the compat api + - name: Ubuntu Clang Undefined Symbols Compat + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON + build-shared: ON + packages: clang-11 llvm-11 lld + + - name: Ubuntu Clang Inflate Strict + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_STRICT=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_strict + + - name: Ubuntu Clang Inflate Allow Invalid Dist + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_allow_invalid_dist + + - name: Ubuntu Clang Reduced Memory + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_REDUCED_MEM=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_reduced_mem + + - name: Ubuntu Clang Memory Map + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cflags: -DUSE_MMAP + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_mmap + + - name: Ubuntu Clang Debug + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_debug + build-config: Debug + + - name: Ubuntu Clang MSAN + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_SANITIZER=Memory + packages: ninja-build clang-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + # https://github.com/llvm/llvm-project/issues/55785 + msan-options: use_sigaltstack=0 + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON + + - name: Windows MSVC 2022 v143 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 + + - name: Windows MSVC 2022 v143 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 + + - name: Windows MSVC 2022 v142 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 + + - name: Windows MSVC 2022 v142 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 + + - name: Windows MSVC 2022 v141 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 + + - name: Windows MSVC 2022 v141 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 + + - name: Windows MSVC 2019 v140 Win32 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 + + - name: Windows MSVC 2019 v140 Win64 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 + + - name: Windows MSVC ARM No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM + + - name: Windows MSVC ARM64 No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + + - name: Windows ClangCl Win32 + os: windows-latest + cmake-args: -T ClangCl -A Win32 + + - name: Windows ClangCl Win64 + os: windows-latest + cmake-args: -T ClangCl -A x64 + + - name: Windows GCC + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja + codecov: win64_gcc + + - name: Windows GCC Compat No Opt + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF + codecov: win64_gcc_compat_no_opt + + - name: macOS Clang ASAN + os: macos-latest + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_SANITIZER=Address + codecov: macos_clang + + - name: macOS GCC UBSAN + os: macos-latest + compiler: gcc-10 + cxx-compiler: g++-10 + cmake-args: -DWITH_SANITIZER=Undefined + packages: gcc@10 + gcov-exec: gcov-10 + codecov: macos_gcc + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs + # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. + if: contains(matrix.name, 'MinGW') == false + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add repositories (Wine) + if: contains(matrix.packages, 'wine32') + run: sudo dpkg --add-architecture i386 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} + + - name: Install packages (Windows) + if: runner.os == 'Windows' + run: | + # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. + # zlib-ng does not need perl, so simply remove it. + choco uninstall --no-progress strawberryperl + choco install --no-progress ninja ${{ matrix.packages }} + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Initialize Wine + # Prevent parallel test jobs from initializing Wine at the same time + if: contains(matrix.packages, 'wine') + run: wineboot --init + + - name: Compile LLVM C++ libraries (MSAN) + if: contains(matrix.name, 'MSAN') + run: | + git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 + cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ + -DLLVM_USE_SANITIZER=MemoryWithOrigins \ + -DLLVM_LIBC_ENABLE_LINTING=OFF + cmake --build llvm-project/build -j2 -- cxx cxxabi + echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + + - name: Generate project files + shell: bash + # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources + run: | + cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ + -DWITH_FUZZERS=ON \ + -DWITH_MAINTAINER_WARNINGS=ON \ + ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} + + - name: Run test cases + # Don't run tests on Windows ARM + if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: ${{ matrix.build-dir || '.' }} + env: + ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 + + - name: Generate coverage report + if: matrix.codecov + shell: bash + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root ${{ matrix.build-src-dir || '.' }} \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + directory: ${{ matrix.build-src-dir || '.' }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml new file mode 100644 index 000000000..1cfa4d7fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + schedule: + - cron: "27 17 * * 0" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ cpp ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml new file mode 100644 index 000000000..51861533e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml @@ -0,0 +1,238 @@ +name: Configure +on: [push, pull_request] +jobs: + configure: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + configure-args: --warn + + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + configure-args: --warn + + - name: Ubuntu GCC OSB + os: ubuntu-latest + compiler: gcc + configure-args: --warn + build-dir: ../build + build-src-dir: ../zlib-ng + + - name: Ubuntu GCC Compat No Opt + os: ubuntu-latest + compiler: gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + + - name: Ubuntu GCC ARM SF + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM SF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No ACLE + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-acle + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No NEON + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-neon + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No ACLE + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-acle + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No NEON + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-neon + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 Compat No Opt + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --without-power8 + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + compiler: powerpc64-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + compiler: powerpc64le-linux-gnu-gcc + configure-args: --warn + chost: powerpc64le-linux-gnu + packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross + + - name: Ubuntu GCC S390X + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X No vectorized CRC32 + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static --without-crc32-vx + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X DFLTCC + os: z15 + compiler: gcc + configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu GCC S390X DFLTCC Compat + os: z15 + compiler: gcc + configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + configure-args: --warn --zlib-compat --static + configure-prefix: emconfigure + cflags: -static + ldflags: -static + emu-run: node + + - name: macOS GCC Symbol Prefix + os: macOS-latest + compiler: gcc-11 + configure-args: --sprefix=zTest_ + + - name: macOS GCC Symbol Prefix & Compat + os: macOS-latest + compiler: gcc-11 + configure-args: --zlib-compat --sprefix=zTest_ + + - name: macOS GCC + os: macOS-latest + compiler: gcc-11 + configure-args: --warn + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Generate project files + run: | + mkdir ${{ matrix.build-dir || '.not-used' }} + cd ${{ matrix.build-dir || '.' }} + ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CHOST: ${{ matrix.chost }} + EMU_RUN: ${{ matrix.emu-run }} + CI: true + + - name: Compile source code + run: make -j2 + working-directory: ${{ matrix.build-dir }} + + - name: Run test cases + run: make test + working-directory: ${{ matrix.build-dir }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (configure) + path: | + **/Makefile + ${{ matrix.build-dir || '.' }}/configure.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml new file mode 100644 index 000000000..95d64e67a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml @@ -0,0 +1,36 @@ +name: OSS-Fuzz +on: + pull_request: + push: + branches: + - stable + - develop + - pre-release + - '2.*' + tags: + - '*' + +jobs: + fuzzing: + name: Fuzzing + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + dry-run: false + + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + fuzz-seconds: 600 + dry-run: false + + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() + with: + name: artifacts + path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml new file mode 100644 index 000000000..c5fea574f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml @@ -0,0 +1,51 @@ +name: Libpng +on: [push, pull_request] +jobs: + libpng: + name: Ubuntu Clang + runs-on: ubuntu-latest + steps: + - name: Checkout repository (zlib-ng) + uses: actions/checkout@v3 + + - name: Generate project files (zlib-ng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_COMPAT=ON \ + -DZLIB_ENABLE_TESTS=OFF + env: + CC: clang + CFLAGS: -fPIC + CI: true + + - name: Compile source code (zlib-ng) + run: cmake --build . -j2 --config Release + + - name: Checkout repository (libpng) + uses: actions/checkout@v3 + with: + repository: glennrp/libpng + path: libpng + + - name: Generate project files (libpng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DPNG_TESTS=ON \ + -DPNG_STATIC=OFF \ + -DZLIB_INCLUDE_DIR=.. \ + -DZLIB_LIBRARY=$PWD/../libz.a + working-directory: libpng + env: + CC: clang + CI: true + + - name: Compile source code (libpng) + run: cmake --build . -j2 --config Release + working-directory: libpng + + - name: Run test cases (libpng) + run: ctest -j2 -C Release --output-on-failure --max-width 120 + working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml new file mode 100644 index 000000000..5de669840 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml @@ -0,0 +1,66 @@ +name: Link +on: [push, pull_request] +jobs: + zlib: + name: Link zlib + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout zlib repository + uses: actions/checkout@v3 + with: + repository: madler/zlib + path: zlib + + - name: Generate project files (zlib) + run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF + + - name: Compile source code (zlib) + run: cmake --build zlib/build -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 + + zlib-ng-compat: + name: Link zlib-ng compat + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Generate project files (compat) + run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON + + - name: Compile source code (compat) + run: cmake --build compat -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib-ng compat (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml new file mode 100644 index 000000000..38e669093 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml @@ -0,0 +1,68 @@ +name: NMake +on: [push, pull_request] +jobs: + nmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows NMake x86 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86 + + - name: Windows NMake x64 compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes + + - name: Windows NMake x64 Symbol Prefix + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 Symbol Prefix Compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + + - name: Windows NMake ARM No Test + os: windows-2022 + makefile: win32/Makefile.arm + arch: x86_arm + + - name: Windows NMake ARM64 No Test + os: windows-2022 + makefile: win32/Makefile.a64 + arch: x86_arm64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup development environment + uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + + - name: Compile source code + shell: cmd + run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} + + - name: Run test cases + shell: cmd + # Don't run tests on Windows ARM + if: contains(matrix.arch, 'arm') == false + run: | + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml new file mode 100644 index 000000000..be4e1ce50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml @@ -0,0 +1,131 @@ +name: Pigz +on: [push, pull_request] +jobs: + pigz: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz + + - name: Ubuntu Clang No Optim + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_optim + cmake-args: -DWITH_OPTIM=OFF + + # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 + - name: Ubuntu Clang No Threads + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_threads + cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_pigz_aarch64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Generate project files + run: | + cmake ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_ROOT=../.. \ + -DWITH_CODE_COVERAGE=ON \ + -DWITH_MAINTAINER_WARNINGS=ON + working-directory: test/pigz + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} + working-directory: test/pigz + + - name: Run test cases + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: test/pigz + + - name: Generate coverage report + if: matrix.codecov + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root . \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml new file mode 100644 index 000000000..8888cf37e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml @@ -0,0 +1,176 @@ +name: Package Check +on: [push, pull_request] +jobs: + pkgcheck: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC -m32 + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + packages: gcc-multilib g++-multilib + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 + cflags: -m32 + cxxflags: -m32 + ldflags: -m32 + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + chost: arm-linux-gnueabihf + compiler: arm-linux-gnueabihf-gcc + cxx-compiler: g++-arm-linux-gnueabihf + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake + packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + chost: aarch64-linux-gnu + compiler: aarch64-linux-gnu-gcc + cxx-compiler: g++-aarch64-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake + packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + chost: powerpc-linux-gnu + compiler: powerpc-linux-gnu-gcc + cxx-compiler: g++-powerpc-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + chost: powerpc64le-linux-gnu + compiler: powerpc64le-linux-gnu-gcc + cxx-compiler: g++-powerpc64le-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross + + - name: macOS Clang + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + + - name: macOS Clang Native + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON + configure-args: --native + + - name: macOS Clang Symbol Prefix + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + configure-args: --sprefix=zTest_ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ + abigail-tools \ + diffoscope \ + ninja-build + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja diffoscope ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Select Xcode version (macOS) + # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports + # AppleClang linking with libtool using -D argument + # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 + if: runner.os == 'macOS' + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '11.7.0' + + - name: Compare builds + run: sh test/pkgcheck.sh + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Compare builds (compat) + run: sh test/pkgcheck.sh --zlib-compat + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI (compat) + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --zlib-compat --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} + path: | + **/*.abi + btmp1/configure.log + btmp1/CMakeFiles/CMakeOutput.log + btmp1/CMakeFiles/CMakeError.log + btmp2/configure.log + btmp2/CMakeFiles/CMakeOutput.log + btmp2/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml new file mode 100644 index 000000000..b64933cc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release +on: + push: + tags: + - '*' +jobs: + release: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows MSVC Win32 + os: windows-latest + compiler: cl + cmake-args: -A Win32 + deploy-name: win-x86 + + - name: Windows MSVC Win32 Compat + os: windows-latest + compiler: cl + cmake-args: -A Win32 -DZLIB_COMPAT=ON + deploy-name: win-x86-compat + + - name: Windows MSVC Win64 + os: windows-latest + compiler: cl + cmake-args: -A x64 + deploy-name: win-x86-64 + + - name: Windows MSVC Win64 Compat + os: windows-latest + compiler: cl + cmake-args: -A x64 -DZLIB_COMPAT=ON + deploy-name: win-x86-64-compat + + - name: Windows MSVC ARM + os: windows-latest + compiler: cl + cmake-args: -A ARM + deploy-name: win-arm + + - name: Windows MSVC ARM Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM -DZLIB_COMPAT=ON + deploy-name: win-arm-compat + + - name: Windows MSVC ARM64 + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + deploy-name: win-arm64 + + - name: Windows MSVC ARM64 Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM64 -DZLIB_COMPAT=ON + deploy-name: win-arm64-compat + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set environment variables + shell: bash + run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + + - name: Generate project files + shell: bash + run: | + cmake . ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DZLIB_ENABLE_TESTS=ON \ + -DCMAKE_INSTALL_PREFIX=out \ + -DINSTALL_UTILS=ON + env: + CC: ${{ matrix.compiler }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release --target install + + - name: Package release (Windows) + if: runner.os == 'Windows' + run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md + working-directory: out + + - name: Upload release (Windows) + uses: svenstaro/upload-release-action@v2 + if: runner.os == 'Windows' + with: + asset_name: zlib-ng-${{ matrix.deploy-name }}.zip + file: zlib-ng-${{ matrix.deploy-name }}.zip + tag: ${{env.tag}} + repo_token: ${{ secrets.GITHUB_TOKEN }} + overwrite: true + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore b/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore new file mode 100644 index 000000000..cd4a9c3fe --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore @@ -0,0 +1,97 @@ +*.diff +*.patch +*.orig +*.rej + +*~ +*.a +*.lo +*.o +*.dylib + +*.gcda +*.gcno +*.gcov + +/benchmark_zlib +/example +/example64 +/examplesh +/gtest_zlib +/libz.so* +/libz-ng.so* +/makefixed +/minigzip +/minigzip64 +/minigzipsh +/switchlevels +/zlib.pc +/zlib-ng.pc + +.DS_Store +*_fuzzer +*.obj +*.exe +*.pdb +*.exp +*.lib +*.dll +*.res +foo.gz +*.manifest +*.opensdf +*.sln +*.sdf +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +.vs + +CMakeCache.txt +CMakeFiles +Testing +/*.cmake +*.stackdump +*._h +zconf.h +zconf.h.cmakein +zconf.h.included +zconf-ng.h +zconf-ng.h.cmakein +ztest* +/test/CTestTestfile.cmake +/test/cmake_install.cmake + +configure.log +a.out + +/Makefile +/arch/arm/Makefile +/arch/generic/Makefile +/arch/power/Makefile +/arch/x86/Makefile +.kdev4 +*.kdev4 + +/Debug +/example.dir +/minigzip.dir +/zlib.dir +/zlibstatic.dir +/test/*.dir/ +/build/ +/build[.-]*/ +/btmp[12]/ +/pkgtmp[12]/ + +/.idea +/cmake-build-debug +/x64/Debug/ +/x64/Release/ +/win32/Debug/ +/win32/Release/ +/ARM*/Debug/ +/ARM*/Release/ +MinSizeRel +RelWithDebInfo +/_deps/googletest* diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.shellcheckrc b/internal-complibs/zlib-ng-2.1.0-beta1/.shellcheckrc new file mode 100644 index 000000000..89a1625ff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2140,SC2086,SC2046,SC2015,SC1097,SC1035,SC1036,SC1007,SC2154,SC2155,SC2000,SC2034,SC2016,SC1091,SC1090,SC2212,SC2143,SC2129,SC2102,SC2069,SC1041,SC1042,SC1044,SC1046,SC1119,SC1110,SC1111,SC1112,SC1102,SC1105,SC1101,SC1004,SC1003,SC1012,SC2068,SC2065,SC2064,SC2063,SC2059,SC2053,SC2048,SC2044,SC2032,SC2031,SC2030,SC2029,SC2025,SC2024,SC2022,SC2018,SC2019,SC2017,SC2014,SC2013,SC2012,SC2009,SC2001,SC2098,SC2096,SC2094,SC2091,SC2092,SC2088,SC2087,SC2076,SC2072,SC2071,SC2223,SC2221,SC2222,SC2217,SC2207,SC2206,SC2205,SC2190,SC2188,SC2187,SC2185,SC2179,SC2178,SC2174,SC2168,SC2167,SC2163,SC2161,SC2160,SC2153,SC2150,SC2148,SC2147,SC2146,SC2142,SC2139,SC2126,SC2123,SC2120,SC2119,SC2117,SC2114,SC1117,SC2164,SC1083,SC2004,SC2125,SC2128,SC2011,SC1008,SC1019,SC2093,SC1132,SC1129,SC2236,SC2237,SC2231,SC2230,SC2229,SC2106,SC2102,SC2243,SC2244,SC2245,SC2247,SC2248,SC2249,SC2250,SC2251,SC2252,SC2181 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/CMakeLists.txt new file mode 100644 index 000000000..6fc12f5bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/CMakeLists.txt @@ -0,0 +1,1250 @@ +cmake_minimum_required(VERSION 3.5.1) +if(CMAKE_VERSION VERSION_LESS 3.12) + cmake_policy(VERSION ${CMAKE_VERSION}) +else() + cmake_policy(VERSION 3.5.1...3.13.2) +endif() +message(STATUS "Using CMake version ${CMAKE_VERSION}") + +set(CMAKE_MACOSX_RPATH 1) + +# If not specified on the command line, enable C11 as the default +# Configuration items that affect the global compiler environment standards +# should be issued before the "project" command. +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) # The C standard whose features are requested to build this target +endif() +if(NOT CMAKE_C_STANDARD_REQUIRED) + set(CMAKE_C_STANDARD_REQUIRED ON) # Boolean describing whether the value of C_STANDARD is a requirement +endif() +if(NOT CMAKE_C_EXTENSIONS) + set(CMAKE_C_EXTENSIONS OFF) # Boolean specifying whether compiler specific extensions are requested +endif() +set(VALID_C_STANDARDS "99" "11") +if(NOT CMAKE_C_STANDARD IN_LIST VALID_C_STANDARDS) + MESSAGE(FATAL_ERROR "CMAKE_C_STANDARD:STRING=${CMAKE_C_STANDARD} not in known standards list\n ${VALID_C_STANDARDS}") +endif() + +# Parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9]+.[0-9]+.[0-9]+).*\".*" + "\\1" ZLIB_HEADER_VERSION ${_zlib_h_contents}) +string(REGEX REPLACE ".*#define[ \t]+ZLIBNG_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIBNG_HEADER_VERSION ${_zlib_h_contents}) +message(STATUS "ZLIB_HEADER_VERSION: ${ZLIB_HEADER_VERSION}") +message(STATUS "ZLIBNG_HEADER_VERSION: ${ZLIBNG_HEADER_VERSION}") + +project(zlib VERSION ${ZLIB_HEADER_VERSION} LANGUAGES C) + +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CheckCCompilerFlag) +include(CMakeDependentOption) +include(FeatureSummary) + +include(cmake/detect-arch.cmake) +include(cmake/detect-install-dirs.cmake) +include(cmake/detect-coverage.cmake) +include(cmake/detect-intrinsics.cmake) +include(cmake/detect-sanitizer.cmake) +include(cmake/fallback-macros.cmake) + +if(CMAKE_TOOLCHAIN_FILE) + message(STATUS "Using CMake toolchain: ${CMAKE_TOOLCHAIN_FILE}") +endif() + +# Make sure we use an appropriate BUILD_TYPE by default, "Release" to be exact +# this should select the maximum generic optimisation on the current platform (i.e. -O3 for gcc/clang) +if(NOT GENERATOR_IS_MULTI_CONFIG) + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, standard options are: Debug Release RelWithDebInfo MinSizeRel." + FORCE) + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (default)") + else() + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (selected)") + endif() +endif() + +# +# Options parsing +# +option(WITH_GZFILEOP "Compile with support for gzFile related functions" ON) +option(ZLIB_COMPAT "Compile with zlib compatible API" OFF) +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +option(ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API" ON) +option(WITH_GTEST "Build gtest_zlib" ON) +option(WITH_FUZZERS "Build test/fuzz" OFF) +option(WITH_BENCHMARKS "Build test/benchmarks" OFF) +option(WITH_BENCHMARK_APPS "Build application benchmarks" OFF) +option(WITH_OPTIM "Build with optimisation" ON) +option(WITH_REDUCED_MEM "Reduced memory usage for special cases (reduces performance)" OFF) +option(WITH_NEW_STRATEGIES "Use new strategies" ON) +option(WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)" OFF) +option(WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings" OFF) +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_INFLATE_STRICT "Build with strict inflate distance checking" OFF) +option(WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances" OFF) +option(WITH_UNALIGNED "Support unaligned reads on platforms that support it" ON) + +set(ZLIB_SYMBOL_PREFIX "" CACHE STRING "Give this prefix to all publicly exported symbols. +Useful when embedding into a larger library. +Default is no prefix (empty prefix).") + +# Add multi-choice option +set(WITH_SANITIZER AUTO CACHE STRING "Enable sanitizer support") +set_property(CACHE WITH_SANITIZER PROPERTY STRINGS "Memory" "Address" "Undefined" "Thread") + +if(BASEARCH_ARM_FOUND) + option(WITH_ACLE "Build with ACLE" ON) + option(WITH_NEON "Build with NEON intrinsics" ON) +elseif(BASEARCH_PPC_FOUND) + option(WITH_ALTIVEC "Build with AltiVec (VMX) optimisations for PowerPC" ON) + option(WITH_POWER8 "Build with optimisations for POWER8" ON) + option(WITH_POWER9 "Build with optimisations for POWER9" ON) +elseif(BASEARCH_S360_FOUND) + option(WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z" OFF) + option(WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z" OFF) + option(WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z" ON) +elseif(BASEARCH_X86_FOUND) + option(WITH_AVX2 "Build with AVX2" ON) + option(WITH_AVX512 "Build with AVX512" ON) + option(WITH_AVX512VNNI "Build with AVX512 VNNI extensions" ON) + option(WITH_SSE2 "Build with SSE2" ON) + option(WITH_SSSE3 "Build with SSSE3" ON) + option(WITH_SSE42 "Build with SSE42" ON) + option(WITH_PCLMULQDQ "Build with PCLMULQDQ" ON) + option(WITH_VPCLMULQDQ "Build with VPCLMULQDQ" ON) +endif() + +option(INSTALL_UTILS "Copy minigzip and minideflate during install" OFF) + +mark_as_advanced(FORCE + ZLIB_SYMBOL_PREFIX + WITH_REDUCED_MEM + WITH_ACLE WITH_NEON + WITH_DFLTCC_DEFLATE + WITH_DFLTCC_INFLATE + WITH_CRC32_VX + WITH_AVX2 WITH_SSE2 + WITH_SSSE3 WITH_SSE42 + WITH_PCLMULQDQ + WITH_ALTIVEC + WITH_POWER8 + WITH_POWER9 + WITH_INFLATE_STRICT + WITH_INFLATE_ALLOW_INVALID_DIST + WITH_UNALIGNED + INSTALL_UTILS + ) + +if(ZLIB_COMPAT) + add_definitions(-DZLIB_COMPAT) + set(WITH_GZFILEOP ON) + set(SUFFIX "") + set(ZLIB_FULL_VERSION ${ZLIB_HEADER_VERSION}.zlib-ng) +else() + set(SUFFIX "-ng") + set(ZLIB_FULL_VERSION ${ZLIBNG_HEADER_VERSION}) +endif() + +if(WITH_GZFILEOP) + add_definitions(-DWITH_GZFILEOP) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "^Intel") + if(CMAKE_HOST_UNIX) + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wall -Wcheck -Wremarks) + set(WARNFLAGS_DISABLE) + else() + set(WARNFLAGS /Wall) + set(WARNFLAGS_MAINTAINER /W5) + set(WARNFLAGS_DISABLE) + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(MSVC) + # Minimum supported MSVC version is 1800 = Visual Studio 12.0/2013 + # See also https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html + if(MSVC_VERSION VERSION_LESS 1800) + message(SEND_ERROR "Unsupported Visual Studio compiler version (requires 2013 or later).") + endif() + # TODO. ICC can be used through MSVC. I'm not sure if we'd ever see that combination + # (who'd use cmake from an IDE...) but checking for ICC before checking for MSVC should + # avoid mistakes. + # /Oi ? + set(WARNFLAGS /W3) + set(WARNFLAGS_MAINTAINER /W4) + set(WARNFLAGS_DISABLE) + if(BASEARCH_ARM_FOUND) + add_definitions(-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE) + if(NOT "${ARCH}" MATCHES "aarch64") + set(NEONFLAG "/arch:VFPv4") + endif() + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + # Enable warnings in GCC and Clang + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wextra) + set(WARNFLAGS_DISABLE) + if(WITH_NATIVE_INSTRUCTIONS) + if(BASEARCH_PPC_FOUND) + set(NATIVEFLAG "-mcpu=native") + else() + set(NATIVEFLAG "-march=native") + endif() + else() + if(BASEARCH_ARM_FOUND) + if("${ARCH}" MATCHES "arm" AND NOT CMAKE_C_FLAGS MATCHES "-mfloat-abi") + # Auto-detect support for ARM floating point ABI + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=softfp) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_SOFTFP) + if(HAVE_FLOATABI_SOFTFP) + set(FLOATABI -mfloat-abi=softfp) + else() + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=hard) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_HARD) + if(HAVE_FLOATABI_HARD) + set(FLOATABI -mfloat-abi=hard) + endif() + endif() + set(CMAKE_REQUIRED_FLAGS) + if(FLOATABI) + message(STATUS "ARM floating point arch: ${FLOATABI}") + add_compile_options(${FLOATABI}) + else() + message(STATUS "ARM floating point arch not auto-detected") + endif() + endif() + endif() + # Check whether -fno-lto is available + set(CMAKE_REQUIRED_FLAGS "-fno-lto") + check_c_source_compiles( + "int main() { return 0; }" + FNO_LTO_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) + if(FNO_LTO_AVAILABLE) + set(NOLTOFLAG "-fno-lto") + endif() + endif() + if(MINGW) + list(APPEND WARNFLAGS_DISABLE -Wno-pedantic-ms-format) + endif() +else() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not implemented yet on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +endif() + +# Disable LTO +if(NOT WITH_NATIVE_INSTRUCTIONS) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF) + foreach(_cfg_name IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER "${_cfg_name}" _cfg_name_uc) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${_cfg_name_uc} OFF) + endforeach() +endif() + +# Set architecture alignment requirements +if(NOT WITH_UNALIGNED) + add_definitions(-DNO_UNALIGNED) + message(STATUS "Unaligned reads manually disabled") +endif() + +# Apply warning compiler flags +if(WITH_MAINTAINER_WARNINGS) + add_compile_options(${WARNFLAGS} ${WARNFLAGS_MAINTAINER} ${WARNFLAGS_DISABLE}) +else() + add_compile_options(${WARNFLAGS} ${WARNFLAGS_DISABLE}) +endif() + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Replace optimization level 3 added by default with level 2 +if(NOT WITH_CODE_COVERAGE AND NOT MSVC AND NOT CMAKE_C_FLAGS MATCHES "([\\/\\-]O)3") + string(REGEX REPLACE "([\\/\\-]O)3" "\\12" + CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +endif() + +# Set native instruction set compiler flag +if(WITH_NATIVE_INSTRUCTIONS AND DEFINED NATIVEFLAG) + # Apply flag to all source files and compilation checks + add_compile_options(${NATIVEFLAG}) +endif() + +# +# Check for standard/system includes +# +check_include_file(sys/auxv.h HAVE_SYS_AUXV_H) +if(HAVE_SYS_AUXV_H) + add_definitions(-DHAVE_SYS_AUXV_H) +endif() +check_include_file(sys/sdt.h HAVE_SYS_SDT_H) +if(HAVE_SYS_SDT_H) + add_definitions(-DHAVE_SYS_SDT_H) +endif() +check_include_file(unistd.h HAVE_UNISTD_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +else() + check_type_size(_off64_t _OFF64_T) + if(HAVE__OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) + else() + check_type_size(__off64_t __OFF64_T) + endif() +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko and other optional functions +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +check_function_exists(strerror HAVE_STRERROR) +if(NOT HAVE_STRERROR) + add_definitions(-DNO_STRERROR) +endif() + +set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L) +check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) +if(HAVE_POSIX_MEMALIGN) + add_definitions(-DHAVE_POSIX_MEMALIGN) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +set(CMAKE_REQUIRED_DEFINITIONS -D_ISOC11_SOURCE=1) +check_symbol_exists(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) +if(HAVE_ALIGNED_ALLOC) + add_definitions(-DHAVE_ALIGNED_ALLOC) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +if(WITH_SANITIZER STREQUAL "Address") + add_address_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Memory") + add_memory_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Thread") + add_thread_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Undefined") + add_undefined_sanitizer() +endif() + +# +# Check whether compiler supports -fno-semantic-interposition parameter +# +check_c_compiler_flag(-fno-semantic-interposition HAVE_NO_INTERPOSITION) + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using hidden +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"hidden\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_HIDDEN FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_HIDDEN) + add_definitions(-DHAVE_VISIBILITY_HIDDEN) +endif() + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using internal +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"internal\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_INTERNAL FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_INTERNAL) + add_definitions(-DHAVE_VISIBILITY_INTERNAL) +endif() + +# +# Check for __attribute__((aligned(x))) support in the compiler +# +check_c_source_compiles( + "int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; + }" + HAVE_ATTRIBUTE_ALIGNED FAIL_REGEX "aligned") +if(HAVE_ATTRIBUTE_ALIGNED) + add_definitions(-DHAVE_ATTRIBUTE_ALIGNED) +endif() + +# +# check for _Thread_local() support in the compiler +# +check_c_source_compiles( + "_Thread_local int test; + int main(void) { + (void)test; + return 0; + }" + HAVE_THREAD_LOCAL +) +if(HAVE_THREAD_LOCAL) + add_definitions(-DHAVE_THREAD_LOCAL) +endif() + +# +# check for __builtin_ctz() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZ +) +if(HAVE_BUILTIN_CTZ) + add_definitions(-DHAVE_BUILTIN_CTZ) +endif() + +# +# check for __builtin_ctzll() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZLL +) +if(HAVE_BUILTIN_CTZLL) + add_definitions(-DHAVE_BUILTIN_CTZLL) +endif() + +# +# check for ptrdiff_t support +# +check_c_source_compiles( + "#include + int main() { + ptrdiff_t *a; + (void)a; + return 0; + }" + HAVE_PTRDIFF_T +) +if(NOT HAVE_PTRDIFF_T) + set(NEED_PTRDIFF_T 1) + + check_type_size("void *" SIZEOF_DATA_PTR) + message(STATUS "sizeof(void *) is ${SIZEOF_DATA_PTR} bytes") + + if(${SIZEOF_DATA_PTR} MATCHES "4") + set(PTRDIFF_TYPE "uint32_t") + elseif(${SIZEOF_DATA_PTR} MATCHES "8") + set(PTRDIFF_TYPE "uint64_t") + else() + message(FATAL_ERROR "sizeof(void *) is neither 32 nor 64 bit") + endif() +endif() + +# Macro to check if source compiles +# (and, when compiling very natively, also runs). +macro(check_c_source_compile_or_run source flag) + if(CMAKE_CROSSCOMPILING OR NOT WITH_NATIVE_INSTRUCTIONS) + check_c_source_compiles("${source}" ${flag}) + else() + check_c_source_runs("${source}" ${flag}) + endif() +endmacro() + +add_compile_options($<$:-DZLIB_DEBUG>) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +endif() + +if(BASEARCH_X86_FOUND) + # FORCE_SSE2 option will only be shown if HAVE_SSE2_INTRIN is true + if("${ARCH}" MATCHES "i[3-6]86") + cmake_dependent_option(FORCE_SSE2 "Always assume CPU is SSE2 capable" OFF "HAVE_SSE2_INTRIN" OFF) + endif() +endif() + +# +# Enable deflate_quick at level 1 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_QUICK_STRATEGY) +endif() +# +# Enable deflate_medium at level 4-6 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_MEDIUM_STRATEGY) +endif() +# +# Enable inflate compilation options +# +if(WITH_INFLATE_STRICT) + add_definitions(-DINFLATE_STRICT) + message(STATUS "Inflate strict distance checking enabled") +endif() +if(WITH_INFLATE_ALLOW_INVALID_DIST) + add_definitions(-DINFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR) + message(STATUS "Inflate zero data for invalid distances enabled") +endif() +# +# Enable reduced memory configuration +# +if(WITH_REDUCED_MEM) + add_definitions(-DHASH_SIZE=32768u -DGZBUFSIZE=8192) + message(STATUS "Configured for reduced memory environment") +endif() + + +set(ZLIB_ARCH_SRCS) +set(ZLIB_ARCH_HDRS) +set(ARCHDIR "arch/generic") +if(BASEARCH_ARM_FOUND) + set(ARCHDIR "arch/arm") +elseif(BASEARCH_PPC_FOUND) + set(ARCHDIR "arch/power") +elseif(BASEARCH_S360_FOUND) + set(ARCHDIR "arch/s390") +elseif(BASEARCH_X86_FOUND) + set(ARCHDIR "arch/x86") + if(NOT ${ARCH} MATCHES "x86_64") + add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") + endif() +else() + message(STATUS "No optimized architecture: using ${ARCHDIR}") +endif() + +if(WITH_OPTIM) + if(BASEARCH_ARM_FOUND) + add_definitions(-DARM_FEATURES) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + check_c_source_compiles( + "#include + #include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_HWCAP_HAS_CRC32 + ) + if (ARM_HWCAP_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP) + else() + message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if(ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if (ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + message(STATUS "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + endif() + endif() + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/arm_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/arm_features.c) + if(WITH_ACLE AND NOT "${ARCH}" MATCHES "armv[2-7]") + check_acle_compiler_flag() + if(HAVE_ACLE_FLAG) + add_definitions(-DARM_ACLE) + set(ACLE_SRCS ${ARCHDIR}/crc32_acle.c ${ARCHDIR}/insert_string_acle.c) + set_property(SOURCE ${ACLE_SRCS} PROPERTY COMPILE_FLAGS "${ACLEFLAG} ${NOLTOFLAG}") + list(APPEND ZLIB_ARCH_SRCS ${ACLE_SRCS}) + add_feature_info(ACLE_CRC 1 "Support ACLE optimized CRC hash generation, using \"${ACLEFLAG}\"") + else() + set(WITH_ACLE OFF) + endif() + else() + set(WITH_ACLE OFF) + endif() + if(WITH_NEON) + check_neon_compiler_flag() + if(MFPU_NEON_AVAILABLE) + add_definitions(-DARM_NEON) + set(NEON_SRCS ${ARCHDIR}/adler32_neon.c ${ARCHDIR}/chunkset_neon.c + ${ARCHDIR}/compare256_neon.c ${ARCHDIR}/slide_hash_neon.c) + list(APPEND ZLIB_ARCH_SRCS ${NEON_SRCS}) + set_property(SOURCE ${NEON_SRCS} PROPERTY COMPILE_FLAGS "${NEONFLAG} ${NOLTOFLAG}") + if(MSVC) + add_definitions(-D__ARM_NEON__) + endif() + add_feature_info(NEON_ADLER32 1 "Support NEON instructions in adler32, using \"${NEONFLAG}\"") + add_feature_info(NEON_SLIDEHASH 1 "Support NEON instructions in slide_hash, using \"${NEONFLAG}\"") + check_neon_ld4_intrinsics() + if(NEON_HAS_LD4) + add_definitions(-DARM_NEON_HASLD4) + endif() + else() + set(WITH_NEON OFF) + endif() + endif() + elseif(BASEARCH_PPC_FOUND) + # Common arch detection code + if(WITH_ALTIVEC) + check_ppc_intrinsics() + endif() + if(WITH_POWER8) + check_power8_intrinsics() + endif() + if(WITH_POWER9) + check_power9_intrinsics() + endif() + if(HAVE_VMX OR HAVE_POWER8_INTRIN OR HAVE_POWER9_INTRIN) + add_definitions(-DPOWER_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/power_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/power_features.c) + endif() + # VMX specific options and files + if(WITH_ALTIVEC) + if(HAVE_VMX) + add_definitions(-DPPC_FEATURES) + if(HAVE_ALTIVEC) + add_definitions(-DPPC_VMX) + set(PPC_SRCS ${ARCHDIR}/adler32_vmx.c ${ARCHDIR}/slide_hash_vmx.c) + list(APPEND ZLIB_ARCH_SRCS ${PPC_SRCS}) + add_feature_info(ALTIVEC 1 "Support the AltiVec instruction set, using \"-maltivec\"") + set_property(SOURCE ${PPC_SRCS} PROPERTY COMPILE_FLAGS "${PPCFLAGS}") + else() + set(WITH_ALTIVEC OFF) + endif() + endif() + endif() + # Power8 specific options and files + if(WITH_POWER8) + if(HAVE_POWER8_INTRIN) + add_definitions(-DPOWER8_VSX) + set(POWER8_SRCS ${ARCHDIR}/adler32_power8.c ${ARCHDIR}/chunkset_power8.c ${ARCHDIR}/slide_hash_power8.c) + if("${ARCH}" MATCHES "powerpc64(le)?") + add_definitions(-DPOWER8_VSX_CRC32) + list(APPEND POWER8_SRCS ${ARCHDIR}/crc32_power8.c) + endif() + list(APPEND ZLIB_ARCH_SRCS ${POWER8_SRCS}) + set_property(SOURCE ${POWER8_SRCS} PROPERTY COMPILE_FLAGS "${POWER8FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER8 OFF) + endif() + endif() + # Power9 specific options and files + if(WITH_POWER9) + if(HAVE_POWER9_INTRIN) + add_definitions(-DPOWER9) + set(POWER9_SRCS ${ARCHDIR}/compare256_power9.c) + list(APPEND ZLIB_ARCH_SRCS ${POWER9_SRCS}) + set_property(SOURCE ${POWER9_SRCS} PROPERTY COMPILE_FLAGS "${POWER9FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER9 OFF) + endif() + endif() + elseif(BASEARCH_S360_FOUND) + check_s390_intrinsics() + if(HAVE_S390_INTRIN) + add_definitions(-DS390_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/s390_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/s390_features.c) + endif() + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_common.c) + endif() + if(WITH_DFLTCC_DEFLATE) + add_definitions(-DS390_DFLTCC_DEFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_deflate.c) + endif() + if(WITH_DFLTCC_INFLATE) + add_definitions(-DS390_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_inflate.c) + endif() + if(WITH_CRC32_VX) + check_vgfma_intrinsics() + if(HAVE_VGFMA_INTRIN) + add_definitions(-DS390_CRC32_VX) + set(CRC32_VX_SRCS ${ARCHDIR}/crc32-vx.c) + list(APPEND ZLIB_ARCH_SRCS ${CRC32_VX_SRCS}) + set_property(SOURCE ${CRC32_VX_SRCS} PROPERTY COMPILE_FLAGS "${VGFMAFLAG} ${NOLTOFLAG}") + else() + set(WITH_CRC32_VX OFF) + endif() + endif() + elseif(BASEARCH_X86_FOUND) + add_definitions(-DX86_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/x86_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/x86_features.c) + if(MSVC) + list(APPEND ZLIB_ARCH_HDRS fallback_builtins.h) + endif() + if(WITH_AVX2) + check_avx2_intrinsics() + if(HAVE_AVX2_INTRIN) + add_definitions(-DX86_AVX2) + set(AVX2_SRCS ${ARCHDIR}/slide_hash_avx2.c) + add_feature_info(AVX2_SLIDEHASH 1 "Support AVX2 optimized slide_hash, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/chunkset_avx2.c) + add_feature_info(AVX2_CHUNKSET 1 "Support AVX2 optimized chunkset, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/compare256_avx2.c) + add_feature_info(AVX2_COMPARE256 1 "Support AVX2 optimized compare256, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/adler32_avx2.c) + add_feature_info(AVX2_ADLER32 1 "Support AVX2-accelerated adler32, using \"${AVX2FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX2_SRCS}) + set_property(SOURCE ${AVX2_SRCS} PROPERTY COMPILE_FLAGS "${AVX2FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX2 OFF) + endif() + endif() + if(WITH_AVX512) + check_avx512_intrinsics() + if(HAVE_AVX512_INTRIN) + add_definitions(-DX86_AVX512) + list(APPEND AVX512_SRCS ${ARCHDIR}/adler32_avx512.c) + add_feature_info(AVX512_ADLER32 1 "Support AVX512-accelerated adler32, using \"${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX512_SRCS}) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/adler32_avx512_p.h) + if(HAVE_MASK_INTRIN) + add_definitions(-DX86_MASK_INTRIN) + endif() + set_property(SOURCE ${AVX512_SRCS} PROPERTY COMPILE_FLAGS "${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512 OFF) + endif() + endif() + if(WITH_AVX512VNNI) + check_avx512vnni_intrinsics() + if(HAVE_AVX512VNNI_INTRIN) + add_definitions(-DX86_AVX512VNNI) + add_feature_info(AVX512VNNI_ADLER32 1 "Support AVX512VNNI adler32, using \"${AVX512VNNIFLAG}\"") + list(APPEND AVX512VNNI_SRCS ${ARCHDIR}/adler32_avx512_vnni.c) + list(APPEND ZLIB_ARCH_SRCS ${AVX512VNNI_SRCS}) + set_property(SOURCE ${AVX512VNNI_SRCS} PROPERTY COMPILE_FLAGS "${AVX512VNNIFLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512VNNI OFF) + endif() + endif() + if(WITH_SSE42) + check_sse42_intrinsics() + if(HAVE_SSE42CRC_INLINE_ASM OR HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42) + set(SSE42_SRCS ${ARCHDIR}/adler32_sse42.c ${ARCHDIR}/insert_string_sse42.c) + add_feature_info(SSE42_CRC 1 "Support SSE4.2 optimized CRC hash generation, using \"${SSE42FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSE42_SRCS}) + set_property(SOURCE ${SSE42_SRCS} PROPERTY COMPILE_FLAGS "${SSE42FLAG} ${NOLTOFLAG}") + if(HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42_CRC_INTRIN) + endif() + else() + set(WITH_SSE42 OFF) + endif() + endif() + if(WITH_SSE2) + check_sse2_intrinsics() + if(HAVE_SSE2_INTRIN) + add_definitions(-DX86_SSE2) + set(SSE2_SRCS ${ARCHDIR}/chunkset_sse2.c ${ARCHDIR}/compare256_sse2.c ${ARCHDIR}/slide_hash_sse2.c) + list(APPEND ZLIB_ARCH_SRCS ${SSE2_SRCS}) + if(NOT ${ARCH} MATCHES "x86_64") + set_property(SOURCE ${SSE2_SRCS} PROPERTY COMPILE_FLAGS "${SSE2FLAG} ${NOLTOFLAG}") + add_feature_info(FORCE_SSE2 FORCE_SSE2 "Assume CPU is SSE2 capable") + if(FORCE_SSE2) + add_definitions(-DX86_NOCHECK_SSE2) + endif() + endif() + else() + set(WITH_SSE2 OFF) + endif() + endif() + if(WITH_SSSE3) + check_ssse3_intrinsics() + if(HAVE_SSSE3_INTRIN) + add_definitions(-DX86_SSSE3) + set(SSSE3_SRCS ${ARCHDIR}/adler32_ssse3.c ${ARCHDIR}/chunkset_ssse3.c) + add_feature_info(SSSE3_ADLER32 1 "Support SSSE3-accelerated adler32, using \"${SSSE3FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSSE3_SRCS}) + set_property(SOURCE ${SSSE3_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${NOLTOFLAG}") + else() + set(WITH_SSSE3 OFF) + endif() + endif() + if(WITH_PCLMULQDQ AND WITH_SSSE3 AND WITH_SSE42) + check_pclmulqdq_intrinsics() + if(HAVE_PCLMULQDQ_INTRIN AND HAVE_SSSE3_INTRIN) + add_definitions(-DX86_PCLMULQDQ_CRC) + set(PCLMULQDQ_SRCS ${ARCHDIR}/crc32_pclmulqdq.c) + add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ, using \"${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${PCLMULQDQ_SRCS}) + set_property(SOURCE ${PCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${NOLTOFLAG}") + + if(WITH_VPCLMULQDQ AND WITH_AVX512) + check_vpclmulqdq_intrinsics() + if(HAVE_VPCLMULQDQ_INTRIN AND HAVE_AVX512_INTRIN) + add_definitions(-DX86_VPCLMULQDQ_CRC) + set(VPCLMULQDQ_SRCS ${ARCHDIR}/crc32_vpclmulqdq.c) + add_feature_info(VPCLMUL_CRC 1 "Support CRC hash generation using VPCLMULQDQ, using \"${VPCLMULFLAG} ${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${VPCLMULQDQ_SRCS}) + set_property(SOURCE ${VPCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${VPCLMULFLAG} ${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + check_xsave_intrinsics() + if(HAVE_XSAVE_INTRIN) + add_feature_info(XSAVE 1 "Support XSAVE intrinsics using \"${XSAVEFLAG}\"") + set_property(SOURCE ${ARCHDIR}/x86_features.c PROPERTY COMPILE_FLAGS "${XSAVEFLAG}") + endif() + endif() +endif() + +message(STATUS "Architecture-specific source files: ${ZLIB_ARCH_SRCS}") + +#============================================================================ +# zconf.h +#============================================================================ + +macro(generate_cmakein input output) + file(REMOVE ${output}) + file(STRINGS ${input} _lines) + foreach(_line IN LISTS _lines) + string(REGEX REPLACE "#ifdef HAVE_UNISTD_H.*" "@ZCONF_UNISTD_LINE@" _line "${_line}") + string(REGEX REPLACE "#ifdef NEED_PTRDIFF_T.*" "@ZCONF_PTRDIFF_LINE@" _line "${_line}") + if(NEED_PTRDIFF_T) + string(REGEX REPLACE "typedef PTRDIFF_TYPE" "typedef @PTRDIFF_TYPE@" _line "${_line}") + endif() + file(APPEND ${output} "${_line}\n") + endforeach() +endmacro(generate_cmakein) + +generate_cmakein( ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.in ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein ) + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h") + message(STATUS "to 'zconf${SUFFIX}.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.included) + endif() + + # If we're doing an out of source build and the user has a zconf.h.cmakein + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein") + message(STATUS "to 'zconf${SUFFIX}.h.cmakeincluded' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakeincluded) + endif() +endif() + +# Refer to prefix symbolically to ease relocation by end user, +# as Makefile-generated .pc file does. +string(FIND "${CMAKE_INSTALL_INCLUDEDIR}" "${CMAKE_INSTALL_PREFIX}/" INCLUDEDIR_POS) +string(FIND "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_PREFIX}/" LIBDIR_POS) +string(LENGTH "${CMAKE_INSTALL_PREFIX}/" INSTALL_PREFIX_LEN) + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(PC_INC_INSTALL_DIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +elseif(INCLUDEDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_INCLUDEDIR}" "${INSTALL_PREFIX_LEN}" "-1" INCLUDEDIR_RELATIVE) + set(PC_INC_INSTALL_DIR "\${prefix}/${INCLUDEDIR_RELATIVE}") +else() + set(PC_INC_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +endif() + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +elseif(LIBDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_LIBDIR}" "${INSTALL_PREFIX_LEN}" "-1" LIBDIR_RELATIVE) + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${LIBDIR_RELATIVE}") +else() + set(PC_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") +endif() + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h +) +set(ZLIB_PRIVATE_HDRS + adler32_p.h + chunkset_tpl.h + cpu_features.h + crc32_braid_p.h + crc32_braid_comb_p.h + crc32_braid_tbl.h + crc32_fold.h + deflate.h + deflate_p.h + functable.h + inffast_tpl.h + inffixed_tbl.h + inflate.h + inflate_p.h + inftrees.h + insert_string_tpl.h + match_tpl.h + trees.h + trees_emit.h + trees_tbl.h + zbuild.h + zendian.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + adler32_fold.c + chunkset.c + compare256.c + compress.c + cpu_features.c + crc32_braid.c + crc32_braid_comb.c + crc32_fold.c + deflate.c + deflate_fast.c + deflate_huff.c + deflate_medium.c + deflate_quick.c + deflate_rle.c + deflate_slow.c + deflate_stored.c + functable.c + infback.c + inflate.c + inftrees.c + insert_string.c + insert_string_roll.c + slide_hash.c + trees.c + uncompr.c + zutil.c +) + +set(ZLIB_GZFILE_PRIVATE_HDRS + gzguts.h +) +set(ZLIB_GZFILE_SRCS + gzlib.c + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c + gzwrite.c +) + +set(ZLIB_ALL_SRCS ${ZLIB_SRCS} ${ZLIB_ARCH_HDRS} ${ZLIB_ARCH_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +if(WITH_GZFILEOP) + list(APPEND ZLIB_ALL_SRCS ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS win32/zlib${SUFFIX}1.rc) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS) + add_library(zlib SHARED ${ZLIB_ALL_SRCS} ${ZLIB_DLL_SRCS}) + add_library(zlibstatic STATIC ${ZLIB_ALL_SRCS}) + + set(ZLIB_INSTALL_LIBRARIES zlib zlibstatic) +else() + add_library(zlib ${ZLIB_ALL_SRCS}) + + if(BUILD_SHARED_LIBS) + target_sources(zlib PRIVATE ${ZLIB_DLL_SRCS}) + else() + add_library(zlibstatic ALIAS zlib) + endif() + + set(ZLIB_INSTALL_LIBRARIES zlib) +endif() + +foreach(ZLIB_INSTALL_LIBRARY ${ZLIB_INSTALL_LIBRARIES}) + if(NOT ZLIB_COMPAT) + target_compile_definitions(${ZLIB_INSTALL_LIBRARY} PUBLIC ZLIBNG_NATIVE_API) + endif() + target_include_directories(${ZLIB_INSTALL_LIBRARY} PUBLIC + "$" + "$") +endforeach() + +if(WIN32) + # Shared library + if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlib${SUFFIX}) + endif() + # Static library + if(NOT DEFINED BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + elseif(NOT BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlib PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + endif() +else() + # On unix-like platforms the library is almost always called libz + set_target_properties(${ZLIB_INSTALL_LIBRARIES} PROPERTIES OUTPUT_NAME z${SUFFIX}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SOVERSION 1) + else() + set_target_properties(zlib PROPERTIES SOVERSION 2) + endif() + + if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) + endif() + + if(UNIX) + if(HAVE_NO_INTERPOSITION) + set_target_properties(zlib PROPERTIES COMPILE_FLAGS "-fno-semantic-interposition") + endif() + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS + "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.map\"") + else() + # Match configure/make's behavior (i.e. don't use @rpath on mac). + set_target_properties(zlib PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}") + endif() + endif() + if(MSYS) + # Suppress version number from shared library name + set(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 0) + elseif(WIN32) + # Creates zlib1.dll when building shared library version + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") + else() + set_target_properties(zlib PROPERTIES SUFFIX "2.dll") + endif() + endif() +endif() + +if(HAVE_UNISTD_H) + SET(ZCONF_UNISTD_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_UNISTD_LINE "#if 0 /* was set to #if 0 by configure/cmake/etc */") +endif() +if(NEED_PTRDIFF_T) + SET(ZCONF_PTRDIFF_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_PTRDIFF_LINE "#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */") +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.pc) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file(${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gzread.c.in + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c @ONLY) + + +if (NOT ZLIB_SYMBOL_PREFIX STREQUAL "") + add_feature_info(ZLIB_SYMBOL_PREFIX ON "Publicly exported symbols have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h @ONLY) +else() + add_feature_info(ZLIB_SYMBOL_PREFIX OFF "Publicly exported symbols DO NOT have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling.h.empty + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h COPYONLY) +endif() +# add_definitions(-DZLIB_SYMBOL_PREFIX=${ZLIB_SYMBOL_PREFIX}) # not needed + + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${ZLIB_INSTALL_LIBRARIES} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib_name_mangling${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zconf${SUFFIX}.h) +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL) + install(FILES ${ZLIB_PC} DESTINATION "${PKGCONFIG_INSTALL_DIR}") +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +if(ZLIB_ENABLE_TESTS) + enable_testing() + + if(BUILD_SHARED_LIBS) + if(ZLIBNG_ENABLE_TESTS) + message(STATUS "Disabling zlib-ng tests because shared libraries are enabled") + set(ZLIBNG_ENABLE_TESTS OFF) + endif() + + if(WITH_BENCHMARKS OR WITH_BENCHMARK_APPS) + message(STATUS "Disabling benchmarks because shared libraries are enabled") + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARK_APPS OFF) + endif() + endif() + + add_subdirectory(test) +endif() + +add_feature_info(WITH_GZFILEOP WITH_GZFILEOP "Compile with support for gzFile related functions") +add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Compile with zlib compatible API") +add_feature_info(ZLIB_ENABLE_TESTS ZLIB_ENABLE_TESTS "Build test binaries") +add_feature_info(ZLIBNG_ENABLE_TESTS ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API") +add_feature_info(WITH_SANITIZER WITH_SANITIZER "Enable sanitizer support") +add_feature_info(WITH_GTEST WITH_GTEST "Build gtest_zlib") +add_feature_info(WITH_FUZZERS WITH_FUZZERS "Build test/fuzz") +add_feature_info(WITH_BENCHMARKS WITH_BENCHMARKS "Build test/benchmarks") +add_feature_info(WITH_BENCHMARK_APPS WITH_BENCHMARK_APPS "Build application benchmarks") +add_feature_info(WITH_OPTIM WITH_OPTIM "Build with optimisation") +add_feature_info(WITH_NEW_STRATEGIES WITH_NEW_STRATEGIES "Use new strategies") +add_feature_info(WITH_NATIVE_INSTRUCTIONS WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)") +add_feature_info(WITH_MAINTAINER_WARNINGS WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings") +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_INFLATE_STRICT WITH_INFLATE_STRICT "Build with strict inflate distance checking") +add_feature_info(WITH_INFLATE_ALLOW_INVALID_DIST WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances") + +if(BASEARCH_ARM_FOUND) + add_feature_info(WITH_ACLE WITH_ACLE "Build with ACLE") + add_feature_info(WITH_NEON WITH_NEON "Build with NEON intrinsics") +elseif(BASEARCH_PPC_FOUND) + add_feature_info(WITH_ALTIVEC WITH_ALTIVEC "Build with AltiVec optimisations") + add_feature_info(WITH_POWER8 WITH_POWER8 "Build with optimisations for POWER8") + add_feature_info(WITH_POWER9 WITH_POWER9 "Build with optimisations for POWER9") +elseif(BASEARCH_S360_FOUND) + add_feature_info(WITH_DFLTCC_DEFLATE WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z") + add_feature_info(WITH_DFLTCC_INFLATE WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z") + add_feature_info(WITH_CRC32_VX WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z") +elseif(BASEARCH_X86_FOUND) + add_feature_info(WITH_AVX2 WITH_AVX2 "Build with AVX2") + add_feature_info(WITH_AVX512 WITH_AVX512 "Build with AVX512") + add_feature_info(WITH_AVX512VNNI WITH_AVX512VNNI "Build with AVX512 VNNI") + add_feature_info(WITH_SSE2 WITH_SSE2 "Build with SSE2") + add_feature_info(WITH_SSSE3 WITH_SSSE3 "Build with SSSE3") + add_feature_info(WITH_SSE42 WITH_SSE42 "Build with SSE42") + add_feature_info(WITH_PCLMULQDQ WITH_PCLMULQDQ "Build with PCLMULQDQ") + add_feature_info(WITH_VPCLMULQDQ WITH_VPCLMULQDQ "Build with VPCLMULQDQ") +endif() + +add_feature_info(INSTALL_UTILS INSTALL_UTILS "Copy minigzip and minideflate during install") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/FAQ.zlib b/internal-complibs/zlib-ng-2.1.0-beta1/FAQ.zlib new file mode 100644 index 000000000..163160c10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/FAQ.zlib @@ -0,0 +1,374 @@ +## +# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.11 +## + + + + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +https://zlib.net/ which may have more recent information. +The latest zlib FAQ is at https://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at https://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * https://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See https://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See https://www.pdflib.com/ . To modify PDF forms, see + https://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com/ for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + https://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + https://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: https://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, https://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://infozip.sourceforge.net/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/INDEX.md b/internal-complibs/zlib-ng-2.1.0-beta1/INDEX.md new file mode 100644 index 000000000..22fd470e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/INDEX.md @@ -0,0 +1,36 @@ +Contents +-------- + +| Name | Description | +|:-----------------|:---------------------------------------------------------------| +| arch/ | Architecture-specific code | +| doc/ | Documentation for formats and algorithms | +| test/example.c | Zlib usages examples for build testing | +| test/minigzip.c | Minimal gzip-like functionality for build testing | +| test/infcover.c | Inflate code coverage for build testing | +| win32/ | Shared library version resources for Windows | +| CMakeLists.txt | Cmake build script | +| configure | Bash configure/build script | +| adler32.c | Compute the Adler-32 checksum of a data stream | +| chunkset.* | Inline functions to copy small data chunks | +| compress.c | Compress a memory buffer | +| deflate.* | Compress data using the deflate algorithm | +| deflate_fast.c | Compress data using the deflate algorithm with fast strategy | +| deflate_medium.c | Compress data using the deflate algorithm with medium strategy | +| deflate_slow.c | Compress data using the deflate algorithm with slow strategy | +| functable.* | Struct containing function pointers to optimized functions | +| gzguts.h | Internal definitions for gzip operations | +| gzlib.c | Functions common to reading and writing gzip files | +| gzread.c | Read gzip files | +| gzwrite.c | Write gzip files | +| infback.* | Inflate using a callback interface | +| inflate.* | Decompress data | +| inffast.* | Decompress data with speed optimizations | +| inffixed_tbl.h | Table for decoding fixed codes | +| inftrees.h | Generate Huffman trees for efficient decoding | +| trees.* | Output deflated data using Huffman coding | +| uncompr.c | Decompress a memory buffer | +| zconf.h.cmakein | zconf.h template for cmake | +| zendian.h | BYTE_ORDER for endian tests | +| zlib.map | Linux symbol information | +| zlib.pc.in | Pkg-config template | diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/LICENSE.md b/internal-complibs/zlib-ng-2.1.0-beta1/LICENSE.md new file mode 100644 index 000000000..adb48d472 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/LICENSE.md @@ -0,0 +1,19 @@ +(C) 1995-2013 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/Makefile.in new file mode 100644 index 000000000..8ca8c81da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/Makefile.in @@ -0,0 +1,395 @@ +# Makefile for zlib +# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DZLIB_DEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS=-L. +LIBNAME1=libz-ng +LIBNAME2=zlib-ng +SUFFIX=-ng +TEST_LIBS=$(LIBNAME1).a +LDSHARED=$(CC) +LDSHAREDFLAGS=-shared + +VER=2.1.0.beta1 +VER1=2 + +STATICLIB=$(LIBNAME1).a +SHAREDLIB=$(LIBNAME1).so +SHAREDLIBV=$(LIBNAME1).so.$(VER) +SHAREDLIBM=$(LIBNAME1).so.$(VER1) +IMPORTLIB= +SHAREDTARGET=$(LIBNAME1).so.$(VER) +PKGFILE=$(LIBNAME2).pc + +LIBS=$(STATICLIB) $(SHAREDTARGET) + +AR=ar +ARFLAGS=rc +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC= +EXE= + +SRCDIR=. +INCLUDES=-I$(SRCDIR) + +BUILDDIR=. + +ARCHDIR=arch/generic +ARCH_STATIC_OBJS= +ARCH_SHARED_OBJS= + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig + +OBJZ = \ + adler32.o \ + adler32_fold.o \ + chunkset.o \ + compare256.o \ + compress.o \ + cpu_features.o \ + crc32_braid.o \ + crc32_braid_comb.o \ + crc32_fold.o \ + deflate.o \ + deflate_fast.o \ + deflate_huff.o \ + deflate_medium.o \ + deflate_quick.o \ + deflate_rle.o \ + deflate_slow.o \ + deflate_stored.o \ + functable.o \ + infback.o \ + inflate.o \ + inftrees.o \ + insert_string.o \ + insert_string_roll.o \ + slide_hash.o \ + trees.o \ + uncompr.o \ + zutil.o \ + $(ARCH_STATIC_OBJS) + +OBJG = \ + gzlib.o \ + gzread.o \ + gzwrite.o + +TESTOBJG = +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = \ + adler32.lo \ + adler32_fold.lo \ + chunkset.lo \ + compare256.lo \ + compress.lo \ + cpu_features.lo \ + crc32_braid.lo \ + crc32_braid_comb.lo \ + crc32_fold.lo \ + deflate.lo \ + deflate_fast.lo \ + deflate_huff.lo \ + deflate_medium.lo \ + deflate_quick.lo \ + deflate_rle.lo \ + deflate_slow.lo \ + deflate_stored.lo \ + functable.lo \ + infback.lo \ + inflate.lo \ + inftrees.lo \ + insert_string.lo \ + insert_string_roll.lo \ + slide_hash.lo \ + trees.lo \ + uncompr.lo \ + zutil.lo \ + $(ARCH_SHARED_OBJS) + +PIC_OBJG = \ + gzlib.lo \ + gzread.lo \ + gzwrite.lo + +PIC_TESTOBJG = +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +OBJS = $(OBJC) + +PIC_OBJS = $(PIC_OBJC) + +all: static shared + +static: example$(EXE) minigzip$(EXE) makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +check: test + +.SECONDARY: + +$(ARCHDIR)/%.o: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +$(ARCHDIR)/%.lo: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +%.o: $(ARCHDIR)/%.o + -cp $< $@ + +%.lo: $(ARCHDIR)/%.lo + -cp $< $@ + +test: all + $(MAKE) -C test + +infcover.o: $(SRCDIR)/test/infcover.c zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/infcover.c + +infcover$(EXE): infcover.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ infcover.o $(STATICLIB) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +cover: infcover$(EXE) + rm -f *.gcda + ./infcover + gcov inf*.c + +$(STATICLIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +example.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/example.c + +minigzip.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/minigzip.c + +makefixed.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makefixed.c + +maketrees.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/maketrees.c + +makecrct.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makecrct.c + +zlibrc.o: $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + $(RC) $(RCFLAGS) -o $@ $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + +.SUFFIXES: .lo + +%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +%.lo: $(SRCDIR)/%.c + $(CC) $(SFLAGS) -DPIC $(INCLUDES) -c -o $@ $< + +gzlib.o: $(SRCDIR)/gzlib.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzlib.lo: $(SRCDIR)/gzlib.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.o: gzread.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.lo: gzread.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.o: $(SRCDIR)/gzwrite.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.lo: $(SRCDIR)/gzwrite.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +$(SHAREDTARGET): $(PIC_OBJS) $(DEFFILE) $(RCOBJS) +ifneq ($(SHAREDTARGET),) + $(LDSHARED) $(CFLAGS) $(LDSHAREDFLAGS) $(LDFLAGS) -o $@ $(DEFFILE) $(PIC_OBJS) $(RCOBJS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) +endif +endif + +example$(EXE): example.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzip$(EXE): minigzip.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzipsh$(EXE): minigzip.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + + +examplesh$(EXE): example.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makefixed$(EXE): makefixed.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makefixed.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +maketrees$(EXE): maketrees.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ maketrees.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makecrct$(EXE): makecrct.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makecrct.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +install-shared: $(SHAREDTARGET) +ifneq ($(SHAREDTARGET),) + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) + cp $(SHAREDTARGET) $(DESTDIR)$(sharedlibdir) + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ($(LDCONFIG) || true) >/dev/null 2>&1 +# ldconfig is for Linux +endif +ifneq ($(IMPORTLIB),) + cp $(IMPORTLIB) $(DESTDIR)$(sharedlibdir) + chmod 644 $(DESTDIR)$(sharedlibdir)/$(IMPORTLIB) +endif +endif + +install-static: $(STATICLIB) + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/$(STATICLIB) || true) >/dev/null 2>&1 +# The ranlib in install-static is needed on NeXTSTEP which checks file times + +install-libs: install-shared install-static + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + cp $(PKGFILE) $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + rm -f $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + cp zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zlib$(SUFFIX).h + cp zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h + cp zlib_name_mangling$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + chmod 644 $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + +uninstall-static: + cd $(DESTDIR)$(libdir) && rm -f $(STATICLIB) + +uninstall-shared: +ifneq ($(SHAREDLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM) +endif +ifneq ($(IMPORTLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(IMPORTLIB) +endif + +uninstall: uninstall-static uninstall-shared + cd $(DESTDIR)$(includedir) && rm -f zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + cd $(DESTDIR)$(pkgconfigdir) && rm -f $(PKGFILE) + +mostlyclean: clean +clean: + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) clean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test clean; fi + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) minigzipsh$(EXE) \ + infcover makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) \ + $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \ + foo.gz so_locations \ + _match.s maketree + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f a.out a.exe + rm -f *._h + rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +maintainer-clean: distclean +distclean: clean + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) distclean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test distclean; fi + rm -f $(PKGFILE) configure.log zconf.h zconf.h.cmakein zlib$(SUFFIX).h zlib_name_mangling$(SUFFIX)}.h *.pc + -@rm -f .DS_Store +# Reset Makefile if building inside source tree + @if [ -f Makefile.in ]; then \ + printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ + printf '\ndistclean:\n\t$(MAKE) -f Makefile.in distclean\n' >> Makefile ; \ + touch -r $(SRCDIR)/Makefile.in Makefile ; fi +# Reset zconf.h and zconf.h.cmakein if building inside source tree + @if [ -f zconf.h.in ]; then \ + cp -p $(SRCDIR)/zconf.h.in zconf.h ; \ + grep -v '^#cmakedefine' $(SRCDIR)/zconf.h.in > zconf.h.cmakein &&\ + touch -r $(SRCDIR)/zconf.h.in zconf.h.cmakein ; fi +# Cleanup these files if building outside source tree + @if [ ! -f README.md ]; then rm -f Makefile; fi +# Remove arch and test directory if building outside source tree + @if [ ! -f $(ARCHDIR)/Makefile.in ]; then rm -rf arch; fi + @if [ ! -f test/Makefile.in ]; then rm -rf test; fi + +tags: + etags $(SRCDIR)/*.[ch] diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/PORTING.md b/internal-complibs/zlib-ng-2.1.0-beta1/PORTING.md new file mode 100644 index 000000000..c48522e3a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/PORTING.md @@ -0,0 +1,79 @@ +Porting applications to use zlib-ng +=================================== + +Zlib-ng can be used/compiled in two different modes, that require some +consideration by the application developer. + +zlib-compat mode +---------------- +Zlib-ng can be compiled in zlib-compat mode, suitable for zlib-replacement +in a single application or system-wide. + +Please note that zlib-ng in zlib-compat mode tries to maintain both API and +ABI compatibility with the original zlib. Any issues regarding compatibility +can be reported as bugs. + +In certain instances you may not be able to simply replace the zlib library/dll +files and expect the application to work. The application may need to be +recompiled against the zlib-ng headers and libs to ensure full compatibility. + +It is also possible for the deflate output stream to differ from the original +zlib due to algorithmic differences between the two libraries. Any tests or +applications that depend on the exact length of the deflate stream being a +certain value will need to be updated. + +**Advantages:** +- Easy to port to, since it only requires a recompile of the application and + no changes to the application code. + +**Disadvantages:** +- Can conflict with a system-installed zlib, as that can often be linked in + by another library you are linking into your application. This can cause + crashes or incorrect output. +- If your application is pre-allocating a memory buffer and you are providing + deflate/inflate init with your own allocator that allocates from that buffer + (looking at you nginx), you should be aware that zlib-ng needs to allocate + more memory than stock zlib needs. The same problem exists with Intel’s and + Cloudflare’s zlib forks. Doing this is not recommended since it makes it + very hard to maintain compatibility over time. + +**Build Considerations:** +- Compile against the *zlib.h* provided by zlib-ng +- Configuration header is named *zconf.h* +- Static library is *libz.a* on Unix and macOS, or *zlib.lib* on Windows +- Shared library is *libz.so* on Unix, *libz.dylib* on macOS, or *zlib1.dll* + on Windows +- Type `z_size_t` is *unsigned __int64* on 64-bit Windows, and *unsigned long* on 32-bit Windows, Unix and macOS +- Type `z_uintmax_t` is *unsigned long* in zlib-compat mode, and *size_t* with zlib-ng API + +zlib-ng native mode +------------------- +Zlib-ng in native mode is suitable for co-existing with the standard zlib +library, allowing applications to implement support and testing separately. + +The zlib-ng native has implemented some modernization and simplifications +in its API, intended to make life easier for application developers. + +**Advantages:** +- Does not conflict with other zlib implementations, and can co-exist as a + system library along with zlib. +- In certain places zlib-ng native uses more appropriate data types, removing + the need for some workarounds in the API compared to zlib. + +**Disadvantages:** +- Requires minor changes to applications to use the prefixed zlib-ng + function calls and structs. Usually this means a small prefix `zng_` has to be added. + +**Build Considerations:** +- Compile against *zlib-ng.h* +- Configuration header is named *zconf-ng.h* +- Static library is *libz-ng.a* on Unix and macOS, or *zlib-ng.lib* on Windows +- Shared library is *libz-ng.so* on Unix, *libz-ng.dylib* on macOS, or + *zlib-ng2.dll* on Windows +- Type `z_size_t` is *size_t* + +zlib-ng compile-time detection +------------------------------ + +To distinguish zlib-ng from other zlib implementations at compile-time check for the +existence of `ZLIBNG_VERSION` defined in the zlib header. diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/README.md b/internal-complibs/zlib-ng-2.1.0-beta1/README.md new file mode 100644 index 000000000..aa72365c9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/README.md @@ -0,0 +1,240 @@ +## zlib-ng +*zlib data compression library for the next generation systems* + +Maintained by Hans Kristian Rosbach + aka Dead2 (zlib-ng àt circlestorm dót org) + +|CI|Status| +|:-|-| +|GitHub Actions|[![Master Branch Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20CMake/badge.svg)](https://github.com/zlib-ng/zlib-ng/actions) [![Master Branch Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20Configure/badge.svg)](https://github.com/zlib-ng/zlib-ng/actions) [![Master Branch Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20NMake/badge.svg)](https://github.com/zlib-ng/zlib-ng/actions)| +|Buildkite|[![Build status](https://badge.buildkite.com/7bb1ef84356d3baee26202706cc053ee1de871c0c712b65d26.svg?branch=develop)](https://buildkite.com/circlestorm-productions/zlib-ng)| +|CodeFactor|[![CodeFactor](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/badge)](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng)| +|OSS-Fuzz|[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/zlib-ng.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zlib-ng) +|Codecov|[![codecov.io](https://codecov.io/github/zlib-ng/zlib-ng/coverage.svg?branch=develop)](https://codecov.io/github/zlib-ng/zlib-ng/)| + + +Features +-------- + +* Zlib compatible API with support for dual-linking +* Modernized native API based on zlib API for ease of porting +* Modern C11 syntax and a clean code layout +* Deflate medium and quick algorithms based on Intel’s zlib fork +* Support for CPU intrinsics when available + * Adler32 implementation using SSSE3, AVX2, AVX512, AVX512-VNNI, Neon, VMX & VSX + * CRC32-B implementation using PCLMULQDQ, VPCLMULQDQ, ACLE, & IBM Z + * Hash table implementation using CRC32-C intrinsics on x86 and ARM + * Slide hash implementations using SSE2, AVX2, Neon, VMX & VSX + * Compare256 implementations using SSE2, AVX2, Neon, & POWER9 + * Inflate chunk copying using SSE2, SSSE3, AVX, Neon & VSX + * Support for hardware-accelerated deflate using IBM Z DFLTCC +* Unaligned memory read/writes and large bit buffer improvements +* Includes improvements from Cloudflare and Intel forks +* Configure, CMake, and NMake build system support +* Comprehensive set of CMake unit tests +* Code sanitizers, fuzzing, and coverage +* GitHub Actions continuous integration on Windows, macOS, and Linux + * Emulated CI for ARM, AARCH64, PPC, PPC64, SPARC64, S390x using qemu + + +History +------- + +The motivation for this fork came after seeing several 3rd party +contributions containing new optimizations not getting implemented +into the official zlib repository. + +Mark Adler has been maintaining zlib for a very long time, and he has +done a great job and hopefully he will continue for a long time yet. +The idea of zlib-ng is not to replace zlib, but to co-exist as a +drop-in replacement with a lower threshold for code change. + +zlib has a long history and is incredibly portable, even supporting +lots of systems that predate the Internet. This is great, but it does +complicate further development and maintainability. +The zlib code has numerous workarounds for old compilers that do not +understand ANSI-C or to accommodate systems with limitations such as +operating in a 16-bit environment. + +Many of these workarounds are only maintenance burdens, some of them +are pretty huge code-wise. For example, the [v]s[n]printf workaround +code has a whopping 8 different implementations just to cater to +various old compilers. With this many workarounds cluttered throughout +the code, new programmers with an idea/interest for zlib will need +to take some time to figure out why all of these seemingly strange +things are used, and how to work within those confines. + +So I decided to make a fork, merge all the Intel optimizations, merge +the Cloudflare optimizations that did not conflict, plus a couple +of other smaller patches. Then I started cleaning out workarounds, +various dead code, all contrib and example code as there is little +point in having those in this fork for various reasons. + +A lot of improvements have gone into zlib-ng since its start, and +numerous people and companies have contributed both small and big +improvements, or valuable testing. + +Please read LICENSE.md, it is very simple and very liberal. + + +Build +----- + +There are two ways to build zlib-ng: + +### Cmake + +To build zlib-ng using the cross-platform makefile generator cmake. + +``` +cmake . +cmake --build . --config Release +ctest --verbose -C Release +``` + +Alternatively, you can use the cmake configuration GUI tool ccmake: + +``` +ccmake . +``` + +### Configure + +To build zlib-ng using the bash configure script: + +``` +./configure +make +make test +``` + +Build Options +------------- + +| CMake | configure | Description | Default | +|:-------------------------|:-------------------------|:--------------------------------------------------------------------------------------|---------| +| ZLIB_COMPAT | --zlib-compat | Compile with zlib compatible API | OFF | +| ZLIB_ENABLE_TESTS | | Build test binaries | ON | +| WITH_GZFILEOP | --without-gzfileops | Compile with support for gzFile related functions | ON | +| WITH_OPTIM | --without-optimizations | Build with optimisations | ON | +| WITH_NEW_STRATEGIES | --without-new-strategies | Use new strategies | ON | +| WITH_NATIVE_INSTRUCTIONS | --native | Compiles with full instruction set supported on this host (gcc/clang -march=native) | OFF | +| WITH_SANITIZER | | Build with sanitizer (memory, address, undefined) | OFF | +| WITH_GTEST | | Build gtest_zlib | ON | +| WITH_FUZZERS | | Build test/fuzz | OFF | +| WITH_BENCHMARKS | | Build test/benchmarks | OFF | +| WITH_MAINTAINER_WARNINGS | | Build with project maintainer warnings | OFF | +| WITH_CODE_COVERAGE | | Enable code coverage reporting | OFF | + + +Install +------- + +WARNING: We do not recommend manually installing unless you really +know what you are doing, because this can potentially override the system +default zlib library, and any incompatibility or wrong configuration of +zlib-ng can make the whole system unusable, requiring recovery or reinstall. +If you still want a manual install, we recommend using the /opt/ path prefix. + +For Linux distros, an alternative way to use zlib-ng (if compiled in +zlib-compat mode) instead of zlib, is through the use of the +_LD_PRELOAD_ environment variable. If the program is dynamically linked +with zlib, then zlib-ng will temporarily be used instead by the program, +without risking system-wide instability. + +``` +LD_PRELOAD=/opt/zlib-ng/libz.so.1.2.13.zlib-ng /usr/bin/program +``` + +### Cmake + +To install zlib-ng system-wide using cmake: + +``` +cmake --build . --target install +``` + +### Configure + +To install zlib-ng system-wide using the configure script: + +``` +make install +``` + +### Vcpkg + +Alternatively, you can build and install zlib-ng using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + +```sh or powershell +git clone https://github.com/Microsoft/vcpkg.git +cd vcpkg +./bootstrap-vcpkg.sh # "./bootstrap-vcpkg.bat" for powershell +./vcpkg integrate install +./vcpkg install zlib-ng +``` + +The zlib-ng port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + +Contributing +------------ + +Zlib-ng is a aiming to be open to contributions, and we would be delighted to +receive pull requests on github. +Just remember that any code you submit must be your own and it must be zlib licensed. +Help with testing and reviewing of pull requests etc is also very much appreciated. + +If you are interested in contributing, please consider joining our +IRC channel #zlib-ng on the Freenode IRC network. + + +Acknowledgments +---------------- + +Thanks to Servebolt.com for sponsoring my maintainership of zlib-ng. + +Thanks go out to all the people and companies who have taken the time to contribute +code reviews, testing and/or patches. Zlib-ng would not have been nearly as good without you. + +The deflate format used by zlib was defined by Phil Katz. +The deflate and zlib specifications were written by L. Peter Deutsch. + +zlib was originally created by Jean-loup Gailly (compression) +and Mark Adler (decompression). + + +Advanced Build Options +---------------------- + +| CMake | configure | Description | Default | +|:--------------------------------|:----------------------|:--------------------------------------------------------------------|------------------------| +| FORCE_SSE2 | --force-sse2 | Skip runtime check for SSE2 instructions (Always on for x86_64) | OFF (x86) | +| WITH_AVX2 | | Build with AVX2 intrinsics | ON | +| WITH_AVX512 | | Build with AVX512 intrinsics | ON | +| WITH_AVX512VNNI | | Build with AVX512VNNI intrinsics | ON | +| WITH_SSE2 | | Build with SSE2 intrinsics | ON | +| WITH_SSSE3 | | Build with SSSE3 intrinsics | ON | +| WITH_SSE42 | | Build with SSE42 intrinsics | ON | +| WITH_PCLMULQDQ | | Build with PCLMULQDQ intrinsics | ON | +| WITH_VPCLMULQDQ | --without-vpclmulqdq | Build with VPCLMULQDQ intrinsics | ON | +| WITH_ACLE | --without-acle | Build with ACLE intrinsics | ON | +| WITH_NEON | --without-neon | Build with NEON intrinsics | ON | +| WITH_ALTIVEC | --without-altivec | Build with AltiVec (VMX) intrinsics | ON | +| WITH_POWER8 | --without-power8 | Build with POWER8 optimisations | ON | +| WITH_CRC32_VX | --without-crc32-vx | Build with vectorized CRC32 on IBM Z | ON | +| WITH_DFLTCC_DEFLATE | --with-dfltcc-deflate | Build with DFLTCC intrinsics for compression on IBM Z | OFF | +| WITH_DFLTCC_INFLATE | --with-dfltcc-inflate | Build with DFLTCC intrinsics for decompression on IBM Z | OFF | +| WITH_UNALIGNED | --without-unaligned | Allow optimizations that use unaligned reads if safe on current arch| ON | +| WITH_INFLATE_STRICT | | Build with strict inflate distance checking | OFF | +| WITH_INFLATE_ALLOW_INVALID_DIST | | Build with zero fill for inflate invalid distances | OFF | +| INSTALL_UTILS | | Copy minigzip and minideflate during install | OFF | +| ZLIBNG_ENABLE_TESTS | | Test zlib-ng specific API | ON | + + +Related Projects +---------------- + +* Fork of the popular minizip https://github.com/zlib-ng/minizip-ng +* Python tool to benchmark minigzip/minideflate https://github.com/zlib-ng/deflatebench +* Python tool to benchmark pigz https://github.com/zlib-ng/pigzbench +* 3rd party patches for zlib-ng compatibility https://github.com/zlib-ng/patches diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/adler32.c b/internal-complibs/zlib-ng-2.1.0-beta1/adler32.c new file mode 100644 index 000000000..95ac13c30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/adler32.c @@ -0,0 +1,115 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_p.h" + +/* ========================================================================= */ +Z_INTERNAL uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; +#ifdef UNROLL_MORE + n = NMAX / 16; /* NMAX is divisible by 16 */ +#else + n = NMAX / 8; /* NMAX is divisible by 8 */ +#endif + do { +#ifdef UNROLL_MORE + DO16(adler, sum2, buf); /* 16 sums unrolled */ + buf += 16; +#else + DO8(adler, sum2, buf, 0); /* 8 sums unrolled */ + buf += 8; +#endif + } while (--n); + adler %= BASE; + sum2 %= BASE; + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + return adler32_len_64(adler, buf, len, sum2); +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_z)(unsigned long adler, const unsigned char *buf, size_t len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32_z)(uint32_t adler, const unsigned char *buf, size_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32)(unsigned long adler, const unsigned char *buf, unsigned int len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32)(uint32_t adler, const unsigned char *buf, uint32_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +static uint32_t adler32_combine_(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + uint32_t sum1; + uint32_t sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffff; + + /* the derivation of this formula is left as an exercise for the reader */ + len2 %= BASE; /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + sum2 %= BASE; + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} + +unsigned long Z_EXPORT PREFIX4(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off64_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} +#else +uint32_t Z_EXPORT PREFIX4(adler32_combine)(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.c b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.c new file mode 100644 index 000000000..e2f6f9ac7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.c @@ -0,0 +1,16 @@ +/* adler32_fold.c -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_fold.h" + +#include + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + adler = functable.adler32(adler, src, len); + memcpy(dst, src, len); + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.h b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.h new file mode 100644 index 000000000..20aa1c740 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_fold.h @@ -0,0 +1,11 @@ +/* adler32_fold.h -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_FOLD_H_ +#define ADLER32_FOLD_H_ + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/adler32_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_p.h new file mode 100644 index 000000000..38ba2ad72 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/adler32_p.h @@ -0,0 +1,70 @@ +/* adler32_p.h -- Private inline functions and macros shared with + * different computation of the Adler-32 checksum + * of a data stream. + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_P_H +#define ADLER32_P_H + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(sum1, sum2, buf, i) {(sum1) += buf[(i)]; (sum2) += (sum1);} +#define DO2(sum1, sum2, buf, i) {DO1(sum1, sum2, buf, i); DO1(sum1, sum2, buf, i+1);} +#define DO4(sum1, sum2, buf, i) {DO2(sum1, sum2, buf, i); DO2(sum1, sum2, buf, i+2);} +#define DO8(sum1, sum2, buf, i) {DO4(sum1, sum2, buf, i); DO4(sum1, sum2, buf, i+4);} +#define DO16(sum1, sum2, buf) {DO8(sum1, sum2, buf, 0); DO8(sum1, sum2, buf, 8);} + +static inline uint32_t adler32_len_1(uint32_t adler, const uint8_t *buf, uint32_t sum2) { + adler += buf[0]; + adler %= BASE; + sum2 += adler; + sum2 %= BASE; + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_16(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { + while (len) { + --len; + adler += *buf++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_copy_len_16(uint32_t adler, const uint8_t *buf, uint8_t *dst, size_t len, uint32_t sum2) { + while (len--) { + *dst = *buf++; + adler += *dst++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_64(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { +#ifdef UNROLL_MORE + while (len >= 16) { + len -= 16; + DO16(adler, sum2, buf); + buf += 16; +#else + while (len >= 8) { + len -= 8; + DO8(adler, sum2, buf, 0); + buf += 8; +#endif + } + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif /* ADLER32_P_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/.gitignore b/internal-complibs/zlib-ng-2.1.0-beta1/arch/.gitignore new file mode 100644 index 000000000..2c3af0a08 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/.gitignore @@ -0,0 +1,2 @@ +# ignore Makefiles; they're all automatically generated +Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/Makefile.in new file mode 100644 index 000000000..abf6193fc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/Makefile.in @@ -0,0 +1,77 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +ACLEFLAG= +NEONFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + adler32_neon.o adler32_neon.lo \ + arm_features.o arm_features.lo \ + chunkset_neon.o chunkset_neon.lo \ + compare256_neon.o compare256_neon.lo \ + crc32_acle.o crc32_acle.lo \ + slide_hash_neon.o slide_hash_neon.lo \ + insert_string_acle.o insert_string_acle.lo + +adler32_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +adler32_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +arm_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +arm_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +chunkset_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +chunkset_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +compare256_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +compare256_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +crc32_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +crc32_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +slide_hash_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +slide_hash_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +insert_string_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +insert_string_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/adler32_neon.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/adler32_neon.c new file mode 100644 index 000000000..f1c43ff04 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/adler32_neon.c @@ -0,0 +1,215 @@ +/* Copyright (C) 1995-2011, 2016 Mark Adler + * Copyright (C) 2017 ARM Holdings Inc. + * Authors: + * Adenilson Cavalcanti + * Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../adler32_p.h" + +static void NEON_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + static const uint16_t ALIGNED_(16) taps[64] = { + 64, 63, 62, 61, 60, 59, 58, 57, + 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1 }; + + uint32x4_t adacc = vdupq_n_u32(0); + uint32x4_t s2acc = vdupq_n_u32(0); + uint32x4_t s2acc_0 = vdupq_n_u32(0); + uint32x4_t s2acc_1 = vdupq_n_u32(0); + uint32x4_t s2acc_2 = vdupq_n_u32(0); + + adacc = vsetq_lane_u32(s[0], adacc, 0); + s2acc = vsetq_lane_u32(s[1], s2acc, 0); + + uint32x4_t s3acc = vdupq_n_u32(0); + uint32x4_t adacc_prev = adacc; + + uint16x8_t s2_0, s2_1, s2_2, s2_3; + s2_0 = s2_1 = s2_2 = s2_3 = vdupq_n_u16(0); + + uint16x8_t s2_4, s2_5, s2_6, s2_7; + s2_4 = s2_5 = s2_6 = s2_7 = vdupq_n_u16(0); + + size_t num_iter = len >> 2; + int rem = len & 3; + + for (size_t i = 0; i < num_iter; ++i) { + uint8x16x4_t d0_d3 = vld1q_u8_x4(buf); + + /* Unfortunately it doesn't look like there's a direct sum 8 bit to 32 + * bit instruction, we'll have to make due summing to 16 bits first */ + uint16x8x2_t hsum, hsum_fold; + hsum.val[0] = vpaddlq_u8(d0_d3.val[0]); + hsum.val[1] = vpaddlq_u8(d0_d3.val[1]); + + hsum_fold.val[0] = vpadalq_u8(hsum.val[0], d0_d3.val[2]); + hsum_fold.val[1] = vpadalq_u8(hsum.val[1], d0_d3.val[3]); + + adacc = vpadalq_u16(adacc, hsum_fold.val[0]); + s3acc = vaddq_u32(s3acc, adacc_prev); + adacc = vpadalq_u16(adacc, hsum_fold.val[1]); + + /* If we do straight widening additions to the 16 bit values, we don't incur + * the usual penalties of a pairwise add. We can defer the multiplications + * until the very end. These will not overflow because we are incurring at + * most 408 loop iterations (NMAX / 64), and a given lane is only going to be + * summed into once. This means for the maximum input size, the largest value + * we will see is 255 * 102 = 26010, safely under uint16 max */ + s2_0 = vaddw_u8(s2_0, vget_low_u8(d0_d3.val[0])); + s2_1 = vaddw_high_u8(s2_1, d0_d3.val[0]); + s2_2 = vaddw_u8(s2_2, vget_low_u8(d0_d3.val[1])); + s2_3 = vaddw_high_u8(s2_3, d0_d3.val[1]); + s2_4 = vaddw_u8(s2_4, vget_low_u8(d0_d3.val[2])); + s2_5 = vaddw_high_u8(s2_5, d0_d3.val[2]); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0_d3.val[3])); + s2_7 = vaddw_high_u8(s2_7, d0_d3.val[3]); + + adacc_prev = adacc; + buf += 64; + } + + s3acc = vshlq_n_u32(s3acc, 6); + + if (rem) { + uint32x4_t s3acc_0 = vdupq_n_u32(0); + while (rem--) { + uint8x16_t d0 = vld1q_u8(buf); + uint16x8_t adler; + adler = vpaddlq_u8(d0); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0)); + s2_7 = vaddw_high_u8(s2_7, d0); + adacc = vpadalq_u16(adacc, adler); + s3acc_0 = vaddq_u32(s3acc_0, adacc_prev); + adacc_prev = adacc; + buf += 16; + } + + s3acc_0 = vshlq_n_u32(s3acc_0, 4); + s3acc = vaddq_u32(s3acc_0, s3acc); + } + + uint16x8x4_t t0_t3 = vld1q_u16_x4(taps); + uint16x8x4_t t4_t7 = vld1q_u16_x4(taps + 32); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[0], s2_0); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[0]), vget_low_u16(s2_0)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[1], s2_1); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[1]), vget_low_u16(s2_1)); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[2], s2_2); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[2]), vget_low_u16(s2_2)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[3], s2_3); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[3]), vget_low_u16(s2_3)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[0], s2_4); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[0]), vget_low_u16(s2_4)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[1], s2_5); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[1]), vget_low_u16(s2_5)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[2], s2_6); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[2]), vget_low_u16(s2_6)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[3], s2_7); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[3]), vget_low_u16(s2_7)); + + s2acc = vaddq_u32(s2acc_0, s2acc); + s2acc_2 = vaddq_u32(s2acc_1, s2acc_2); + s2acc = vaddq_u32(s2acc, s2acc_2); + + uint32x2_t adacc2, s2acc2, as; + s2acc = vaddq_u32(s2acc, s3acc); + adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc)); + s2acc2 = vpadd_u32(vget_low_u32(s2acc), vget_high_u32(s2acc)); + as = vpadd_u32(adacc2, s2acc2); + s[0] = vget_lane_u32(as, 0); + s[1] = vget_lane_u32(as, 1); +} + +static void NEON_handle_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +Z_INTERNAL uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len) { + /* split Adler-32 into component sums */ + uint32_t sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) + return adler32_len_16(adler, buf, len, sum2); + + uint32_t pair[2]; + int n = NMAX; + unsigned int done = 0; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + pair[0] = adler; + pair[1] = sum2; + + /* If memory is not SIMD aligned, do scalar sums to an aligned + * offset, provided that doing so doesn't completely eliminate + * SIMD operation. Aligned loads are still faster on ARM, even + * though there's no explicit aligned load instruction */ + unsigned int align_offset = ((uintptr_t)buf & 15); + unsigned int align_adj = (align_offset) ? 16 - align_offset : 0; + + if (align_offset && len >= (16 + align_adj)) { + NEON_handle_tail(pair, buf, align_adj); + n -= align_adj; + done += align_adj; + + } else { + /* If here, we failed the len criteria test, it wouldn't be + * worthwhile to do scalar aligning sums */ + align_adj = 0; + } + + while (done < len) { + int remaining = (int)(len - done); + n = MIN(remaining, (done == align_adj) ? n : NMAX); + + if (n < 16) + break; + + NEON_accum32(pair, buf + done, n >> 4); + pair[0] %= BASE; + pair[1] %= BASE; + + int actual_nsums = (n >> 4) << 4; + done += actual_nsums; + } + + /* Handle the tail elements. */ + if (done < len) { + NEON_handle_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.c new file mode 100644 index 000000000..7394351fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.c @@ -0,0 +1,82 @@ +#include "../../zbuild.h" +#include "arm_features.h" + +#if defined(__linux__) && defined(HAVE_SYS_AUXV_H) +# include +# ifdef ARM_ASM_HWCAP +# include +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) +# include +# ifndef ID_AA64ISAR0_CRC32_VAL +# define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32 +# endif +#elif defined(__APPLE__) +# if !defined(_DARWIN_C_SOURCE) +# define _DARWIN_C_SOURCE /* enable types aliases (eg u_int) */ +# endif +# include +#elif defined(_WIN32) +# include +#endif + +static int arm_has_crc32() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_CRC32) +# ifdef HWCAP_CRC32 + return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) + return getenv("QEMU_EMULATING") == NULL + && ID_AA64ISAR0_CRC32_VAL(READ_SPECIALREG(id_aa64isar0_el1)) >= ID_AA64ISAR0_CRC32_BASE; +#elif defined(__APPLE__) + int hascrc32; + size_t size = sizeof(hascrc32); + return sysctlbyname("hw.optional.armv8_crc32", &hascrc32, &size, NULL, 0) == 0 + && hascrc32 == 1; +#elif defined(_WIN32) + return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); +#elif defined(ARM_NOCHECK_ACLE) + return 1; +#else + return 0; +#endif +} + +/* AArch64 has neon. */ +#if !defined(__aarch64__) && !defined(_M_ARM64) +static inline int arm_has_neon() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) +# ifdef HWCAP_ARM_NEON + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# endif +#elif defined(__APPLE__) + int hasneon; + size_t size = sizeof(hasneon); + return sysctlbyname("hw.optional.neon", &hasneon, &size, NULL, 0) == 0 + && hasneon == 1; +#elif defined(_M_ARM) && defined(WINAPI_FAMILY_PARTITION) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + return 1; /* Always supported */ +# endif +#endif + +#if defined(ARM_NOCHECK_NEON) + return 1; +#else + return 0; +#endif +} +#endif + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features) { +#if defined(__aarch64__) || defined(_M_ARM64) + features->has_neon = 1; /* always available */ +#else + features->has_neon = arm_has_neon(); +#endif + features->has_crc32 = arm_has_crc32(); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.h new file mode 100644 index 000000000..6fcd8d3eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/arm_features.h @@ -0,0 +1,15 @@ +/* arm_features.h -- check for ARM features. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ARM_H_ +#define ARM_H_ + +struct arm_cpu_features { + int has_neon; + int has_crc32; +}; + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features); + +#endif /* ARM_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/chunkset_neon.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/chunkset_neon.c new file mode 100644 index 000000000..1890c9135 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/chunkset_neon.c @@ -0,0 +1,101 @@ +/* chunkset_neon.c -- NEON inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../generic/chunk_permute_table.h" + +typedef uint8x16_t chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u16(vdupq_n_u16(tmp)); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u32(vdupq_n_u32(tmp)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u64(vdupq_n_u64(tmp)); +} + +#define CHUNKSIZE chunksize_neon +#define CHUNKCOPY chunkcopy_neon +#define CHUNKUNROLL chunkunroll_neon +#define CHUNKMEMSET chunkmemset_neon +#define CHUNKMEMSET_SAFE chunkmemset_safe_neon + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vld1q_u8(s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vst1q_u8(out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + + /* This version of table is only available on aarch64 */ +#if defined(_M_ARM64) || defined(__aarch64__) + uint8x16_t ret_vec = vld1q_u8(buf); + + uint8x16_t perm_vec = vld1q_u8(permute_table + lut_rem.idx); + return vqtbl1q_u8(ret_vec, perm_vec); +#else + uint8x8_t ret0, ret1, a, b, perm_vec0, perm_vec1; + perm_vec0 = vld1_u8(permute_table + lut_rem.idx); + perm_vec1 = vld1_u8(permute_table + lut_rem.idx + 8); + a = vld1_u8(buf); + b = vld1_u8(buf + 8); + ret0 = vtbl1_u8(a, perm_vec0); + uint8x8x2_t ab = {{a, b}}; + ret1 = vtbl2_u8(ab, perm_vec1); + return vcombine_u8(ret0, ret1); +#endif +} + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_neon + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/compare256_neon.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/compare256_neon.c new file mode 100644 index 000000000..7daeba411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/compare256_neon.c @@ -0,0 +1,59 @@ +/* compare256_neon.c - NEON version of compare256 + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +#include "neon_intrins.h" + +static inline uint32_t compare256_neon_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint8x16_t a, b, cmp; + uint64_t lane; + + a = vld1q_u8(src0); + b = vld1q_u8(src1); + + cmp = veorq_u8(a, b); + + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 0); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 1); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + + src0 += 16, src1 += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1) { + return compare256_neon_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/crc32_acle.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/crc32_acle.c new file mode 100644 index 000000000..a4e54d718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/crc32_acle.c @@ -0,0 +1,98 @@ +/* crc32_acle.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2016 Yang Zhang + * For conditions of distribution and use, see copyright notice in zlib.h + * +*/ + +#ifdef ARM_ACLE +#ifdef _MSC_VER +# include +#else +# include +#endif +#include "../../zbuild.h" + +Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + Z_REGISTER const uint16_t *buf2; + Z_REGISTER const uint32_t *buf4; + + c = ~crc; + if (len && ((ptrdiff_t)buf & 1)) { + c = __crc32b(c, *buf++); + len--; + } + + if ((len >= sizeof(uint16_t)) && ((ptrdiff_t)buf & sizeof(uint16_t))) { + buf2 = (const uint16_t *) buf; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf4 = (const uint32_t *) buf2; + } else { + buf4 = (const uint32_t *) buf; + } + +#if defined(__aarch64__) || defined(_M_ARM64) + if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len == 0) { + c = ~c; + return c; + } + + const uint64_t *buf8 = (const uint64_t *) buf4; + + while (len >= sizeof(uint64_t)) { + c = __crc32d(c, *buf8++); + len -= sizeof(uint64_t); + } + + if (len >= sizeof(uint32_t)) { + buf4 = (const uint32_t *) buf8; + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + buf2 = (const uint16_t *) buf4; + } else { + buf2 = (const uint16_t *) buf8; + } + + if (len >= sizeof(uint16_t)) { + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + } + + buf = (const unsigned char *) buf2; +#else /* __aarch64__ */ + + if (len == 0) { + c = ~c; + return c; + } + + while (len >= sizeof(uint32_t)) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len >= sizeof(uint16_t)) { + buf2 = (const uint16_t *) buf4; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf = (const unsigned char *) buf2; + } else { + buf = (const unsigned char *) buf4; + } +#endif /* __aarch64__ */ + + if (len) { + c = __crc32b(c, *buf); + } + + c = ~c; + return c; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/insert_string_acle.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/insert_string_acle.c new file mode 100644 index 000000000..9ac3ccb42 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/insert_string_acle.c @@ -0,0 +1,26 @@ +/* insert_string_acle.c -- insert_string integer hash variant using ACLE's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifdef ARM_ACLE +#ifndef _MSC_VER +# include +#endif +#include "../../zbuild.h" +#include "../../deflate.h" + +#define HASH_CALC(s, h, val) \ + h = __crc32w(0, val) + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_acle +#define INSERT_STRING insert_string_acle +#define QUICK_INSERT_STRING quick_insert_string_acle + +#include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/neon_intrins.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/neon_intrins.h new file mode 100644 index 000000000..d6b57f641 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/neon_intrins.h @@ -0,0 +1,57 @@ +#ifndef ARM_NEON_INTRINS_H +#define ARM_NEON_INTRINS_H + +#ifdef _M_ARM64 +# include +#else +# include +#endif + +#if defined(ARM_NEON) && !defined(__aarch64__) && !defined(_M_ARM64) +/* Compatibility shim for the _high family of functions */ +#define vmull_high_u8(a, b) vmull_u8(vget_high_u8(a), vget_high_u8(b)) +#define vmlal_high_u8(a, b, c) vmlal_u8(a, vget_high_u8(b), vget_high_u8(c)) +#define vmlal_high_u16(a, b, c) vmlal_u16(a, vget_high_u16(b), vget_high_u16(c)) +#define vaddw_high_u8(a, b) vaddw_u8(a, vget_high_u8(b)) +#endif + +#ifdef ARM_NEON + +#define vqsubq_u16_x4_x1(out, a, b) do { \ + out.val[0] = vqsubq_u16(a.val[0], b); \ + out.val[1] = vqsubq_u16(a.val[1], b); \ + out.val[2] = vqsubq_u16(a.val[2], b); \ + out.val[3] = vqsubq_u16(a.val[3], b); \ +} while (0) + + +# ifndef ARM_NEON_HASLD4 + +static inline uint16x8x4_t vld1q_u16_x4(uint16_t const *a) { + uint16x8x4_t ret = (uint16x8x4_t) {{ + vld1q_u16(a), + vld1q_u16(a+8), + vld1q_u16(a+16), + vld1q_u16(a+24)}}; + return ret; +} + +static inline uint8x16x4_t vld1q_u8_x4(uint8_t const *a) { + uint8x16x4_t ret = (uint8x16x4_t) {{ + vld1q_u8(a), + vld1q_u8(a+16), + vld1q_u8(a+32), + vld1q_u8(a+48)}}; + return ret; +} + +static inline void vst1q_u16_x4(uint16_t *p, uint16x8x4_t a) { + vst1q_u16(p, a.val[0]); + vst1q_u16(p + 8, a.val[1]); + vst1q_u16(p + 16, a.val[2]); + vst1q_u16(p + 24, a.val[3]); +} +# endif // HASLD4 check +#endif + +#endif // include guard ARM_NEON_INTRINS_H diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/slide_hash_neon.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/slide_hash_neon.c new file mode 100644 index 000000000..a96ca1179 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/arm/slide_hash_neon.c @@ -0,0 +1,46 @@ +/* slide_hash_neon.c -- Optimized hash table shifting for ARM with support for NEON instructions + * Copyright (C) 2017-2020 Mika T. Lindqvist + * + * Authors: + * Mika T. Lindqvist + * Jun He + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../deflate.h" + +/* SIMD version of hash_chain rebase */ +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + Z_REGISTER uint16x8_t v; + uint16x8x4_t p0, p1; + Z_REGISTER size_t n; + + size_t size = entries*sizeof(table[0]); + Assert((size % sizeof(uint16x8_t) * 8 == 0), "hash table size err"); + + Assert(sizeof(Pos) == 2, "Wrong Pos size"); + v = vdupq_n_u16(wsize); + + n = size / (sizeof(uint16x8_t) * 8); + do { + p0 = vld1q_u16_x4(table); + p1 = vld1q_u16_x4(table+32); + vqsubq_u16_x4_x1(p0, p0, v); + vqsubq_u16_x4_x1(p1, p1, v); + vst1q_u16_x4(table, p0); + vst1q_u16_x4(table+32, p1); + table += 64; + } while (--n); +} + +Z_INTERNAL void slide_hash_neon(deflate_state *s) { + unsigned int wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/Makefile.in new file mode 100644 index 000000000..be8c18545 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/Makefile.in @@ -0,0 +1,21 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: + + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + rm -rf objs + rm -f *.gcda *.gcno *.gcov diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/chunk_permute_table.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/chunk_permute_table.h new file mode 100644 index 000000000..bad66ccc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/generic/chunk_permute_table.h @@ -0,0 +1,53 @@ +/* chunk_permute_table.h - shared AVX/SSSE3 permutation table for use with chunkmemset family of functions. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CHUNK_PERMUTE_TABLE_H_ +#define CHUNK_PERMUTE_TABLE_H_ + +#include "zbuild.h" + +/* Need entries for all numbers not an even modulus for 1, 2, 4, 8, 16 & 32 */ +static const ALIGNED_(32) uint8_t permute_table[26*32] = { + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, /* dist 3 */ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, /* dist 5 */ + 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, /* dist 6 */ + 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, /* dist 7 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, /* dist 9 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, /* dist 10 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 11 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 12 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, /* dist 13 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, /* dist 14 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, /* dist 15 */ + + /* Beyond dists of 15 means we have to permute from a vector > len(m128i). Because AVX couldn't permute + * beyond 128 bit lanes until AVX512 for sub 4-byte sequences, we have to do some math here for an eventual + * blend with a comparison. That means we need to wrap the indices with yet another derived table. For simplicity, + * we'll use absolute indexing here to derive a blend vector. This is actually a lot simpler with ARM's TBL, but, + * this is what we're dealt. + */ + + 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* dist 17 */ + 16, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, /* dist 18 */ + 16, 17, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, /* dist 19 */ + 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* dist 20 */ + 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, /* dist 21 */ + 16, 17, 18, 19, 20, 21, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 22 */ + 16, 17, 18, 19, 20, 21, 22, 0, 1, 2, 3, 4, 5, 6, 7, 8, /* dist 23 */ + 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 24 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4, 5, 6, /* dist 25 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 1, 2, 3, 4, 5, /* dist 26 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 1, 2, 3, 4, /* dist 27 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3, /* dist 28 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, 1, 2, /* dist 29 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 1, /* dist 30 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, /* dist 31 */ +}; + +typedef struct lut_rem_pair_s { + uint16_t idx; + uint16_t remval; +} lut_rem_pair; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/Makefile.in new file mode 100644 index 000000000..e9be6dddb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/Makefile.in @@ -0,0 +1,93 @@ +# Makefile for POWER-specific files +# Copyright (C) 2020 Matheus Castanho , IBM +# Copyright (C) 2021 Mika T. Lindqvist +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +P8FLAGS=-mcpu=power8 +P9FLAGS=-mcpu=power9 +PPCFLAGS=-maltivec +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: power_features.o \ + power_features.lo \ + adler32_power8.o \ + adler32_power8.lo \ + adler32_vmx.o \ + adler32_vmx.lo \ + chunkset_power8.o \ + chunkset_power8.lo \ + compare256_power9.o \ + compare256_power9.lo \ + crc32_power8.o \ + crc32_power8.lo \ + slide_hash_power8.o \ + slide_hash_power8.lo \ + slide_hash_vmx.o \ + slide_hash_vmx.lo + +power_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +power_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +adler32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_vmx.o: + $(CC) $(CFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +adler32_vmx.lo: + $(CC) $(SFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +chunkset_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +chunkset_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +compare256_power9.o: + $(CC) $(CFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +compare256_power9.lo: + $(CC) $(SFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +crc32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +crc32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +slide_hash_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_vmx.o: + $(CC) $(CFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +slide_hash_vmx.lo: + $(CC) $(SFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_power8.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_power8.c new file mode 100644 index 000000000..4aaea9f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_power8.c @@ -0,0 +1,153 @@ +/* Adler32 for POWER8 using VSX instructions. + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate adler32 checksum for 16 bytes at once using POWER8+ VSX (vector) + * instructions. + * + * If adler32 do 1 byte at time on the first iteration s1 is s1_0 (_n means + * iteration n) is the initial value of adler - at start _0 is 1 unless + * adler initial value is different than 1. So s1_1 = s1_0 + c[0] after + * the first calculation. For the iteration s1_2 = s1_1 + c[1] and so on. + * Hence, for iteration N, s1_N = s1_(N-1) + c[N] is the value of s1 on + * after iteration N. + * + * Therefore, for s2 and iteration N, s2_N = s2_0 + N*s1_N + N*c[0] + + * N-1*c[1] + ... + c[N] + * + * In a more general way: + * + * s1_N = s1_0 + sum(i=1 to N)c[i] + * s2_N = s2_0 + N*s1 + sum (i=1 to N)(N-i+1)*c[i] + * + * Where s1_N, s2_N are the values for s1, s2 after N iterations. So if we + * can process N-bit at time we can do this at once. + * + * Since VSX can support 16-bit vector instructions, we can process + * 16-bit at time using N = 16 we have: + * + * s1 = s1_16 = s1_(16-1) + c[16] = s1_0 + sum(i=1 to 16)c[i] + * s2 = s2_16 = s2_0 + 16*s1 + sum(i=1 to 16)(16-i+1)*c[i] + * + * After the first iteration we calculate the adler32 checksum for 16 bytes. + * + * For more background about adler32 please check the RFC: + * https://www.ietf.org/rfc/rfc1950.txt + */ + +#ifdef POWER8_VSX + +#include +#include "zbuild.h" +#include "adler32_p.h" + +/* Vector across sum unsigned int (saturate). */ +static inline vector unsigned int vec_sumsu(vector unsigned int __a, vector unsigned int __b) { + __b = vec_sld(__a, __a, 8); + __b = vec_add(__b, __a); + __a = vec_sld(__b, __b, 4); + __a = vec_add(__a, __b); + + return __a; +} + +Z_INTERNAL uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(s1, buf, s2); + + /* If buffer is empty or len=0 we need to return adler initial value. */ + if (UNLIKELY(buf == NULL)) + return 1; + + /* This is faster than VSX code for len < 64. */ + if (len < 64) + return adler32_len_64(s1, buf, len, s2); + + /* Use POWER VSX instructions for len >= 64. */ + const vector unsigned int v_zeros = { 0 }; + const vector unsigned char v_mul = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, + 6, 5, 4, 3, 2, 1}; + const vector unsigned char vsh = vec_splat_u8(4); + const vector unsigned int vmask = {0xffffffff, 0x0, 0x0, 0x0}; + vector unsigned int vs1 = { 0 }; + vector unsigned int vs2 = { 0 }; + vector unsigned int vs1_save = { 0 }; + vector unsigned int vsum1, vsum2; + vector unsigned char vbuf; + int n; + + vs1[0] = s1; + vs2[0] = s2; + + /* Do length bigger than NMAX in blocks of NMAX size. */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; + do { + vbuf = vec_xl(0, (unsigned char *) buf); + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } while (--n); + /* Once each block of NMAX size. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + + /* vs1[0] = (s1_i + sum(i=1 to 16)buf[i]) mod 65521. */ + vs1[0] = vs1[0] % BASE; + /* vs2[0] = s2_i + 16*s1_save + + sum(i=1 to 16)(16-i+1)*buf[i] mod 65521. */ + vs2[0] = vs2[0] % BASE; + + vs1 = vec_and(vs1, vmask); + vs2 = vec_and(vs2, vmask); + vs1_save = v_zeros; + } + + /* len is less than NMAX one modulo is needed. */ + if (len >= 16) { + while (len >= 16) { + len -= 16; + + vbuf = vec_xl(0, (unsigned char *) buf); + + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } + /* Since the size will be always less than NMAX we do this once. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + } + /* Copy result back to s1, s2 (mod 65521). */ + s1 = vs1[0] % BASE; + s2 = vs2[0] % BASE; + + /* Process tail (len < 16). */ + return adler32_len_16(s1, buf, len, s2); +} + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_vmx.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_vmx.c new file mode 100644 index 000000000..ef1649b58 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/adler32_vmx.c @@ -0,0 +1,181 @@ +/* adler32_vmx.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 2017-2021 Mika T. Lindqvist + * Copyright (C) 2021 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef PPC_VMX +#include +#include "zbuild.h" +#include "adler32_p.h" + +#define vmx_zero() (vec_splat_u32(0)) + +static inline void vmx_handle_head_or_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +static void vmx_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + /* Different taps for the separable components of sums */ + const vector unsigned char t0 = {64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49}; + const vector unsigned char t1 = {48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33}; + const vector unsigned char t2 = {32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17}; + const vector unsigned char t3 = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + /* As silly and inefficient as it seems, creating 1 permutation vector to permute + * a 2 element vector from a single load + a subsequent shift is just barely faster + * than doing 2 indexed insertions into zero initialized vectors from unaligned memory. */ + const vector unsigned char s0_perm = {0, 1, 2, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + const vector unsigned char shift_vec = vec_sl(vec_splat_u8(8), vec_splat_u8(2)); + vector unsigned int adacc, s2acc; + vector unsigned int pair_vec = vec_ld(0, s); + adacc = vec_perm(pair_vec, pair_vec, s0_perm); + s2acc = vec_slo(pair_vec, shift_vec); + + vector unsigned int zero = vmx_zero(); + vector unsigned int s3acc = zero; + vector unsigned int s3acc_0 = zero; + vector unsigned int adacc_prev = adacc; + vector unsigned int adacc_prev_0 = zero; + + vector unsigned int s2acc_0 = zero; + vector unsigned int s2acc_1 = zero; + vector unsigned int s2acc_2 = zero; + + /* Maintain a running sum of a second half, this might help use break yet another + * data dependency bubble in the sum */ + vector unsigned int adacc_0 = zero; + + int num_iter = len / 4; + int rem = len & 3; + + for (int i = 0; i < num_iter; ++i) { + vector unsigned char d0 = vec_ld(0, buf); + vector unsigned char d1 = vec_ld(16, buf); + vector unsigned char d2 = vec_ld(32, buf); + vector unsigned char d3 = vec_ld(48, buf); + + /* The core operation of the loop, basically + * what is being unrolled below */ + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s3acc_0 = vec_add(s3acc_0, adacc_prev_0); + s2acc = vec_msum(t0, d0, s2acc); + + /* interleave dependent sums in here */ + adacc_0 = vec_sum4s(d1, adacc_0); + s2acc_0 = vec_msum(t1, d1, s2acc_0); + adacc = vec_sum4s(d2, adacc); + s2acc_1 = vec_msum(t2, d2, s2acc_1); + s2acc_2 = vec_msum(t3, d3, s2acc_2); + adacc_0 = vec_sum4s(d3, adacc_0); + + adacc_prev = adacc; + adacc_prev_0 = adacc_0; + buf += 64; + } + + adacc = vec_add(adacc, adacc_0); + s3acc = vec_add(s3acc, s3acc_0); + s3acc = vec_sl(s3acc, vec_splat_u32(6)); + + if (rem) { + adacc_prev = vec_add(adacc_prev_0, adacc_prev); + adacc_prev = vec_sl(adacc_prev, vec_splat_u32(4)); + while (rem--) { + vector unsigned char d0 = vec_ld(0, buf); + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s2acc = vec_msum(t3, d0, s2acc); + adacc_prev = vec_sl(adacc, vec_splat_u32(4)); + buf += 16; + } + } + + + /* Sum up independent second sums */ + s2acc = vec_add(s2acc, s2acc_0); + s2acc_2 = vec_add(s2acc_1, s2acc_2); + s2acc = vec_add(s2acc, s2acc_2); + + s2acc = vec_add(s2acc, s3acc); + + adacc = vec_add(adacc, vec_sld(adacc, adacc, 8)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 8)); + adacc = vec_add(adacc, vec_sld(adacc, adacc, 4)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 4)); + + vec_ste(adacc, 0, s); + vec_ste(s2acc, 0, s+1); +} + +Z_INTERNAL uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + uint32_t pair[16] ALIGNED_(16); + memset(&pair[2], 0, 14); + int n = NMAX; + unsigned int done = 0, i; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + pair[0] = adler; + pair[1] = sum2; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + // Align buffer + unsigned int al = 0; + if ((uintptr_t)buf & 0xf) { + al = 16-((uintptr_t)buf & 0xf); + if (al > len) { + al=len; + } + vmx_handle_head_or_tail(pair, buf, al); + + done += al; + /* Rather than rebasing, we can reduce the max sums for the + * first round only */ + n -= al; + } + for (i = al; i < len; i += n) { + int remaining = (int)(len-i); + n = MIN(remaining, (i == al) ? n : NMAX); + + if (n < 16) + break; + + vmx_accum32(pair, buf + i, n / 16); + pair[0] %= BASE; + pair[1] %= BASE; + + done += (n / 16) * 16; + } + + /* Handle the tail elements. */ + if (done < len) { + vmx_handle_head_or_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/chunkset_power8.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/chunkset_power8.c new file mode 100644 index 000000000..443aae92f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/chunkset_power8.c @@ -0,0 +1,55 @@ +/* chunkset_power8.c -- VSX inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX +#include +#include "../../zbuild.h" + +typedef vector unsigned char chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vec_xl(0, s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vec_xst(*chunk, 0, out); +} + +#define CHUNKSIZE chunksize_power8 +#define CHUNKCOPY chunkcopy_power8 +#define CHUNKUNROLL chunkunroll_power8 +#define CHUNKMEMSET chunkmemset_power8 +#define CHUNKMEMSET_SAFE chunkmemset_safe_power8 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_power8 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/compare256_power9.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/compare256_power9.c new file mode 100644 index 000000000..9b3e61701 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/compare256_power9.c @@ -0,0 +1,66 @@ +/* compare256_power9.c - Power9 version of compare256 + * Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER9 +#include +#include "../../zbuild.h" +#include "../../zendian.h" + +/* Older versions of GCC misimplemented semantics for these bit counting builtins. + * https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=3f30f2d1dbb3228b8468b26239fe60c2974ce2ac */ +#if defined(__GNUC__) && (__GNUC__ < 12) +# define zng_vec_vctzlsbb(vc, len) __asm__ volatile("vctzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +# define zng_vec_vclzlsbb(vc, len) __asm__ volatile("vclzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +#else +# define zng_vec_vctzlsbb(vc, len) len = __builtin_vec_vctzlsbb(vc) +# define zng_vec_vclzlsbb(vc, len) len = __builtin_vec_vclzlsbb(vc) +#endif + +static inline uint32_t compare256_power9_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0, cmplen; + + do { + vector unsigned char vsrc0, vsrc1, vc; + + vsrc0 = *((vector unsigned char *)src0); + vsrc1 = *((vector unsigned char *)src1); + + /* Compare 16 bytes at a time. Each byte of vc will be either + * all ones or all zeroes, depending on the result of the comparison. */ + vc = (vector unsigned char)vec_cmpne(vsrc0, vsrc1); + + /* Since the index of matching bytes will contain only zeroes + * on vc (since we used cmpne), counting the number of consecutive + * bytes where LSB == 0 is the same as counting the length of the match. */ +#if BYTE_ORDER == LITTLE_ENDIAN + zng_vec_vctzlsbb(vc, cmplen); +#else + zng_vec_vclzlsbb(vc, cmplen); +#endif + if (cmplen != 16) + return len + cmplen; + + src0 += 16, src1 += 16, len += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1) { + return compare256_power9_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_constants.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_constants.h new file mode 100644 index 000000000..8c8f2153b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_constants.h @@ -0,0 +1,1123 @@ +/* Constants table used by crc32_power8.c + * Copyright (C) 2021 IBM Corporation + * + * This file was automatically generated, DO NOT EDIT IT MANUALLY. + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zendian.h" +#include "zbuild.h" + +/* Reduce 262144 kbits to 1024 bits */ +static const __vector unsigned long long vcrc_const[255] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x0000000099ea94a8, 0x00000001651797d2 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x00000000945a8420, 0x0000000021e0d56c }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x0000000030762706, 0x000000000f95ecaa }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001a52fc582, 0x00000001ebd224ac }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x00000001a4a7167a, 0x000000000ccb97ca }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x000000000c18249a, 0x00000001006ec8a8 }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x00000000a924ae7c, 0x000000014f58f196 }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001e12ccc12, 0x00000001a7192ca6 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x00000000a0b9d4ac, 0x000000019a64bab2 }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000095e8ddfe, 0x0000000014f4ed2e }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x00000000233fddc4, 0x000000011092b6a2 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000001b4529b62, 0x00000000c8a1629c }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x00000001a7fa0e64, 0x000000017bf32e8e }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001b5334592, 0x00000001f8cc6582 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000011f8ee1b4, 0x000000008631ddf0 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000006252e632, 0x000000007e5a76d0 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x00000000ab973e84, 0x000000002b09b31c }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x000000007734f5ec, 0x00000001b2df1f84 }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x000000007c547798, 0x00000001d6f56afc }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x000000007ec40210, 0x00000001b9b5e70c }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x00000001ab1695a8, 0x0000000034b626d2 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x0000000090494bba, 0x000000014c53479a }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001123fb816, 0x00000001a6d179a4 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x00000001e188c74c, 0x000000015abd16b4 }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000001c2d3451c, 0x00000000018f9852 }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x00000000f55cf1ca, 0x000000001fb3084a }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000001a0531540, 0x00000000c53dfb04 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x0000000132cd7ebc, 0x00000000e10c9ad6 }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000073ab7f36, 0x0000000025aa994a }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x0000000041aed1c2, 0x00000000fa3a74c4 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000136c53800, 0x0000000033eb3f40 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x0000000126835a30, 0x000000017193f296 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x000000006241b502, 0x0000000043f6c86a }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x00000000d5196ad4, 0x000000016b513ec6 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x000000009cfa769a, 0x00000000c8f25b4e }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000000920e5df4, 0x00000001a45048ec }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x0000000169dc310e, 0x000000000c441004 }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x0000000009fc331c, 0x000000000e17cad6 }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x000000010d94a81e, 0x00000001253ae964 }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x0000000027a20ab2, 0x00000001d7c88ebc }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x0000000114f87504, 0x00000001e7ca913a }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x000000004b076d96, 0x0000000033ed078a }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000da4d1e74, 0x00000000e1839c78 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x000000001b81f672, 0x00000001322b267e }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x000000009367c988, 0x00000000638231b6 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001717214ca, 0x00000001ee7f16f4 }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x000000009f47d820, 0x0000000117d9924a }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x000000010d9a47d2, 0x00000000e1a9e0c4 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000000a696c58c, 0x00000001403731dc }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x000000002aa28ec6, 0x00000001a5ea9682 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x00000001fe18fd9a, 0x0000000101c5c578 }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x000000019d4fc1ae, 0x00000000dddf6494 }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000001ba0e3dea, 0x00000000f1c3db28 }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x0000000074b59a5e, 0x000000013112fb9c }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000f2b5ea98, 0x00000000b680b906 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x0000000187132676, 0x000000001a282932 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x000000010a8c6ad4, 0x0000000089406e7e }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001e21dfe70, 0x00000001def6be8c }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x00000001da0050e4, 0x0000000075258728 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x00000000772172ae, 0x000000019536090a }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000e47724aa, 0x00000000f2455bfc }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000003cd63ac4, 0x000000018c40baf4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x00000001bf47d352, 0x000000004cd390d4 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x000000018dc1d708, 0x00000001e4ece95a }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000002d4620a4, 0x000000001a3ee918 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x0000000058fd1740, 0x000000007c652fb8 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x00000000dadd9bfc, 0x000000011c67842c }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000001ea2140be, 0x00000000254f759c }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000009de128ba, 0x000000007ece94ca }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x000000013ac3aa8e, 0x0000000038f258c2 }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x0000000099980562, 0x00000001cdf17b00 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x00000001c1579c86, 0x000000011f882c16 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000068dbbf94, 0x0000000100093fc8 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x000000004509fb04, 0x00000001cd684f16 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x00000001202f6398, 0x000000004bc6a70a }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000013aea243e, 0x000000004fc7e8e4 }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x00000001b4052ae6, 0x0000000130103f1c }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x00000001cd2a0ae8, 0x0000000111b0024c }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x00000001fe4aa8b4, 0x000000010b3079da }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x00000001d1559a42, 0x000000010192bcc2 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x00000001f3e05ecc, 0x0000000074838d50 }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x0000000104ddd2cc, 0x000000001b20f520 }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x000000015393153c, 0x0000000050c3590a }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x0000000057e942c6, 0x00000000b41cac8e }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000012c633850, 0x000000000c72cc78 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x00000000ebcaae4c, 0x0000000030cdb032 }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013ee532a6, 0x000000013e09fc32 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x00000001bf0cbc7e, 0x000000001ed624d2 }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000d50b7a5a, 0x00000000781aee1a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x0000000002fca6e8, 0x00000001c4d8348c }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x000000007af40044, 0x0000000057a40336 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000016178744, 0x0000000085544940 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000014c177458, 0x000000019cd21e80 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000011b6ddf04, 0x000000013eb95bc0 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001f3e29ccc, 0x00000001dfc9fdfc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x0000000135ae7562, 0x00000000cd028bc2 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000190ef812c, 0x0000000090db8c44 }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x0000000067a2c786, 0x000000010010a4ce }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x0000000048b9496c, 0x00000001c8f4c72c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000015a422de6, 0x000000001c26170c }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000001ef0e3640, 0x00000000e3fccf68 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000001006d2d26, 0x00000000d513ed24 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000001170d56d6, 0x00000000141beada }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x00000000a5fb613c, 0x000000011071aea0 }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x0000000040bbf7fc, 0x000000012e19080a }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x000000016ac3a5b2, 0x0000000100ecf826 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x00000000abf16230, 0x0000000069b09412 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x00000001ebe23fac, 0x0000000122297bac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x000000008b6a0894, 0x00000000e9e4b068 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x00000001288ea478, 0x000000004b38651a }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x000000016619c442, 0x00000001468360e2 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x0000000086230038, 0x00000000121c2408 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x000000017746a756, 0x00000000da7e7d08 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x0000000191b8f8f8, 0x00000001058d7652 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000008e167708, 0x000000014a098a90 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000148b22d54, 0x0000000020dbe72e }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x0000000044ba2c3c, 0x000000011e7323e8 }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000b54d2b52, 0x00000000d5d4bf94 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000005a4fd8a, 0x0000000199d8746c }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x0000000139f9fc46, 0x00000000ce9ca8a0 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x000000015a1fa824, 0x00000000136edece }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000000a61ae4c, 0x000000019b92a068 }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000145e9113e, 0x0000000071d62206 }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x000000006a348448, 0x00000000dfc50158 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x000000004d80a08c, 0x00000001517626bc }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x000000014b6837a0, 0x0000000148d1e4fa }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x000000016896a7fc, 0x0000000094d8266e }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x000000014f187140, 0x00000000606c5e34 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019581b9da, 0x000000019766beaa }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001091bc984, 0x00000001d80c506c }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001067223c, 0x000000001e73837c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x00000001ab16ea02, 0x0000000064d587de }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x000000013c4598a8, 0x00000000f4a507b0 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x00000000b3735430, 0x0000000040e342fc }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001bb3fc0c0, 0x00000001d5ad9c3a }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x00000001570ae19c, 0x0000000094a691a4 }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001ea910712, 0x00000001271ecdfa }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x0000000167127128, 0x000000009e54475a }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x0000000019e790a2, 0x00000000c9c099ee }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000003788f710, 0x000000009a2f736c }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000001682a160e, 0x00000000bb9f4996 }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x000000007f0ebd2e, 0x00000001db688050 }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x000000002b032080, 0x00000000e9b10af4 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x00000000cfd1664a, 0x000000012d4545e4 }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x00000000aa1181c2, 0x000000000361139c }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000000ddd08002, 0x00000001a5a1a3a8 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x00000000e8dd0446, 0x000000006844e0b0 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000001bbd94a00, 0x00000000c3762f28 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000000ab6cd180, 0x00000001d26287a2 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x0000000031803ce2, 0x00000001f6f0bba8 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x0000000024f40b0c, 0x000000002ffabd62 }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000001ba1d9834, 0x00000000fb4516b8 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x0000000104de61aa, 0x000000018cfa961c }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x0000000113e40d46, 0x000000019e588d52 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001415598a0, 0x00000001180f0bbc }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000bf6c8c90, 0x00000000e1d9177a }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x00000001788b0504, 0x0000000105abc27c }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x0000000038385d02, 0x00000000972e4a58 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x00000001b6c83844, 0x0000000183499a5e }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x0000000051061a8a, 0x00000001c96a8cca }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x000000017351388a, 0x00000001a1a5b60c }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x0000000132928f92, 0x00000000e4b6ac9c }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000000e6b4f48a, 0x00000001807e7f5a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x0000000039d15e90, 0x000000017a7e3bc8 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000312d6074, 0x00000000d73975da }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017bbb2cc4, 0x000000017375d038 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x000000016ded3e18, 0x00000000193680bc }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000f1638b16, 0x00000000999b06f6 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001d38b9ecc, 0x00000001f685d2b8 }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x000000018b8d09dc, 0x00000001f4ecbed2 }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000e7bc27d2, 0x00000000ba16f1a0 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x00000000275e1e96, 0x0000000115aceac4 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000000e2e3031e, 0x00000001aeff6292 }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x00000001041c84d8, 0x000000009640124c }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x00000000706ce672, 0x0000000114f41f02 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000015d5070da, 0x000000009c5f3586 }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x0000000038f9493a, 0x00000001878275fa }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000a3348a76, 0x00000000ddc42ce8 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x00000001ad0aab92, 0x0000000181d2c73a }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x000000019e85f712, 0x0000000141c9320a }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000005a871e76, 0x000000015235719a }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x000000017249c662, 0x00000000be27d804 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000003a084712, 0x000000006242d45a }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x00000000ed438478, 0x000000009a53638e }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000000abac34cc, 0x00000001001ecfb6 }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000005f35ef3e, 0x000000016d7c2d64 }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x0000000047d6608c, 0x00000001d0ce46c0 }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x000000002d01470e, 0x0000000124c907b4 }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000158bbc7b0, 0x0000000018a555ca }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x00000000c0a23e8e, 0x000000006b0980bc }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x00000001ebd85c88, 0x000000008bbba964 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x000000019ee20bb2, 0x00000001070a5a1e }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x00000001acabf2d6, 0x000000002204322a }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000001b7963d56, 0x00000000a27524d0 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x000000017bffa1fe, 0x0000000020b1e4ba }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x000000001f15333e, 0x0000000032cc27fc }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x000000018593129e, 0x0000000044dd22b8 }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x000000019cb32602, 0x00000000dffc9e0a }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x0000000142b05cc8, 0x00000001b7a0ed14 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000001be49e7a4, 0x00000000c7842488 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x0000000108f69d6c, 0x00000001c02a4fee }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000006c0971f0, 0x000000003c273778 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x000000005b16467a, 0x00000001d63f8894 }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x00000001551a628e, 0x000000006be557d6 }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000019e42ea92, 0x000000006a7806ea }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000012fa83ff2, 0x000000016155aa0c }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x000000011ca9cde0, 0x00000000908650ac }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000c8e5cd74, 0x00000000aa5a8084 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000096c27f0c, 0x0000000191bb500a }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x000000002baed926, 0x0000000064e9bed0 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000017c8de8d2, 0x000000009444f302 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x00000000d43d6068, 0x000000019db07d3c }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000000cb2c4b26, 0x00000001359e3e6e }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x0000000145b8da26, 0x00000001e4f10dd2 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x000000018fff4b08, 0x0000000124f5735e }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000150b58ed0, 0x0000000124760a4c }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x00000001549f39bc, 0x000000000f1fc186 }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000ef4d2f42, 0x00000000150e4cc4 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x00000001b1468572, 0x000000002a6204e8 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x000000013d7403b2, 0x00000000beb1d432 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x00000001a4681842, 0x0000000135f3f1f0 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000167714492, 0x0000000074fe2232 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x00000001e599099a, 0x000000001ac6e2ba }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x00000000fe128194, 0x0000000013fca91e }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000077e8b990, 0x0000000183f4931e }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000001a267f63a, 0x00000000b6d9b4e4 }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000001945c245a, 0x00000000b5188656 }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000149002e76, 0x0000000027a81a84 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x00000001bb8310a4, 0x0000000125699258 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x000000019ec60bcc, 0x00000001b23de796 }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x000000012d8590ae, 0x00000000fe4365dc }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x0000000065b00684, 0x00000000c68f497a }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x000000015e5aeadc, 0x00000000fbf521ee }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x00000000b77ff2b0, 0x000000015eac3378 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000188da2ff6, 0x0000000134914b90 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000063da929a, 0x0000000016335cfe }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x00000001389caa80, 0x000000010372d10c }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000013db599d2, 0x000000015097b908 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x0000000122505a86, 0x00000001227a7572 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000016bd72746, 0x000000009a8f75c0 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000001c3faf1d4, 0x00000000682c77a2 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000001111c826c, 0x00000000231f091c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x00000000153e9fb2, 0x000000007d4439f2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000002b1f7b60, 0x000000017e221efc }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x00000000b1dba570, 0x0000000167457c38 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000001f6397b76, 0x00000000bdf081c4 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x0000000156335214, 0x000000016286d6b0 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000001d70e3986, 0x00000000c84f001c }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x000000003701a774, 0x0000000064efe7c0 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x00000000ac81ef72, 0x000000000ac2d904 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x0000000133212464, 0x00000000fd226d14 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x00000000e4e45610, 0x000000011cfd42e0 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000000c1bd370, 0x000000016e5a5678 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001a7b9e7a6, 0x00000001d888fe22 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x000000007d657a10, 0x00000001af77fcd4 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x00000001651797d2, 0x0000000099ea94a8 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x0000000021e0d56c, 0x00000000945a8420 }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x000000000f95ecaa, 0x0000000030762706 }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001ebd224ac, 0x00000001a52fc582 }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x000000000ccb97ca, 0x00000001a4a7167a }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x00000001006ec8a8, 0x000000000c18249a }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x000000014f58f196, 0x00000000a924ae7c }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001a7192ca6, 0x00000001e12ccc12 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x000000019a64bab2, 0x00000000a0b9d4ac }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000014f4ed2e, 0x0000000095e8ddfe }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x000000011092b6a2, 0x00000000233fddc4 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000000c8a1629c, 0x00000001b4529b62 }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x000000017bf32e8e, 0x00000001a7fa0e64 }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001f8cc6582, 0x00000001b5334592 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000008631ddf0, 0x000000011f8ee1b4 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000007e5a76d0, 0x000000006252e632 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x000000002b09b31c, 0x00000000ab973e84 }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x00000001b2df1f84, 0x000000007734f5ec }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x00000001d6f56afc, 0x000000007c547798 }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x00000001b9b5e70c, 0x000000007ec40210 }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x0000000034b626d2, 0x00000001ab1695a8 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x000000014c53479a, 0x0000000090494bba }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001a6d179a4, 0x00000001123fb816 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x000000015abd16b4, 0x00000001e188c74c }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000000018f9852, 0x00000001c2d3451c }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x000000001fb3084a, 0x00000000f55cf1ca }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000000c53dfb04, 0x00000001a0531540 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x00000000e10c9ad6, 0x0000000132cd7ebc }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000025aa994a, 0x0000000073ab7f36 }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x00000000fa3a74c4, 0x0000000041aed1c2 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000033eb3f40, 0x0000000136c53800 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x000000017193f296, 0x0000000126835a30 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x0000000043f6c86a, 0x000000006241b502 }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x000000016b513ec6, 0x00000000d5196ad4 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x00000000c8f25b4e, 0x000000009cfa769a }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000001a45048ec, 0x00000000920e5df4 }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x000000000c441004, 0x0000000169dc310e }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x000000000e17cad6, 0x0000000009fc331c }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x00000001253ae964, 0x000000010d94a81e }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x00000001d7c88ebc, 0x0000000027a20ab2 }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x00000001e7ca913a, 0x0000000114f87504 }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x0000000033ed078a, 0x000000004b076d96 }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000e1839c78, 0x00000000da4d1e74 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x00000001322b267e, 0x000000001b81f672 }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x00000000638231b6, 0x000000009367c988 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001ee7f16f4, 0x00000001717214ca }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x0000000117d9924a, 0x000000009f47d820 }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x00000000e1a9e0c4, 0x000000010d9a47d2 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000001403731dc, 0x00000000a696c58c }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x00000001a5ea9682, 0x000000002aa28ec6 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x0000000101c5c578, 0x00000001fe18fd9a }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x00000000dddf6494, 0x000000019d4fc1ae }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000000f1c3db28, 0x00000001ba0e3dea }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x000000013112fb9c, 0x0000000074b59a5e }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000b680b906, 0x00000000f2b5ea98 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x000000001a282932, 0x0000000187132676 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x0000000089406e7e, 0x000000010a8c6ad4 }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001def6be8c, 0x00000001e21dfe70 }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x0000000075258728, 0x00000001da0050e4 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x000000019536090a, 0x00000000772172ae }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000f2455bfc, 0x00000000e47724aa }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000018c40baf4, 0x000000003cd63ac4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x000000004cd390d4, 0x00000001bf47d352 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x00000001e4ece95a, 0x000000018dc1d708 }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000001a3ee918, 0x000000002d4620a4 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x000000007c652fb8, 0x0000000058fd1740 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x000000011c67842c, 0x00000000dadd9bfc }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000000254f759c, 0x00000001ea2140be }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000007ece94ca, 0x000000009de128ba }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x0000000038f258c2, 0x000000013ac3aa8e }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x00000001cdf17b00, 0x0000000099980562 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x000000011f882c16, 0x00000001c1579c86 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000100093fc8, 0x0000000068dbbf94 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x00000001cd684f16, 0x000000004509fb04 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x000000004bc6a70a, 0x00000001202f6398 }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000004fc7e8e4, 0x000000013aea243e }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x0000000130103f1c, 0x00000001b4052ae6 }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x0000000111b0024c, 0x00000001cd2a0ae8 }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x000000010b3079da, 0x00000001fe4aa8b4 }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x000000010192bcc2, 0x00000001d1559a42 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x0000000074838d50, 0x00000001f3e05ecc }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x000000001b20f520, 0x0000000104ddd2cc }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x0000000050c3590a, 0x000000015393153c }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x00000000b41cac8e, 0x0000000057e942c6 }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000000c72cc78, 0x000000012c633850 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x0000000030cdb032, 0x00000000ebcaae4c }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013e09fc32, 0x000000013ee532a6 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x000000001ed624d2, 0x00000001bf0cbc7e }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000781aee1a, 0x00000000d50b7a5a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x00000001c4d8348c, 0x0000000002fca6e8 }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x0000000057a40336, 0x000000007af40044 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000085544940, 0x0000000016178744 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000019cd21e80, 0x000000014c177458 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000013eb95bc0, 0x000000011b6ddf04 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001dfc9fdfc, 0x00000001f3e29ccc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x00000000cd028bc2, 0x0000000135ae7562 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000090db8c44, 0x0000000190ef812c }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x000000010010a4ce, 0x0000000067a2c786 }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x00000001c8f4c72c, 0x0000000048b9496c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000001c26170c, 0x000000015a422de6 }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000000e3fccf68, 0x00000001ef0e3640 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000000d513ed24, 0x00000001006d2d26 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000000141beada, 0x00000001170d56d6 }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x000000011071aea0, 0x00000000a5fb613c }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x000000012e19080a, 0x0000000040bbf7fc }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x0000000100ecf826, 0x000000016ac3a5b2 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x0000000069b09412, 0x00000000abf16230 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x0000000122297bac, 0x00000001ebe23fac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x00000000e9e4b068, 0x000000008b6a0894 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x000000004b38651a, 0x00000001288ea478 }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x00000001468360e2, 0x000000016619c442 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x00000000121c2408, 0x0000000086230038 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x00000000da7e7d08, 0x000000017746a756 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x00000001058d7652, 0x0000000191b8f8f8 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000014a098a90, 0x000000008e167708 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000020dbe72e, 0x0000000148b22d54 }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x000000011e7323e8, 0x0000000044ba2c3c }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000d5d4bf94, 0x00000000b54d2b52 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000199d8746c, 0x0000000005a4fd8a }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x00000000ce9ca8a0, 0x0000000139f9fc46 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x00000000136edece, 0x000000015a1fa824 }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000019b92a068, 0x000000000a61ae4c }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000071d62206, 0x0000000145e9113e }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x00000000dfc50158, 0x000000006a348448 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x00000001517626bc, 0x000000004d80a08c }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x0000000148d1e4fa, 0x000000014b6837a0 }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x0000000094d8266e, 0x000000016896a7fc }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x00000000606c5e34, 0x000000014f187140 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019766beaa, 0x000000019581b9da }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001d80c506c, 0x00000001091bc984 }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001e73837c, 0x000000001067223c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x0000000064d587de, 0x00000001ab16ea02 }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x00000000f4a507b0, 0x000000013c4598a8 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x0000000040e342fc, 0x00000000b3735430 }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001d5ad9c3a, 0x00000001bb3fc0c0 }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x0000000094a691a4, 0x00000001570ae19c }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001271ecdfa, 0x00000001ea910712 }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x000000009e54475a, 0x0000000167127128 }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x00000000c9c099ee, 0x0000000019e790a2 }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000009a2f736c, 0x000000003788f710 }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000000bb9f4996, 0x00000001682a160e }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x00000001db688050, 0x000000007f0ebd2e }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x00000000e9b10af4, 0x000000002b032080 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x000000012d4545e4, 0x00000000cfd1664a }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x000000000361139c, 0x00000000aa1181c2 }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000001a5a1a3a8, 0x00000000ddd08002 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x000000006844e0b0, 0x00000000e8dd0446 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000000c3762f28, 0x00000001bbd94a00 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000001d26287a2, 0x00000000ab6cd180 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x00000001f6f0bba8, 0x0000000031803ce2 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x000000002ffabd62, 0x0000000024f40b0c }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000000fb4516b8, 0x00000001ba1d9834 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x000000018cfa961c, 0x0000000104de61aa }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x000000019e588d52, 0x0000000113e40d46 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001180f0bbc, 0x00000001415598a0 }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000e1d9177a, 0x00000000bf6c8c90 }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x0000000105abc27c, 0x00000001788b0504 }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x00000000972e4a58, 0x0000000038385d02 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x0000000183499a5e, 0x00000001b6c83844 }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x00000001c96a8cca, 0x0000000051061a8a }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x00000001a1a5b60c, 0x000000017351388a }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x00000000e4b6ac9c, 0x0000000132928f92 }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000001807e7f5a, 0x00000000e6b4f48a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x000000017a7e3bc8, 0x0000000039d15e90 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000d73975da, 0x00000000312d6074 }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017375d038, 0x000000017bbb2cc4 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x00000000193680bc, 0x000000016ded3e18 }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000999b06f6, 0x00000000f1638b16 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001f685d2b8, 0x00000001d38b9ecc }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x00000001f4ecbed2, 0x000000018b8d09dc }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000ba16f1a0, 0x00000000e7bc27d2 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x0000000115aceac4, 0x00000000275e1e96 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000001aeff6292, 0x00000000e2e3031e }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x000000009640124c, 0x00000001041c84d8 }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x0000000114f41f02, 0x00000000706ce672 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000009c5f3586, 0x000000015d5070da }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x00000001878275fa, 0x0000000038f9493a }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000ddc42ce8, 0x00000000a3348a76 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x0000000181d2c73a, 0x00000001ad0aab92 }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x0000000141c9320a, 0x000000019e85f712 }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000015235719a, 0x000000005a871e76 }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x00000000be27d804, 0x000000017249c662 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000006242d45a, 0x000000003a084712 }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x000000009a53638e, 0x00000000ed438478 }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000001001ecfb6, 0x00000000abac34cc }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000016d7c2d64, 0x000000005f35ef3e }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x00000001d0ce46c0, 0x0000000047d6608c }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x0000000124c907b4, 0x000000002d01470e }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000018a555ca, 0x0000000158bbc7b0 }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x000000006b0980bc, 0x00000000c0a23e8e }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x000000008bbba964, 0x00000001ebd85c88 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x00000001070a5a1e, 0x000000019ee20bb2 }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x000000002204322a, 0x00000001acabf2d6 }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000000a27524d0, 0x00000001b7963d56 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x0000000020b1e4ba, 0x000000017bffa1fe }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x0000000032cc27fc, 0x000000001f15333e }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x0000000044dd22b8, 0x000000018593129e }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x00000000dffc9e0a, 0x000000019cb32602 }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x00000001b7a0ed14, 0x0000000142b05cc8 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000000c7842488, 0x00000001be49e7a4 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x00000001c02a4fee, 0x0000000108f69d6c }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000003c273778, 0x000000006c0971f0 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x00000001d63f8894, 0x000000005b16467a }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x000000006be557d6, 0x00000001551a628e }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000006a7806ea, 0x000000019e42ea92 }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000016155aa0c, 0x000000012fa83ff2 }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x00000000908650ac, 0x000000011ca9cde0 }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000aa5a8084, 0x00000000c8e5cd74 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000191bb500a, 0x0000000096c27f0c }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x0000000064e9bed0, 0x000000002baed926 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000009444f302, 0x000000017c8de8d2 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x000000019db07d3c, 0x00000000d43d6068 }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000001359e3e6e, 0x00000000cb2c4b26 }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x00000001e4f10dd2, 0x0000000145b8da26 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x0000000124f5735e, 0x000000018fff4b08 }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000124760a4c, 0x0000000150b58ed0 }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x000000000f1fc186, 0x00000001549f39bc }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000150e4cc4, 0x00000000ef4d2f42 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x000000002a6204e8, 0x00000001b1468572 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x00000000beb1d432, 0x000000013d7403b2 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x0000000135f3f1f0, 0x00000001a4681842 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000074fe2232, 0x0000000167714492 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x000000001ac6e2ba, 0x00000001e599099a }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x0000000013fca91e, 0x00000000fe128194 }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000183f4931e, 0x0000000077e8b990 }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000000b6d9b4e4, 0x00000001a267f63a }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000000b5188656, 0x00000001945c245a }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000027a81a84, 0x0000000149002e76 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x0000000125699258, 0x00000001bb8310a4 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x00000001b23de796, 0x000000019ec60bcc }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x00000000fe4365dc, 0x000000012d8590ae }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x00000000c68f497a, 0x0000000065b00684 }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x00000000fbf521ee, 0x000000015e5aeadc }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x000000015eac3378, 0x00000000b77ff2b0 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000134914b90, 0x0000000188da2ff6 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000016335cfe, 0x0000000063da929a }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x000000010372d10c, 0x00000001389caa80 }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000015097b908, 0x000000013db599d2 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x00000001227a7572, 0x0000000122505a86 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000009a8f75c0, 0x000000016bd72746 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000000682c77a2, 0x00000001c3faf1d4 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000000231f091c, 0x00000001111c826c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x000000007d4439f2, 0x00000000153e9fb2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000017e221efc, 0x000000002b1f7b60 }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x0000000167457c38, 0x00000000b1dba570 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000000bdf081c4, 0x00000001f6397b76 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x000000016286d6b0, 0x0000000156335214 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000000c84f001c, 0x00000001d70e3986 }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x0000000064efe7c0, 0x000000003701a774 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x000000000ac2d904, 0x00000000ac81ef72 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x00000000fd226d14, 0x0000000133212464 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x000000011cfd42e0, 0x00000000e4e45610 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000016e5a5678, 0x000000000c1bd370 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001d888fe22, 0x00000001a7b9e7a6 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x00000001af77fcd4, 0x000000007d657a10 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros */ + +static const __vector unsigned long long vcrc_short_const[16] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0x99168a18ec447f11, 0xed837b2613e8221e }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xe23e954e8fd2cd3c, 0xc8acdd8147b9ce5a }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0x92f8befe6b1d2b53, 0xd9ad6d87d4277e25 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xf38a3556291ea462, 0xc10ec5e033fbca3b }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0x974ac56262b6ca4b, 0xc0b55b0e82e02e2f }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x855712b3784d2a56, 0x71aa1df0e172334d }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xa5abe9f80eaee722, 0xfee3053e3969324d }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0x1fa0943ddb54814c, 0xf44779b93eb2bd08 }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xa53ff440d7bbfe6a, 0xf5449b3f00cc3374 }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0xebe7e3566325605c, 0x6f8346e1d777606e }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xc65a272ce5b592b8, 0xe3ab4f2ac0b95347 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0x5705a9ca4721589f, 0xaa2215ea329ecc11 }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0xe3720acb88d14467, 0x1ed8f66ed95efd26 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0xba1aca0315141c31, 0x78ed02d5a700e96a }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xad2a31b3ed627dae, 0xba8ccbe832b39da3 }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0x6655004fa06a2517, 0xedb88320b1e6b092 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0xed837b2613e8221e, 0x99168a18ec447f11 }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xc8acdd8147b9ce5a, 0xe23e954e8fd2cd3c }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0xd9ad6d87d4277e25, 0x92f8befe6b1d2b53 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xc10ec5e033fbca3b, 0xf38a3556291ea462 }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0xc0b55b0e82e02e2f, 0x974ac56262b6ca4b }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x71aa1df0e172334d, 0x855712b3784d2a56 }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xfee3053e3969324d, 0xa5abe9f80eaee722 }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0xf44779b93eb2bd08, 0x1fa0943ddb54814c }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xf5449b3f00cc3374, 0xa53ff440d7bbfe6a }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0x6f8346e1d777606e, 0xebe7e3566325605c }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xe3ab4f2ac0b95347, 0xc65a272ce5b592b8 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0xaa2215ea329ecc11, 0x5705a9ca4721589f }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0x1ed8f66ed95efd26, 0xe3720acb88d14467 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0x78ed02d5a700e96a, 0xba1aca0315141c31 }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xba8ccbe832b39da3, 0xad2a31b3ed627dae }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0xedb88320b1e6b092, 0x6655004fa06a2517 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Barrett constants */ +/* 33 bit reflected Barrett constant m - (4^32)/n */ + +static const __vector unsigned long long v_Barrett_const[2] ALIGNED_(16) = { + /* x^64 div p(x) */ +#if BYTE_ORDER == LITTLE_ENDIAN + { 0x00000001f7011641, 0x0000000000000000 }, + { 0x00000001db710641, 0x0000000000000000 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + { 0x0000000000000000, 0x00000001f7011641 }, + { 0x0000000000000000, 0x00000001db710641 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_power8.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_power8.c new file mode 100644 index 000000000..1cb5f299f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/crc32_power8.c @@ -0,0 +1,589 @@ +/* crc32 for POWER8 using VSX instructions + * Copyright (C) 2021 IBM Corporation + * + * Author: Rogerio Alves + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate the checksum of data that is 16 byte aligned and a multiple of + * 16 bytes. + * + * The first step is to reduce it to 1024 bits. We do this in 8 parallel + * chunks in order to mask the latency of the vpmsum instructions. If we + * have more than 32 kB of data to checksum we repeat this step multiple + * times, passing in the previous 1024 bits. + * + * The next step is to reduce the 1024 bits to 64 bits. This step adds + * 32 bits of 0s to the end - this matches what a CRC does. We just + * calculate constants that land the data in this 32 bits. + * + * We then use fixed point Barrett reduction to compute a mod n over GF(2) + * for n = CRC using POWER8 instructions. We use x = 32. + * + * http://en.wikipedia.org/wiki/Barrett_reduction + * + * This code uses gcc vector builtins instead using assembly directly. + */ + +#include +#include "zendian.h" +#include "zbuild.h" + +#include "crc32_constants.h" +#include "crc32_braid_tbl.h" + +#if defined (__clang__) +#include "fallback_builtins.h" +#endif + +#define MAX_SIZE 32768 +#define VMX_ALIGN 16 +#define VMX_ALIGN_MASK (VMX_ALIGN-1) + +static unsigned int crc32_align(unsigned int crc, const unsigned char *p, unsigned long len) { + while (len--) + crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); + return crc; +} + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len); + +Z_INTERNAL uint32_t crc32_power8(uint32_t crc, const unsigned char *p, size_t _len) { + unsigned int prealign; + unsigned int tail; + + unsigned long len = (unsigned long) _len; + + if (p == (const unsigned char *) 0x0) + return 0; + + crc ^= 0xffffffff; + + if (len < VMX_ALIGN + VMX_ALIGN_MASK) { + crc = crc32_align(crc, p, len); + goto out; + } + + if ((unsigned long)p & VMX_ALIGN_MASK) { + prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK); + crc = crc32_align(crc, p, prealign); + len -= prealign; + p += prealign; + } + + crc = __crc32_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); + + tail = len & VMX_ALIGN_MASK; + if (tail) { + p += len & ~VMX_ALIGN_MASK; + crc = crc32_align(crc, p, tail); + } + +out: + crc ^= 0xffffffff; + + return crc; +} + +/* When we have a load-store in a single-dispatch group and address overlap + * such that forward is not allowed (load-hit-store) the group must be flushed. + * A group ending NOP prevents the flush. + */ +#define GROUP_ENDING_NOP __asm__("ori 2,2,0" ::: "memory") + +#if BYTE_ORDER == BIG_ENDIAN +#define BYTESWAP_DATA +#endif + +#ifdef BYTESWAP_DATA +#define VEC_PERM(vr, va, vb, vc) vr = vec_perm(va, vb, (__vector unsigned char) vc) +#if BYTE_ORDER == LITTLE_ENDIAN +/* Byte reverse permute constant LE. */ +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x08090A0B0C0D0E0FUL, 0x0001020304050607UL }; +#else +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x0F0E0D0C0B0A0908UL, 0X0706050403020100UL }; +#endif +#else +#define VEC_PERM(vr, va, vb, vc) +#endif + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len) { + + const __vector unsigned long long vzero = {0,0}; + const __vector unsigned long long vones = {0xffffffffffffffffUL, 0xffffffffffffffffUL}; + + const __vector unsigned long long vmask_32bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 4); + + const __vector unsigned long long vmask_64bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 8); + + __vector unsigned long long vcrc; + + __vector unsigned long long vconst1, vconst2; + + /* vdata0-vdata7 will contain our data (p). */ + __vector unsigned long long vdata0, vdata1, vdata2, vdata3, vdata4, vdata5, vdata6, vdata7; + + /* v0-v7 will contain our checksums */ + __vector unsigned long long v0 = {0,0}; + __vector unsigned long long v1 = {0,0}; + __vector unsigned long long v2 = {0,0}; + __vector unsigned long long v3 = {0,0}; + __vector unsigned long long v4 = {0,0}; + __vector unsigned long long v5 = {0,0}; + __vector unsigned long long v6 = {0,0}; + __vector unsigned long long v7 = {0,0}; + + + /* Vector auxiliary variables. */ + __vector unsigned long long va0, va1, va2, va3, va4, va5, va6, va7; + + unsigned int offset; /* Constant table offset. */ + + unsigned long i; /* Counter. */ + unsigned long chunks; + + unsigned long block_size; + int next_block = 0; + + /* Align by 128 bits. The last 128 bit block will be processed at end. */ + unsigned long length = len & 0xFFFFFFFFFFFFFF80UL; + + vcrc = (__vector unsigned long long)__builtin_pack_vector_int128(0UL, crc); + + /* Short version. */ + if (len < 256) { + /* Calculate where in the constant table we need to start. */ + offset = 256 - len; + + vconst1 = vec_ld(offset, vcrc_short_const); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + + /* xor initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + + for (i = 16; i < len; i += 16) { + vconst1 = vec_ld(offset + i, vcrc_short_const); + vdata0 = vec_ld(i, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + } + } else { + + /* Load initial values. */ + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + /* xor in initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + p = (char *)p + 128; + + do { + /* Checksum in blocks of MAX_SIZE. */ + block_size = length; + if (block_size > MAX_SIZE) { + block_size = MAX_SIZE; + } + + length = length - block_size; + + /* + * Work out the offset into the constants table to start at. Each + * constant is 16 bytes, and it is used against 128 bytes of input + * data - 128 / 16 = 8 + */ + offset = (MAX_SIZE/8) - (block_size/8); + /* We reduce our final 128 bytes in a separate step */ + chunks = (block_size/128)-1; + + vconst1 = vec_ld(offset, vcrc_const); + + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + + if (chunks > 1) { + offset += 16; + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + + /* + * main loop. Each iteration calculates the CRC for a 128-byte + * block. + */ + for (i = 0; i < chunks-2; i++) { + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + GROUP_ENDING_NOP; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst2); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst2); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long) + vdata2, (__vector unsigned long long)vconst2); + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst2); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + } + + /* First cool down */ + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + }/* else */ + + /* Second cool down. */ + v0 = vec_xor(v0, va0); + v1 = vec_xor(v1, va1); + v2 = vec_xor(v2, va2); + v3 = vec_xor(v3, va3); + v4 = vec_xor(v4, va4); + v5 = vec_xor(v5, va5); + v6 = vec_xor(v6, va6); + v7 = vec_xor(v7, va7); + + /* + * vpmsumd produces a 96 bit result in the least significant bits + * of the register. Since we are bit reflected we have to shift it + * left 32 bits so it occupies the least significant bits in the + * bit reflected domain. + */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v1, + (__vector unsigned char)vzero, 4); + v2 = (__vector unsigned long long)vec_sld((__vector unsigned char)v2, + (__vector unsigned char)vzero, 4); + v3 = (__vector unsigned long long)vec_sld((__vector unsigned char)v3, + (__vector unsigned char)vzero, 4); + v4 = (__vector unsigned long long)vec_sld((__vector unsigned char)v4, + (__vector unsigned char)vzero, 4); + v5 = (__vector unsigned long long)vec_sld((__vector unsigned char)v5, + (__vector unsigned char)vzero, 4); + v6 = (__vector unsigned long long)vec_sld((__vector unsigned char)v6, + (__vector unsigned char)vzero, 4); + v7 = (__vector unsigned long long)vec_sld((__vector unsigned char)v7, + (__vector unsigned char)vzero, 4); + + /* xor with the last 1024 bits. */ + va0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(va0, va0, va0, vperm_const); + + va1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(va1, va1, va1, vperm_const); + + va2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(va2, va2, va2, vperm_const); + + va3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(va3, va3, va3, vperm_const); + + va4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(va4, va4, va4, vperm_const); + + va5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(va5, va5, va5, vperm_const); + + va6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(va6, va6, va6, vperm_const); + + va7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(va7, va7, va7, vperm_const); + + p = (char *)p + 128; + + vdata0 = vec_xor(v0, va0); + vdata1 = vec_xor(v1, va1); + vdata2 = vec_xor(v2, va2); + vdata3 = vec_xor(v3, va3); + vdata4 = vec_xor(v4, va4); + vdata5 = vec_xor(v5, va5); + vdata6 = vec_xor(v6, va6); + vdata7 = vec_xor(v7, va7); + + /* Check if we have more blocks to process */ + next_block = 0; + if (length != 0) { + next_block = 1; + + /* zero v0-v7 */ + v0 = vec_xor(v0, v0); + v1 = vec_xor(v1, v1); + v2 = vec_xor(v2, v2); + v3 = vec_xor(v3, v3); + v4 = vec_xor(v4, v4); + v5 = vec_xor(v5, v5); + v6 = vec_xor(v6, v6); + v7 = vec_xor(v7, v7); + } + length = length + 128; + + } while (next_block); + + /* Calculate how many bytes we have left. */ + length = (len & 127); + + /* Calculate where in (short) constant table we need to start. */ + offset = 128 - length; + + v0 = vec_ld(offset, vcrc_short_const); + v1 = vec_ld(offset + 16, vcrc_short_const); + v2 = vec_ld(offset + 32, vcrc_short_const); + v3 = vec_ld(offset + 48, vcrc_short_const); + v4 = vec_ld(offset + 64, vcrc_short_const); + v5 = vec_ld(offset + 80, vcrc_short_const); + v6 = vec_ld(offset + 96, vcrc_short_const); + v7 = vec_ld(offset + 112, vcrc_short_const); + + offset += 128; + + v0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)v0); + v1 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata1, (__vector unsigned int)v1); + v2 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata2, (__vector unsigned int)v2); + v3 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata3, (__vector unsigned int)v3); + v4 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata4, (__vector unsigned int)v4); + v5 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata5, (__vector unsigned int)v5); + v6 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata6, (__vector unsigned int)v6); + v7 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata7, (__vector unsigned int)v7); + + /* Now reduce the tail (0-112 bytes). */ + for (i = 0; i < length; i+=16) { + vdata0 = vec_ld(i,(__vector unsigned long long*)p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + va0 = vec_ld(offset + i,vcrc_short_const); + va0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)va0); + v0 = vec_xor(v0, va0); + } + + /* xor all parallel chunks together. */ + v0 = vec_xor(v0, v1); + v2 = vec_xor(v2, v3); + v4 = vec_xor(v4, v5); + v6 = vec_xor(v6, v7); + + v0 = vec_xor(v0, v2); + v4 = vec_xor(v4, v6); + + v0 = vec_xor(v0, v4); + } + + /* Barrett Reduction */ + vconst1 = vec_ld(0, v_Barrett_const); + vconst2 = vec_ld(16, v_Barrett_const); + + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)v0, 8); + v0 = vec_xor(v1,v0); + + /* shift left one bit */ + __vector unsigned char vsht_splat = vec_splat_u8 (1); + v0 = (__vector unsigned long long)vec_sll((__vector unsigned char)v0, vsht_splat); + + v0 = vec_and(v0, vmask_64bit); + + /* + * The reflected version of Barrett reduction. Instead of bit + * reflecting our data (which is expensive to do), we bit reflect our + * constants and our algorithm, which means the intermediate data in + * our vector registers goes from 0-63 instead of 63-0. We can reflect + * the algorithm because we don't carry in mod 2 arithmetic. + */ + + /* bottom 32 bits of a */ + v1 = vec_and(v0, vmask_32bit); + + /* ma */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst1); + + /* bottom 32bits of ma */ + v1 = vec_and(v1, vmask_32bit); + /* qn */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst2); + /* a - qn, subtraction is xor in GF(2) */ + v0 = vec_xor (v0, v1); + + /* + * Since we are bit reflected, the result (ie the low 32 bits) is in + * the high 32 bits. We just need to shift it left 4 bytes + * V0 [ 0 1 X 3 ] + * V0 [ 0 X 2 3 ] + */ + + /* shift result into top 64 bits of */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + +#if BYTE_ORDER == BIG_ENDIAN + return v0[0]; +#else + return v0[1]; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/fallback_builtins.h new file mode 100644 index 000000000..ed9584617 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/fallback_builtins.h @@ -0,0 +1,31 @@ +/* Helper functions to work around issues with clang builtins + * Copyright (C) 2021 IBM Corporation + * + * Authors: + * Daniel Black + * Rogerio Alves + * Tulio Magno Quites Machado Filho + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_BUILTINS_H +#define POWER_BUILTINS_H + +/* + * These stubs fix clang incompatibilities with GCC builtins. + */ + +#ifndef __builtin_crypto_vpmsumw +#define __builtin_crypto_vpmsumw __builtin_crypto_vpmsumb +#endif +#ifndef __builtin_crypto_vpmsumd +#define __builtin_crypto_vpmsumd __builtin_crypto_vpmsumb +#endif + +static inline __vector unsigned long long __attribute__((overloadable)) +vec_ld(int __a, const __vector unsigned long long* __b) { + return (__vector unsigned long long)__builtin_altivec_lvx(__a, __b); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.c new file mode 100644 index 000000000..003a4c6e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.c @@ -0,0 +1,42 @@ +/* power_features.c - POWER feature check + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021-2022 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef HAVE_SYS_AUXV_H +# include +#endif +#ifdef __FreeBSD__ +# include +#endif +#include "../../zbuild.h" +#include "power_features.h" + +void Z_INTERNAL power_check_features(struct power_cpu_features *features) { +#ifdef PPC_FEATURES + unsigned long hwcap; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); +#else + hwcap = getauxval(AT_HWCAP); +#endif + + if (hwcap & PPC_FEATURE_HAS_ALTIVEC) + features->has_altivec = 1; +#endif + +#ifdef POWER_FEATURES + unsigned long hwcap2; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); +#else + hwcap2 = getauxval(AT_HWCAP2); +#endif + + if (hwcap2 & PPC_FEATURE2_ARCH_2_07) + features->has_arch_2_07 = 1; + if (hwcap2 & PPC_FEATURE2_ARCH_3_00) + features->has_arch_3_00 = 1; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.h new file mode 100644 index 000000000..9252364cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/power_features.h @@ -0,0 +1,18 @@ +/* power_features.h -- check for POWER CPU features + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_H_ +#define POWER_H_ + +struct power_cpu_features { + int has_altivec; + int has_arch_2_07; + int has_arch_3_00; +}; + +void Z_INTERNAL power_check_features(struct power_cpu_features *features); + +#endif /* POWER_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_power8.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_power8.c new file mode 100644 index 000000000..d01e0acd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_power8.c @@ -0,0 +1,12 @@ +/* Optimized slide_hash for POWER processors + * Copyright (C) 2019-2020 IBM Corporation + * Author: Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX + +#define SLIDE_PPC slide_hash_power8 +#include "slide_ppc_tpl.h" + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_vmx.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_vmx.c new file mode 100644 index 000000000..5a87ef7d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_hash_vmx.c @@ -0,0 +1,10 @@ +/* Optimized slide_hash for PowerPC processors with VMX instructions + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef PPC_VMX + +#define SLIDE_PPC slide_hash_vmx +#include "slide_ppc_tpl.h" + +#endif /* PPC_VMX */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_ppc_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_ppc_tpl.h new file mode 100644 index 000000000..5c17e38fb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/power/slide_ppc_tpl.h @@ -0,0 +1,31 @@ +/* Optimized slide_hash for PowerPC processors + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" + +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + const vector unsigned short vmx_wsize = vec_splats(wsize); + Pos *p = table; + + do { + vector unsigned short value, result; + + value = vec_ld(0, p); + result = vec_subs(value, vmx_wsize); + vec_st(result, 0, p); + + p += 8; + entries -= 8; + } while (entries > 0); +} + +void Z_INTERNAL SLIDE_PPC(deflate_state *s) { + uint16_t wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/Makefile.in new file mode 100644 index 000000000..39b5aae61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/Makefile.in @@ -0,0 +1,54 @@ +# Makefile for zlib-ng +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= +VGFMAFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +s390_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +s390_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +dfltcc_common.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_common.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_deflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_deflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_inflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +dfltcc_inflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +crc32-vx.o: + $(CC) $(CFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +crc32-vx.lo: + $(CC) $(SFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/README.md b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/README.md new file mode 100644 index 000000000..2c3165412 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/README.md @@ -0,0 +1,284 @@ +# Introduction + +This directory contains SystemZ deflate hardware acceleration support. +It can be enabled using the following build commands: + + $ ./configure --with-dfltcc-deflate --with-dfltcc-inflate + $ make + +or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 -DWITH_DFLTCC_INFLATE=1 . + $ make + +When built like this, zlib-ng would compress using hardware on level 1, +and using software on all other levels. Decompression will always happen +in hardware. In order to enable hardware compression for levels 1-6 +(i.e. to make it used by default) one could add +`-DDFLTCC_LEVEL_MASK=0x7e` to CFLAGS when building zlib-ng. + +SystemZ deflate hardware acceleration is available on [IBM z15]( +https://www.ibm.com/products/z15) and newer machines under the name [ +"Integrated Accelerator for zEnterprise Data Compression"]( +https://www.ibm.com/support/z-content-solutions/compression/). The +programming interface to it is a machine instruction called DEFLATE +CONVERSION CALL (DFLTCC). It is documented in Chapter 26 of [Principles +of Operation](https://publibfp.dhe.ibm.com/epubs/pdf/a227832c.pdf). Both +the code and the rest of this document refer to this feature simply as +"DFLTCC". + +# Performance + +Performance figures are published [here]( +https://github.com/iii-i/zlib-ng/wiki/Performance-with-dfltcc-patch-applied-and-dfltcc-support-built-on-dfltcc-enabled-machine +). The compression speed-up can be as high as 110x and the decompression +speed-up can be as high as 15x. + +# Limitations + +Two DFLTCC compression calls with identical inputs are not guaranteed to +produce identical outputs. Therefore care should be taken when using +hardware compression when reproducible results are desired. In +particular, zlib-ng-specific `zng_deflateSetParams` call allows setting +`Z_DEFLATE_REPRODUCIBLE` parameter, which disables DFLTCC support for a +particular stream. + +DFLTCC does not support every single zlib-ng feature, in particular: + +* `inflate(Z_BLOCK)` and `inflate(Z_TREES)` +* `inflateMark()` +* `inflatePrime()` +* `inflateSyncPoint()` + +When used, these functions will either switch to software, or, in case +this is not possible, gracefully fail. + +# Code structure + +All SystemZ-specific code lives in `arch/s390` directory and is +integrated with the rest of zlib-ng using hook macros. + +## Hook macros + +DFLTCC takes as arguments a parameter block, an input buffer, an output +buffer and a window. `ZALLOC_DEFLATE_STATE()`, `ZALLOC_INFLATE_STATE()`, +`ZFREE_STATE()`, `ZCOPY_DEFLATE_STATE()`, `ZCOPY_INFLATE_STATE()`, +`ZALLOC_WINDOW()`, `ZCOPY_WINDOW()` and `TRY_FREE_WINDOW()` macros encapsulate +allocation details for the parameter block (which is allocated alongside +zlib-ng state) and the window (which must be page-aligned and large enough). + +Software and hardware window formats do not match, therefore, +`deflateSetDictionary()`, `deflateGetDictionary()`, `inflateSetDictionary()` +and `inflateGetDictionary()` need special handling, which is triggered using +`DEFLATE_SET_DICTIONARY_HOOK()`, `DEFLATE_GET_DICTIONARY_HOOK()`, +`INFLATE_SET_DICTIONARY_HOOK()` and `INFLATE_GET_DICTIONARY_HOOK()` macros. + +`deflateResetKeep()` and `inflateResetKeep()` update the DFLTCC +parameter block using `DEFLATE_RESET_KEEP_HOOK()` and +`INFLATE_RESET_KEEP_HOOK()` macros. + +`INFLATE_PRIME_HOOK()`, `INFLATE_MARK_HOOK()` and +`INFLATE_SYNC_POINT_HOOK()` macros make the respective unsupported +calls gracefully fail. + +`DEFLATE_PARAMS_HOOK()` implements switching between hardware and +software compression mid-stream using `deflateParams()`. Switching +normally entails flushing the current block, which might not be possible +in low memory situations. `deflateParams()` uses `DEFLATE_DONE()` hook +in order to detect and gracefully handle such situations. + +The algorithm implemented in hardware has different compression ratio +than the one implemented in software. `DEFLATE_BOUND_ADJUST_COMPLEN()` +and `DEFLATE_NEED_CONSERVATIVE_BOUND()` macros make `deflateBound()` +return the correct results for the hardware implementation. + +Actual compression and decompression are handled by `DEFLATE_HOOK()` and +`INFLATE_TYPEDO_HOOK()` macros. Since inflation with DFLTCC manages the +window on its own, calling `updatewindow()` is suppressed using +`INFLATE_NEED_UPDATEWINDOW()` macro. + +In addition to compression, DFLTCC computes CRC-32 and Adler-32 +checksums, therefore, whenever it's used, software checksumming is +suppressed using `DEFLATE_NEED_CHECKSUM()` and `INFLATE_NEED_CHECKSUM()` +macros. + +While software always produces reproducible compression results, this +is not the case for DFLTCC. Therefore, zlib-ng users are given the +ability to specify whether or not reproducible compression results +are required. While it is always possible to specify this setting +before the compression begins, it is not always possible to do so in +the middle of a deflate stream - the exact conditions for that are +determined by `DEFLATE_CAN_SET_REPRODUCIBLE()` macro. + +## SystemZ-specific code + +When zlib-ng is built with DFLTCC, the hooks described above are +converted to calls to functions, which are implemented in +`arch/s390/dfltcc_*` files. The functions can be grouped in three broad +categories: + +* Base DFLTCC support, e.g. wrapping the machine instruction - + `dfltcc()` and allocating aligned memory - `dfltcc_alloc_state()`. +* Translating between software and hardware data formats, e.g. + `dfltcc_deflate_set_dictionary()`. +* Translating between software and hardware state machines, e.g. + `dfltcc_deflate()` and `dfltcc_inflate()`. + +The functions from the first two categories are fairly simple, however, +various quirks in both software and hardware state machines make the +functions from the third category quite complicated. + +### `dfltcc_deflate()` function + +This function is called by `deflate()` and has the following +responsibilities: + +* Checking whether DFLTCC can be used with the current stream. If this + is not the case, then it returns `0`, making `deflate()` use some + other function in order to compress in software. Otherwise it returns + `1`. +* Block management and Huffman table generation. DFLTCC ends blocks only + when explicitly instructed to do so by the software. Furthermore, + whether to use fixed or dynamic Huffman tables must also be determined + by the software. Since looking at data in order to gather statistics + would negate performance benefits, the following approach is used: the + first `DFLTCC_FIRST_FHT_BLOCK_SIZE` bytes are placed into a fixed + block, and every next `DFLTCC_BLOCK_SIZE` bytes are placed into + dynamic blocks. +* Writing EOBS. Block Closing Control bit in the parameter block + instructs DFLTCC to write EOBS, however, certain conditions need to be + met: input data length must be non-zero or Continuation Flag must be + set. To put this in simpler terms, DFLTCC will silently refuse to + write EOBS if this is the only thing that it is asked to do. Since the + code has to be able to emit EOBS in software anyway, in order to avoid + tricky corner cases Block Closing Control is never used. Whether to + write EOBS is instead controlled by `soft_bcc` variable. +* Triggering block post-processing. Depending on flush mode, `deflate()` + must perform various additional actions when a block or a stream ends. + `dfltcc_deflate()` informs `deflate()` about this using + `block_state *result` parameter. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `wrap` and Check Value Type or `bi_valid` + and Sub-Byte Boundary. Certain fields cannot be translated and must + persist untouched in the parameter block between calls, for example, + Continuation Flag or Continuation State Buffer. +* Handling flush modes and low-memory situations. These aspects are + quite intertwined and pervasive. The general idea here is that the + code must not do anything in software - whether explicitly by e.g. + calling `send_eobs()`, or implicitly - by returning to `deflate()` + with certain return and `*result` values, when Continuation Flag is + set. +* Ending streams. When a new block is started and flush mode is + `Z_FINISH`, Block Header Final parameter block bit is used to mark + this block as final. However, sometimes an empty final block is + needed, and, unfortunately, just like with EOBS, DFLTCC will silently + refuse to do this. The general idea of DFLTCC implementation is to + rely as much as possible on the existing code. Here in order to do + this, the code pretends that it does not support DFLTCC, which makes + `deflate()` call a software compression function, which writes an + empty final block. Whether this is required is controlled by + `need_empty_block` variable. +* Error handling. This is simply converting + Operation-Ending-Supplemental Code to string. Errors can only happen + due to things like memory corruption, and therefore they don't affect + the `deflate()` return code. + +### `dfltcc_inflate()` function + +This function is called by `inflate()` from the `TYPEDO` state (that is, +when all the metadata is parsed and the stream is positioned at the type +bits of deflate block header) and it's responsible for the following: + +* Falling back to software when flush mode is `Z_BLOCK` or `Z_TREES`. + Unfortunately, there is no way to ask DFLTCC to stop decompressing on + block or tree boundary. +* `inflate()` decompression loop management. This is controlled using + the return value, which can be either `DFLTCC_INFLATE_BREAK` or + `DFLTCC_INFLATE_CONTINUE`. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `whave` and History Length or `wnext` and + History Offset. +* Ending streams. This instructs `inflate()` to return `Z_STREAM_END` + and is controlled by `last` state field. +* Error handling. Like deflate, error handling comprises + Operation-Ending-Supplemental Code to string conversion. Unlike + deflate, errors may happen due to bad inputs, therefore they are + propagated to `inflate()` by setting `mode` field to `MEM` or `BAD`. + +# Testing + +Given complexity of DFLTCC machine instruction, it is not clear whether +QEMU TCG will ever support it. At the time of writing, one has to have +access to an IBM z15+ VM or LPAR in order to test DFLTCC support. Since +DFLTCC is a non-privileged instruction, neither special VM/LPAR +configuration nor root are required. + +zlib-ng CI uses an IBM-provided z15 self-hosted builder for the DFLTCC +testing. There are no IBM Z builds of GitHub Actions runner, and +stable qemu-user has problems with .NET apps, so the builder runs the +x86_64 runner version with qemu-user built from the master branch. + +## Configuring the builder. + +### Install prerequisites. + +``` +$ sudo dnf install docker +``` + +### Add services. + +``` +$ sudo cp self-hosted-builder/*.service /etc/systemd/system/ +$ sudo systemctl daemon-reload +``` + +### Create a config file. + +``` +$ sudo tee /etc/actions-runner +repo=/ +access_token= +``` + +Access token should have the repo scope, consult +https://docs.github.com/en/rest/reference/actions#create-a-registration-token-for-a-repository +for details. + +### Autostart the x86_64 emulation support. + +``` +$ sudo systemctl enable --now qemu-user-static +``` + +### Autostart the runner. + +``` +$ sudo systemctl enable --now actions-runner +``` + +## Rebuilding the image + +In order to update the `iiilinuxibmcom/actions-runner` image, e.g. to get the +latest OS security fixes, use the following commands: + +``` +$ sudo docker build \ + --pull \ + -f self-hosted-builder/actions-runner.Dockerfile \ + -t iiilinuxibmcom/actions-runner +$ sudo systemctl restart actions-runner +``` + +## Removing persistent data + +The `actions-runner` service stores various temporary data, such as runner +registration information, work directories and logs, in the `actions-runner` +volume. In order to remove it and start from scratch, e.g. when switching the +runner to a different repository, use the following commands: + +``` +$ sudo systemctl stop actions-runner +$ sudo docker rm -f actions-runner +$ sudo docker volume rm actions-runner +``` diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/crc32-vx.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/crc32-vx.c new file mode 100644 index 000000000..acfa21887 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/crc32-vx.c @@ -0,0 +1,222 @@ +/* + * Hardware-accelerated CRC-32 variants for Linux on z Systems + * + * Use the z/Architecture Vector Extension Facility to accelerate the + * computing of bitreflected CRC-32 checksums. + * + * This CRC-32 implementation algorithm is bitreflected and processes + * the least-significant bit first (Little-Endian). + * + * This code was originally written by Hendrik Brueckner + * for use in the Linux kernel and has been + * relicensed under the zlib license. + */ + +#include "../../zbuild.h" +#include "crc32_braid_p.h" + +#include + +typedef unsigned char uv16qi __attribute__((vector_size(16))); +typedef unsigned int uv4si __attribute__((vector_size(16))); +typedef unsigned long long uv2di __attribute__((vector_size(16))); + +static uint32_t crc32_le_vgfm_16(uint32_t crc, const uint8_t *buf, size_t len) { + /* + * The CRC-32 constant block contains reduction constants to fold and + * process particular chunks of the input data stream in parallel. + * + * For the CRC-32 variants, the constants are precomputed according to + * these definitions: + * + * R1 = [(x4*128+32 mod P'(x) << 32)]' << 1 + * R2 = [(x4*128-32 mod P'(x) << 32)]' << 1 + * R3 = [(x128+32 mod P'(x) << 32)]' << 1 + * R4 = [(x128-32 mod P'(x) << 32)]' << 1 + * R5 = [(x64 mod P'(x) << 32)]' << 1 + * R6 = [(x32 mod P'(x) << 32)]' << 1 + * + * The bitreflected Barret reduction constant, u', is defined as + * the bit reversal of floor(x**64 / P(x)). + * + * where P(x) is the polynomial in the normal domain and the P'(x) is the + * polynomial in the reversed (bitreflected) domain. + * + * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials: + * + * P(x) = 0x04C11DB7 + * P'(x) = 0xEDB88320 + */ + const uv16qi perm_le2be = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; /* BE->LE mask */ + const uv2di r2r1 = {0x1C6E41596, 0x154442BD4}; /* R2, R1 */ + const uv2di r4r3 = {0x0CCAA009E, 0x1751997D0}; /* R4, R3 */ + const uv2di r5 = {0, 0x163CD6124}; /* R5 */ + const uv2di ru_poly = {0, 0x1F7011641}; /* u' */ + const uv2di crc_poly = {0, 0x1DB710641}; /* P'(x) << 1 */ + + /* + * Load the initial CRC value. + * + * The CRC value is loaded into the rightmost word of the + * vector register and is later XORed with the LSB portion + * of the loaded input data. + */ + uv2di v0 = {0, 0}; + v0 = (uv2di)vec_insert(crc, (uv4si)v0, 3); + + /* Load a 64-byte data chunk and XOR with CRC */ + uv2di v1 = vec_perm(((uv2di *)buf)[0], ((uv2di *)buf)[0], perm_le2be); + uv2di v2 = vec_perm(((uv2di *)buf)[1], ((uv2di *)buf)[1], perm_le2be); + uv2di v3 = vec_perm(((uv2di *)buf)[2], ((uv2di *)buf)[2], perm_le2be); + uv2di v4 = vec_perm(((uv2di *)buf)[3], ((uv2di *)buf)[3], perm_le2be); + + v1 ^= v0; + buf += 64; + len -= 64; + + while (len >= 64) { + /* Load the next 64-byte data chunk */ + uv16qi part1 = vec_perm(((uv16qi *)buf)[0], ((uv16qi *)buf)[0], perm_le2be); + uv16qi part2 = vec_perm(((uv16qi *)buf)[1], ((uv16qi *)buf)[1], perm_le2be); + uv16qi part3 = vec_perm(((uv16qi *)buf)[2], ((uv16qi *)buf)[2], perm_le2be); + uv16qi part4 = vec_perm(((uv16qi *)buf)[3], ((uv16qi *)buf)[3], perm_le2be); + + /* + * Perform a GF(2) multiplication of the doublewords in V1 with + * the R1 and R2 reduction constants in V0. The intermediate result + * is then folded (accumulated) with the next data chunk in PART1 and + * stored in V1. Repeat this step for the register contents + * in V2, V3, and V4 respectively. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r2r1, v1, part1); + v2 = (uv2di)vec_gfmsum_accum_128(r2r1, v2, part2); + v3 = (uv2di)vec_gfmsum_accum_128(r2r1, v3, part3); + v4 = (uv2di)vec_gfmsum_accum_128(r2r1, v4, part4); + + buf += 64; + len -= 64; + } + + /* + * Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3 + * and R4 and accumulating the next 128-bit chunk until a single 128-bit + * value remains. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v3); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v4); + + while (len >= 16) { + /* Load next data chunk */ + v2 = vec_perm(*(uv2di *)buf, *(uv2di *)buf, perm_le2be); + + /* Fold next data chunk */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + + buf += 16; + len -= 16; + } + + /* + * Set up a vector register for byte shifts. The shift value must + * be loaded in bits 1-4 in byte element 7 of a vector register. + * Shift by 8 bytes: 0x40 + * Shift by 4 bytes: 0x20 + */ + uv16qi v9 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + v9 = vec_insert((unsigned char)0x40, v9, 7); + + /* + * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes + * to move R4 into the rightmost doubleword and set the leftmost + * doubleword to 0x1. + */ + v0 = vec_srb(r4r3, (uv2di)v9); + v0[0] = 1; + + /* + * Compute GF(2) product of V1 and V0. The rightmost doubleword + * of V1 is multiplied with R4. The leftmost doubleword of V1 is + * multiplied by 0x1 and is then XORed with rightmost product. + * Implicitly, the intermediate leftmost product becomes padded + */ + v1 = (uv2di)vec_gfmsum_128(v0, v1); + + /* + * Now do the final 32-bit fold by multiplying the rightmost word + * in V1 with R5 and XOR the result with the remaining bits in V1. + * + * To achieve this by a single VGFMAG, right shift V1 by a word + * and store the result in V2 which is then accumulated. Use the + * vector unpack instruction to load the rightmost half of the + * doubleword into the rightmost doubleword element of V1; the other + * half is loaded in the leftmost doubleword. + * The vector register with CONST_R5 contains the R5 constant in the + * rightmost doubleword and the leftmost doubleword is zero to ignore + * the leftmost product of V1. + */ + v9 = vec_insert((unsigned char)0x20, v9, 7); + v2 = vec_srb(v1, (uv2di)v9); + v1 = vec_unpackl((uv4si)v1); /* Split rightmost doubleword */ + v1 = (uv2di)vec_gfmsum_accum_128(r5, v1, (uv16qi)v2); + + /* + * Apply a Barret reduction to compute the final 32-bit CRC value. + * + * The input values to the Barret reduction are the degree-63 polynomial + * in V1 (R(x)), degree-32 generator polynomial, and the reduction + * constant u. The Barret reduction result is the CRC value of R(x) mod + * P(x). + * + * The Barret reduction algorithm is defined as: + * + * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u + * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x) + * 3. C(x) = R(x) XOR T2(x) mod x^32 + * + * Note: The leftmost doubleword of vector register containing + * CONST_RU_POLY is zero and, thus, the intermediate GF(2) product + * is zero and does not contribute to the final result. + */ + + /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */ + v2 = vec_unpackl((uv4si)v1); + v2 = (uv2di)vec_gfmsum_128(ru_poly, v2); + + /* + * Compute the GF(2) product of the CRC polynomial with T1(x) in + * V2 and XOR the intermediate result, T2(x), with the value in V1. + * The final result is stored in word element 2 of V2. + */ + v2 = vec_unpackl((uv4si)v2); + v2 = (uv2di)vec_gfmsum_accum_128(crc_poly, v2, (uv16qi)v1); + + return ((uv4si)v2)[2]; +} + +#define VX_MIN_LEN 64 +#define VX_ALIGNMENT 16L +#define VX_ALIGN_MASK (VX_ALIGNMENT - 1) + +uint32_t Z_INTERNAL crc32_s390_vx(uint32_t crc, const unsigned char *buf, size_t len) { + size_t prealign, aligned, remaining; + + if (len < VX_MIN_LEN + VX_ALIGN_MASK) + return PREFIX(crc32_braid)(crc, buf, len); + + if ((uintptr_t)buf & VX_ALIGN_MASK) { + prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK); + len -= prealign; + crc = PREFIX(crc32_braid)(crc, buf, prealign); + buf += prealign; + } + aligned = len & ~VX_ALIGN_MASK; + remaining = len & VX_ALIGN_MASK; + + crc = crc32_le_vgfm_16(crc ^ 0xffffffff, buf, aligned) ^ 0xffffffff; + + if (remaining) + crc = PREFIX(crc32_braid)(crc, buf + aligned, remaining); + + return crc; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.c new file mode 100644 index 000000000..78be71811 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.c @@ -0,0 +1,40 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL general support. */ + +#include "zbuild.h" +#include "dfltcc_common.h" +#include "dfltcc_detail.h" + +/* + Memory management. + + DFLTCC requires parameter blocks and window to be aligned. zlib-ng allows + users to specify their own allocation functions, so using e.g. + `posix_memalign' is not an option. Thus, we overallocate and take the + aligned portion of the buffer. +*/ + +static const int PAGE_ALIGN = 0x1000; + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size) { + void *p; + void *w; + + /* To simplify freeing, we store the pointer to the allocated buffer right + * before the window. Note that DFLTCC always uses HB_SIZE bytes. + */ + p = ZALLOC(strm, sizeof(void *) + MAX(items * size, HB_SIZE) + PAGE_ALIGN, sizeof(unsigned char)); + if (p == NULL) + return NULL; + w = ALIGN_UP((char *)p + sizeof(void *), PAGE_ALIGN); + *(void **)((char *)w - sizeof(void *)) = p; + return w; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n) { + memcpy(dest, src, MAX(n, HB_SIZE)); +} + +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w) { + if (w) + ZFREE(strm, *(void **)((unsigned char *)w - sizeof(void *))); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.h new file mode 100644 index 000000000..b73437411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_common.h @@ -0,0 +1,44 @@ +#ifndef DFLTCC_COMMON_H +#define DFLTCC_COMMON_H + +#include "zutil.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size); +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n); +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w); + +#define ZFREE_STATE ZFREE + +#define ZALLOC_WINDOW PREFIX(dfltcc_alloc_window) + +#define ZCOPY_WINDOW PREFIX(dfltcc_copy_window) + +#define ZFREE_WINDOW PREFIX(dfltcc_free_window) + +#define TRY_FREE_WINDOW PREFIX(dfltcc_free_window) + +#define DFLTCC_BLOCK_HEADER_BITS 3 +#define DFLTCC_HLITS_COUNT_BITS 5 +#define DFLTCC_HDISTS_COUNT_BITS 5 +#define DFLTCC_HCLENS_COUNT_BITS 4 +#define DFLTCC_MAX_HCLENS 19 +#define DFLTCC_HCLEN_BITS 3 +#define DFLTCC_MAX_HLITS 286 +#define DFLTCC_MAX_HDISTS 30 +#define DFLTCC_MAX_HLIT_HDIST_BITS 7 +#define DFLTCC_MAX_SYMBOL_BITS 16 +#define DFLTCC_MAX_EOBS_BITS 15 +#define DFLTCC_MAX_PADDING_BITS 7 + +#define DEFLATE_BOUND_COMPLEN(source_len) \ + ((DFLTCC_BLOCK_HEADER_BITS + \ + DFLTCC_HLITS_COUNT_BITS + \ + DFLTCC_HDISTS_COUNT_BITS + \ + DFLTCC_HCLENS_COUNT_BITS + \ + DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ + (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ + (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ + DFLTCC_MAX_EOBS_BITS + \ + DFLTCC_MAX_PADDING_BITS) >> 3) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.c new file mode 100644 index 000000000..3ad988afc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.c @@ -0,0 +1,404 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL compression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC compression support: + + $ ./configure --with-dfltcc-deflate + or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "deflate.h" +#include "trees_emit.h" +#include "dfltcc_deflate.h" +#include "dfltcc_detail.h" + +struct dfltcc_deflate_state { + struct dfltcc_state common; + uint16_t level_mask; /* Levels on which to use DFLTCC */ + uint32_t block_size; /* New block each X bytes */ + size_t block_threshold; /* New block after total_in > X */ + uint32_t dht_threshold; /* New block only if avail_in >= X */ +}; + +#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state)) + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp) strm) { + return dfltcc_alloc_state(strm, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + dfltcc_reset_state(&dfltcc_state->common); + + /* Initialize tuning parameters */ + dfltcc_state->level_mask = DFLTCC_LEVEL_MASK; + dfltcc_state->block_size = DFLTCC_BLOCK_SIZE; + dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE; + dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src) { + dfltcc_copy_state(dst, src, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +static inline int dfltcc_can_deflate_with_params(PREFIX3(streamp) strm, int level, uInt window_bits, int strategy, + int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + /* Unsupported compression settings */ + if ((dfltcc_state->level_mask & (1 << level)) == 0) + return 0; + if (window_bits != HB_BITS) + return 0; + if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) + return 0; + if (reproducible) + return 0; + + /* Unsupported hardware */ + if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) || + !is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) || + !is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0)) + return 0; + + return 1; +} + +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + + return dfltcc_can_deflate_with_params(strm, state->level, state->w_bits, state->strategy, state->reproducible); +} + +static inline void dfltcc_gdht(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + + dfltcc(DFLTCC_GDHT, param, NULL, NULL, &strm->next_in, &avail_in, NULL); +} + +static inline dfltcc_cc dfltcc_cmpr(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->total_in += (strm->avail_in - avail_in); + strm->total_out += (strm->avail_out - avail_out); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +static inline void send_eobs(PREFIX3(streamp) strm, const struct dfltcc_param_v0 *param) { + deflate_state *state = (deflate_state *)strm->state; + + send_bits(state, PREFIX(bi_reverse)(param->eobs >> (15 - param->eobl), param->eobl), param->eobl, state->bi_buf, state->bi_valid); + PREFIX(flush_pending)(strm); + if (state->pending != 0) { + /* The remaining data is located in pending_out[0:pending]. If someone + * calls put_byte() - this might happen in deflate() - the byte will be + * placed into pending_buf[pending], which is incorrect. Move the + * remaining data to the beginning of pending_buf so that put_byte() is + * usable again. + */ + memmove(state->pending_buf, state->pending_out, state->pending); + state->pending_out = state->pending_buf; + } +#ifdef ZLIB_DEBUG + state->compressed_len += param->eobl; +#endif +} + +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->common.param; + uInt masked_avail_in; + dfltcc_cc cc; + int need_empty_block; + int soft_bcc; + int no_flush; + + if (!PREFIX(dfltcc_can_deflate)(strm)) { + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + return 0; + } + +again: + masked_avail_in = 0; + soft_bcc = 0; + no_flush = flush == Z_NO_FLUSH; + + /* No input data. Return, except when Continuation Flag is set, which means + * that DFLTCC has buffered some output in the parameter block and needs to + * be called again in order to flush it. + */ + if (strm->avail_in == 0 && !param->cf) { + /* A block is still open, and the hardware does not support closing + * blocks without adding data. Thus, close it manually. + */ + if (!no_flush && param->bcf) { + send_eobs(strm, param); + param->bcf = 0; + } + /* Let one of deflate_* functions write a trailing empty block. */ + if (flush == Z_FINISH) + return 0; + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + /* Trigger block post-processing if necessary. */ + *result = no_flush ? need_more : block_done; + return 1; + } + + /* There is an open non-BFINAL block, we are not going to close it just + * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see + * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new + * DHT in order to adapt to a possibly changed input data distribution. + */ + if (param->bcf && no_flush && + strm->total_in > dfltcc_state->block_threshold && + strm->avail_in >= dfltcc_state->dht_threshold) { + if (param->cf) { + /* We need to flush the DFLTCC buffer before writing the + * End-of-block Symbol. Mask the input data and proceed as usual. + */ + masked_avail_in += strm->avail_in; + strm->avail_in = 0; + no_flush = 0; + } else { + /* DFLTCC buffer is empty, so we can manually write the + * End-of-block Symbol right away. + */ + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } + } + + /* No space for compressed data. If we proceed, dfltcc_cmpr() will return + * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still + * set BCF=1, which is wrong. Avoid complications and return early. + */ + if (strm->avail_out == 0) { + *result = need_more; + return 1; + } + + /* The caller gave us too much data. Pass only one block worth of + * uncompressed data to DFLTCC and mask the rest, so that on the next + * iteration we start a new block. + */ + if (no_flush && strm->avail_in > dfltcc_state->block_size) { + masked_avail_in += (strm->avail_in - dfltcc_state->block_size); + strm->avail_in = dfltcc_state->block_size; + } + + /* When we have an open non-BFINAL deflate block and caller indicates that + * the stream is ending, we need to close an open deflate block and open a + * BFINAL one. + */ + need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; + + /* Translate stream to parameter block */ + param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; + if (!no_flush) + /* We need to close a block. Always do this in software - when there is + * no input data, the hardware will not honor BCC. */ + soft_bcc = 1; + if (flush == Z_FINISH && !param->bcf) + /* We are about to open a BFINAL block, set Block Header Final bit + * until the stream ends. + */ + param->bhf = 1; + /* DFLTCC-CMPR will write to next_out, so make sure that buffers with + * higher precedence are empty. + */ + Assert(state->pending == 0, "There must be no pending bytes"); + Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); + param->sbb = (unsigned int)state->bi_valid; + if (param->sbb > 0) + *strm->next_out = (unsigned char)state->bi_buf; + /* Honor history and check value */ + param->nt = 0; + if (state->wrap == 1) + param->cv = strm->adler; + else if (state->wrap == 2) + param->cv = ZSWAP32(state->crc_fold.value); + + /* When opening a block, choose a Huffman-Table Type */ + if (!param->bcf) { + if (state->strategy == Z_FIXED || (strm->total_in == 0 && dfltcc_state->block_threshold > 0)) + param->htt = HTT_FIXED; + else { + param->htt = HTT_DYNAMIC; + dfltcc_gdht(strm); + } + } + + /* Deflate */ + do { + cc = dfltcc_cmpr(strm); + if (strm->avail_in < 4096 && masked_avail_in > 0) + /* We are about to call DFLTCC with a small input buffer, which is + * inefficient. Since there is masked data, there will be at least + * one more DFLTCC call, so skip the current one and make the next + * one handle more data. + */ + break; + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc); + state->bi_valid = param->sbb; + if (state->bi_valid == 0) + state->bi_buf = 0; /* Avoid accessing next_out */ + else + state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); + if (state->wrap == 1) + strm->adler = param->cv; + else if (state->wrap == 2) + state->crc_fold.value = ZSWAP32(param->cv); + + /* Unmask the input data */ + strm->avail_in += masked_avail_in; + masked_avail_in = 0; + + /* If we encounter an error, it means there is a bug in DFLTCC call */ + Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); + + /* Update Block-Continuation Flag. It will be used to check whether to call + * GDHT the next time. + */ + if (cc == DFLTCC_CC_OK) { + if (soft_bcc) { + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } else + param->bcf = 1; + if (flush == Z_FINISH) { + if (need_empty_block) + /* Make the current deflate() call also close the stream */ + return 0; + else { + bi_windup(state); + *result = finish_done; + } + } else { + if (flush == Z_FULL_FLUSH) + param->hl = 0; /* Clear history */ + *result = flush == Z_NO_FLUSH ? need_more : block_done; + } + } else { + param->bcf = 1; + *result = need_more; + } + if (strm->avail_in != 0 && strm->avail_out != 0) + goto again; /* deflate() must use all input or all output */ + return 1; +} + +/* + Switching between hardware and software compression. + + DFLTCC does not support all zlib settings, e.g. generation of non-compressed + blocks or alternative window sizes. When such settings are applied on the + fly with deflateParams, we need to convert between hardware and software + window formats. +*/ +static int dfltcc_was_deflate_used(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return strm->total_in > 0 || param->nt == 0 || param->hl > 0; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush) { + deflate_state *state = (deflate_state *)strm->state; + int could_deflate = PREFIX(dfltcc_can_deflate)(strm); + int can_deflate = dfltcc_can_deflate_with_params(strm, level, state->w_bits, strategy, state->reproducible); + + if (can_deflate == could_deflate) + /* We continue to work in the same mode - no changes needed */ + return Z_OK; + + if (!dfltcc_was_deflate_used(strm)) + /* DFLTCC was not used yet - no changes needed */ + return Z_OK; + + /* For now, do not convert between window formats - simply get rid of the old data instead */ + *flush = Z_FULL_FLUSH; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might + * close the block without resetting the compression state. Detect this + * situation and return that deflation is not done. + */ + if (flush == Z_FULL_FLUSH && strm->avail_out == 0) + return 0; + + /* Return that deflation is not done if DFLTCC is used and either it + * buffered some data (Continuation Flag is set), or has not written EOBS + * yet (Block-Continuation Flag is set). + */ + return !PREFIX(dfltcc_can_deflate)(strm) || (!param->cf && !param->bcf); +} + +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + + return reproducible != state->reproducible && !dfltcc_was_deflate_used(strm); +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + append_history(param, state->window, dictionary, dict_length); + state->strstart = 1; /* Add FDICT to zlib header */ + state->block_start = state->strstart; /* Make deflate_stored happy */ + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt *dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.h new file mode 100644 index 000000000..cb261b156 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_deflate.h @@ -0,0 +1,60 @@ +#ifndef DFLTCC_DEFLATE_H +#define DFLTCC_DEFLATE_H + +#include "dfltcc_common.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src); +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result); +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush); +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush); +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible); +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_DEFLATE_STATE PREFIX(dfltcc_alloc_deflate_state) +#define ZCOPY_DEFLATE_STATE PREFIX(dfltcc_copy_deflate_state) + +#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_deflate_state) + +#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ + do { \ + int err; \ +\ + err = PREFIX(dfltcc_deflate_params)((strm), (level), (strategy), (hook_flush)); \ + if (err == Z_STREAM_ERROR) \ + return err; \ + } while (0) + +#define DEFLATE_DONE PREFIX(dfltcc_deflate_done) + +#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ + do { \ + if (deflateStateCheck((strm)) || PREFIX(dfltcc_can_deflate)((strm))) \ + (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ + } while (0) + +#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_HOOK PREFIX(dfltcc_deflate) + +#define DEFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_CAN_SET_REPRODUCIBLE PREFIX(dfltcc_can_set_reproducible) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_detail.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_detail.h new file mode 100644 index 000000000..354c2f555 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_detail.h @@ -0,0 +1,312 @@ +#include "../../zbuild.h" +#include + +#ifdef HAVE_SYS_SDT_H +#include +#endif + +/* + Tuning parameters. + */ +#ifndef DFLTCC_LEVEL_MASK +#define DFLTCC_LEVEL_MASK 0x2 +#endif +#ifndef DFLTCC_BLOCK_SIZE +#define DFLTCC_BLOCK_SIZE 1048576 +#endif +#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE +#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 +#endif +#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE +#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 +#endif +#ifndef DFLTCC_RIBM +#define DFLTCC_RIBM 0 +#endif + +/* + Parameter Block for Query Available Functions. + */ +#define static_assert(c, msg) __attribute__((unused)) static char static_assert_failed_ ## msg[c ? 1 : -1] + +struct dfltcc_qaf_param { + char fns[16]; + char reserved1[8]; + char fmts[2]; + char reserved2[6]; +}; + +#define DFLTCC_SIZEOF_QAF 32 +static_assert(sizeof(struct dfltcc_qaf_param) == DFLTCC_SIZEOF_QAF, qaf); + +static inline int is_bit_set(const char *bits, int n) { + return bits[n / 8] & (1 << (7 - (n % 8))); +} + +static inline void clear_bit(char *bits, int n) { + bits[n / 8] &= ~(1 << (7 - (n % 8))); +} + +#define DFLTCC_FACILITY 151 + +static inline int is_dfltcc_enabled(void) { + uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; + Z_REGISTER uint8_t r0 __asm__("r0"); + + memset(facilities, 0, sizeof(facilities)); + r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; + /* STFLE is supported since z9-109 and only in z/Architecture mode. When + * compiling with -m31, gcc defaults to ESA mode, however, since the kernel + * is 64-bit, it's always z/Architecture mode at runtime. + */ + __asm__ volatile( +#ifndef __clang__ + ".machinemode push\n" + ".machinemode zarch\n" +#endif + "stfle %[facilities]\n" +#ifndef __clang__ + ".machinemode pop\n" +#endif + : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc"); + return is_bit_set((const char *)facilities, DFLTCC_FACILITY); +} + +#define DFLTCC_FMT0 0 + +/* + Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. + */ +#define CVT_CRC32 0 +#define CVT_ADLER32 1 +#define HTT_FIXED 0 +#define HTT_DYNAMIC 1 + +struct dfltcc_param_v0 { + uint16_t pbvn; /* Parameter-Block-Version Number */ + uint8_t mvn; /* Model-Version Number */ + uint8_t ribm; /* Reserved for IBM use */ + uint32_t reserved32 : 31; + uint32_t cf : 1; /* Continuation Flag */ + uint8_t reserved64[8]; + uint32_t nt : 1; /* New Task */ + uint32_t reserved129 : 1; + uint32_t cvt : 1; /* Check Value Type */ + uint32_t reserved131 : 1; + uint32_t htt : 1; /* Huffman-Table Type */ + uint32_t bcf : 1; /* Block-Continuation Flag */ + uint32_t bcc : 1; /* Block Closing Control */ + uint32_t bhf : 1; /* Block Header Final */ + uint32_t reserved136 : 1; + uint32_t reserved137 : 1; + uint32_t dhtgc : 1; /* DHT Generation Control */ + uint32_t reserved139 : 5; + uint32_t reserved144 : 5; + uint32_t sbb : 3; /* Sub-Byte Boundary */ + uint8_t oesc; /* Operation-Ending-Supplemental Code */ + uint32_t reserved160 : 12; + uint32_t ifs : 4; /* Incomplete-Function Status */ + uint16_t ifl; /* Incomplete-Function Length */ + uint8_t reserved192[8]; + uint8_t reserved256[8]; + uint8_t reserved320[4]; + uint16_t hl; /* History Length */ + uint32_t reserved368 : 1; + uint16_t ho : 15; /* History Offset */ + uint32_t cv; /* Check Value */ + uint32_t eobs : 15; /* End-of-block Symbol */ + uint32_t reserved431: 1; + uint8_t eobl : 4; /* End-of-block Length */ + uint32_t reserved436 : 12; + uint32_t reserved448 : 4; + uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table + Length */ + uint8_t reserved464[6]; + uint8_t cdht[288]; /* Compressed-Dynamic-Huffman Table */ + uint8_t reserved[24]; + uint8_t ribm2[8]; /* Reserved for IBM use */ + uint8_t csb[1152]; /* Continuation-State Buffer */ +}; + +#define DFLTCC_SIZEOF_GDHT_V0 384 +#define DFLTCC_SIZEOF_CMPR_XPND_V0 1536 +static_assert(offsetof(struct dfltcc_param_v0, csb) == DFLTCC_SIZEOF_GDHT_V0, gdht_v0); +static_assert(sizeof(struct dfltcc_param_v0) == DFLTCC_SIZEOF_CMPR_XPND_V0, cmpr_xpnd_v0); + +static inline z_const char *oesc_msg(char *buf, int oesc) { + if (oesc == 0x00) + return NULL; /* Successful completion */ + else { + sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); + return buf; + } +} + +/* + C wrapper for the DEFLATE CONVERSION CALL instruction. + */ +typedef enum { + DFLTCC_CC_OK = 0, + DFLTCC_CC_OP1_TOO_SHORT = 1, + DFLTCC_CC_OP2_TOO_SHORT = 2, + DFLTCC_CC_OP2_CORRUPT = 2, + DFLTCC_CC_AGAIN = 3, +} dfltcc_cc; + +#define DFLTCC_QAF 0 +#define DFLTCC_GDHT 1 +#define DFLTCC_CMPR 2 +#define DFLTCC_XPND 4 +#define HBT_CIRCULAR (1 << 7) +#define DFLTCC_FN_MASK ((1 << 7) - 1) +#define HB_BITS 15 +#define HB_SIZE (1 << HB_BITS) + +static inline dfltcc_cc dfltcc(int fn, void *param, + unsigned char **op1, size_t *len1, + z_const unsigned char **op2, size_t *len2, void *hist) { + unsigned char *t2 = op1 ? *op1 : NULL; +#ifdef Z_MEMORY_SANITIZER + unsigned char *orig_t2 = t2; +#endif + size_t t3 = len1 ? *len1 : 0; + z_const unsigned char *t4 = op2 ? *op2 : NULL; + size_t t5 = len2 ? *len2 : 0; + Z_REGISTER int r0 __asm__("r0") = fn; + Z_REGISTER void *r1 __asm__("r1") = param; + Z_REGISTER unsigned char *r2 __asm__("r2") = t2; + Z_REGISTER size_t r3 __asm__("r3") = t3; + Z_REGISTER z_const unsigned char *r4 __asm__("r4") = t4; + Z_REGISTER size_t r5 __asm__("r5") = t5; + int cc; + + __asm__ volatile( +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_entry, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_exit, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + "ipm %[cc]\n" + : [r2] "+r" (r2) + , [r3] "+r" (r3) + , [r4] "+r" (r4) + , [r5] "+r" (r5) + , [cc] "=r" (cc) + : [r0] "r" (r0) + , [r1] "r" (r1) + , [hist] "r" (hist) +#ifdef HAVE_SYS_SDT_H + , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist) +#endif + : "cc", "memory"); + t2 = r2; t3 = r3; t4 = r4; t5 = r5; + +#ifdef Z_MEMORY_SANITIZER + switch (fn & DFLTCC_FN_MASK) { + case DFLTCC_QAF: + __msan_unpoison(param, DFLTCC_SIZEOF_QAF); + break; + case DFLTCC_GDHT: + __msan_unpoison(param, DFLTCC_SIZEOF_GDHT_V0); + break; + case DFLTCC_CMPR: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2 + (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1)); + break; + case DFLTCC_XPND: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2); + break; + } +#endif + + if (op1) + *op1 = t2; + if (len1) + *len1 = t3; + if (op2) + *op2 = t4; + if (len2) + *len2 = t5; + return (cc >> 28) & 3; +} + +/* + Extension of inflate_state and deflate_state. Must be doubleword-aligned. +*/ +struct dfltcc_state { + struct dfltcc_param_v0 param; /* Parameter block. */ + struct dfltcc_qaf_param af; /* Available functions. */ + char msg[64]; /* Buffer for strm->msg */ +}; + +#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1)) + +#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8))) + +static inline void *dfltcc_alloc_state(PREFIX3(streamp) strm, uInt size, uInt extension_size) { + return ZALLOC(strm, 1, ALIGN_UP(size, 8) + extension_size); +} + +static inline void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) { + /* Initialize available functions */ + if (is_dfltcc_enabled()) { + dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL); + memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af)); + } else + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + + /* Initialize parameter block */ + memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); + dfltcc_state->param.nt = 1; + dfltcc_state->param.ribm = DFLTCC_RIBM; +} + +static inline void dfltcc_copy_state(void *dst, const void *src, uInt size, uInt extension_size) { + memcpy(dst, src, ALIGN_UP(size, 8) + extension_size); +} + +static inline void append_history(struct dfltcc_param_v0 *param, unsigned char *history, + const unsigned char *buf, uInt count) { + size_t offset; + size_t n; + + /* Do not use more than 32K */ + if (count > HB_SIZE) { + buf += count - HB_SIZE; + count = HB_SIZE; + } + offset = (param->ho + param->hl) % HB_SIZE; + if (offset + count <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(history + offset, buf, count); + else { + /* Circular history buffer wraps - copy two chunks */ + n = HB_SIZE - offset; + memcpy(history + offset, buf, n); + memcpy(history, buf + n, count - n); + } + n = param->hl + count; + if (n <= HB_SIZE) + /* All history fits into buffer - no need to discard anything */ + param->hl = n; + else { + /* History does not fit into buffer - discard extra bytes */ + param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE; + param->hl = HB_SIZE; + } +} + +static inline void get_history(struct dfltcc_param_v0 *param, const unsigned char *history, + unsigned char *buf) { + if (param->ho + param->hl <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(buf, history + param->ho, param->hl); + else { + /* Circular history buffer wraps - copy two chunks */ + memcpy(buf, history + param->ho, HB_SIZE - param->ho); + memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE); + } +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.c new file mode 100644 index 000000000..f0d3951b5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.c @@ -0,0 +1,205 @@ +/* dfltcc_inflate.c - IBM Z DEFLATE CONVERSION CALL decompression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC decompression support: + + $ ./configure --with-dfltcc-inflate + or + + $ cmake -DWITH_DFLTCC_INFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "dfltcc_inflate.h" +#include "dfltcc_detail.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm) { + return (struct inflate_state *)dfltcc_alloc_state(strm, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + dfltcc_reset_state(dfltcc_state); +} + +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src) { + dfltcc_copy_state(dst, src, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + /* Unsupported hardware */ + return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); +} + +static inline dfltcc_cc dfltcc_xpnd(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + dfltcc_cc cc; + + if (flush == Z_BLOCK || flush == Z_TREES) { + /* DFLTCC does not support stopping on block boundaries */ + if (PREFIX(dfltcc_inflate_disable)(strm)) { + *ret = Z_STREAM_ERROR; + return DFLTCC_INFLATE_BREAK; + } else + return DFLTCC_INFLATE_SOFTWARE; + } + + if (state->last) { + if (state->bits != 0) { + strm->next_in++; + strm->avail_in--; + state->bits = 0; + } + state->mode = CHECK; + return DFLTCC_INFLATE_CONTINUE; + } + + if (strm->avail_in == 0 && !param->cf) + return DFLTCC_INFLATE_BREAK; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return DFLTCC_INFLATE_CONTINUE; + } + + /* Translate stream to parameter block */ + param->cvt = ((state->wrap & 4) && state->flags) ? CVT_CRC32 : CVT_ADLER32; + param->sbb = state->bits; + if (param->hl) + param->nt = 0; /* Honor history for the first block */ + if (state->wrap & 4) + param->cv = state->flags ? ZSWAP32(state->check) : state->check; + + /* Inflate */ + do { + cc = dfltcc_xpnd(strm); + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); + state->last = cc == DFLTCC_CC_OK; + state->bits = param->sbb; + if (state->wrap & 4) + strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv; + if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { + /* Report an error if stream is corrupted */ + state->mode = BAD; + return DFLTCC_INFLATE_CONTINUE; + } + state->mode = TYPEDO; + /* Break if operands are exhausted, otherwise continue looping */ + return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? + DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; +} + +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return !param->nt; +} + +/* + Rotates a circular buffer. + The implementation is based on https://cplusplus.com/reference/algorithm/rotate/ + */ +static void rotate(unsigned char *start, unsigned char *pivot, unsigned char *end) { + unsigned char *p = pivot; + unsigned char tmp; + + while (p != start) { + tmp = *start; + *start = *p; + *p = tmp; + + start++; + p++; + + if (p == end) + p = pivot; + else if (start == pivot) + pivot = p; + } +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (!PREFIX(dfltcc_can_inflate)(strm)) + return 0; + if (PREFIX(dfltcc_was_inflate_used)(strm)) + /* DFLTCC has already decompressed some data. Since there is not + * enough information to resume decompression in software, the call + * must fail. + */ + return 1; + /* DFLTCC was not used yet - decompress in software */ + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + /* Convert the window from the hardware to the software format */ + rotate(state->window, state->window + param->ho, state->window + HB_SIZE); + state->whave = state->wnext = MIN(param->hl, state->wsize); + return 0; +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + + append_history(param, state->window, dictionary, dict_length); + state->havedict = 1; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt *dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary && state->window) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.h new file mode 100644 index 000000000..632fada62 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/dfltcc_inflate.h @@ -0,0 +1,70 @@ +#ifndef DFLTCC_INFLATE_H +#define DFLTCC_INFLATE_H + +#include "dfltcc_common.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src); +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm); +typedef enum { + DFLTCC_INFLATE_CONTINUE, + DFLTCC_INFLATE_BREAK, + DFLTCC_INFLATE_SOFTWARE, +} dfltcc_inflate_action; +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret); +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_INFLATE_STATE PREFIX(dfltcc_alloc_inflate_state) +#define ZCOPY_INFLATE_STATE PREFIX(dfltcc_copy_inflate_state) + +#define INFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_inflate_state) + +#define INFLATE_PRIME_HOOK(strm, bits, value) \ + do { if (PREFIX(dfltcc_inflate_disable)((strm))) return Z_STREAM_ERROR; } while (0) + +#define INFLATE_TYPEDO_HOOK(strm, flush) \ + if (PREFIX(dfltcc_can_inflate)((strm))) { \ + dfltcc_inflate_action action; \ +\ + RESTORE(); \ + action = PREFIX(dfltcc_inflate)((strm), (flush), &ret); \ + LOAD(); \ + if (action == DFLTCC_INFLATE_CONTINUE) \ + break; \ + else if (action == DFLTCC_INFLATE_BREAK) \ + goto inf_leave; \ + } + +#define INFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_NEED_UPDATEWINDOW(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_MARK_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return -(1L << 16); \ + } while (0) + +#define INFLATE_SYNC_POINT_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return Z_STREAM_ERROR; \ + } while (0) + +#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.c new file mode 100644 index 000000000..82901060e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.c @@ -0,0 +1,14 @@ +#include "../../zbuild.h" +#include "s390_features.h" + +#ifdef HAVE_SYS_AUXV_H +# include +#endif + +#ifndef HWCAP_S390_VXRS +#define HWCAP_S390_VXRS HWCAP_S390_VX +#endif + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features) { + features->has_vx = getauxval(AT_HWCAP) & HWCAP_S390_VXRS; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.h new file mode 100644 index 000000000..b8ffef74d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/s390_features.h @@ -0,0 +1,10 @@ +#ifndef S390_FEATURES_H_ +#define S390_FEATURES_H_ + +struct s390_cpu_features { + int has_vx; +}; + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.Dockerfile b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.Dockerfile new file mode 100644 index 000000000..136eec77a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.Dockerfile @@ -0,0 +1,45 @@ +# Self-Hosted IBM Z Github Actions Runner. + +# Temporary image: amd64 dependencies. +FROM amd64/ubuntu:20.04 as ld-prefix +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install ca-certificates libicu66 libssl1.1 + +# Main image. +FROM s390x/ubuntu:20.04 + +# Packages for zlib-ng testing. +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install \ + clang-11 \ + cmake \ + curl \ + gcc \ + git \ + jq \ + libxml2-dev \ + libxslt-dev \ + llvm-11-tools \ + ninja-build \ + python-is-python3 \ + python3 \ + python3-dev \ + python3-pip + +# amd64 dependencies. +COPY --from=ld-prefix / /usr/x86_64-linux-gnu/ +RUN ln -fs ../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /usr/x86_64-linux-gnu/lib64/ +RUN ln -fs /etc/resolv.conf /usr/x86_64-linux-gnu/etc/ +ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu + +# amd64 Github Actions Runner. +RUN useradd -m actions-runner +USER actions-runner +WORKDIR /home/actions-runner +RUN curl -L https://github.com/actions/runner/releases/download/v2.287.1/actions-runner-linux-x64-2.287.1.tar.gz | tar -xz +VOLUME /home/actions-runner + +# Scripts. +COPY fs/ / +ENTRYPOINT ["/usr/bin/entrypoint"] +CMD ["/usr/bin/actions-runner"] diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.service b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.service new file mode 100644 index 000000000..71053a79d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/actions-runner.service @@ -0,0 +1,24 @@ +[Unit] +Description=Self-Hosted IBM Z Github Actions Runner +Wants=qemu-user-static +After=qemu-user-static +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +ExecStartPre=-/usr/bin/docker rm --force actions-runner +ExecStart=/usr/bin/docker run \ + --env-file=/etc/actions-runner \ + --init \ + --interactive \ + --name=actions-runner \ + --rm \ + --volume=actions-runner:/home/actions-runner \ + iiilinuxibmcom/actions-runner +ExecStop=/bin/sh -c "docker exec actions-runner kill -INT -- -1" +ExecStop=/bin/sh -c "docker wait actions-runner" +ExecStop=/bin/sh -c "docker rm actions-runner" + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner new file mode 100755 index 000000000..c9d8227d4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Ephemeral runner startup script. +# +# Expects the following environment variables: +# +# - repo=/ +# - access_token= +# + +set -e -u + +# Check the cached registration token. +token_file=registration-token.json +set +e +expires_at=$(jq --raw-output .expires_at "$token_file" 2>/dev/null) +status=$? +set -e +if [[ $status -ne 0 || $(date +%s) -ge $(date -d "$expires_at" +%s) ]]; then + # Refresh the cached registration token. + curl \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $access_token" \ + "https://api.github.com/repos/$repo/actions/runners/registration-token" \ + -o "$token_file" +fi + +# (Re-)register the runner. +registration_token=$(jq --raw-output .token "$token_file") +./config.sh remove --token "$registration_token" || true +./config.sh \ + --url "https://github.com/$repo" \ + --token "$registration_token" \ + --labels z15 \ + --ephemeral + +# Run one job. +./run.sh diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint new file mode 100755 index 000000000..eb8772bec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint @@ -0,0 +1,30 @@ +#!/bin/bash + +# +# Container entrypoint that waits for all spawned processes. +# + +set -e -u + +# Create a FIFO and start reading from its read end. +tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX") +trap 'rm -r "$tempdir"' EXIT +done="$tempdir/pipe" +mkfifo "$done" +cat "$done" & waiter=$! + +# Start the workload. Its descendants will inherit the FIFO's write end. +status=0 +if [ "$#" -eq 0 ]; then + bash 9>"$done" || status=$? +else + "$@" 9>"$done" || status=$? +fi + +# When the workload and all of its descendants exit, the FIFO's write end will +# be closed and `cat "$done"` will exit. Wait until it happens. This is needed +# in order to handle SelfUpdater, which the workload may start in background +# before exiting. +wait "$waiter" + +exit "$status" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/qemu-user-static.service b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/qemu-user-static.service new file mode 100644 index 000000000..301f3edd9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/s390/self-hosted-builder/qemu-user-static.service @@ -0,0 +1,11 @@ +[Unit] +Description=Support for transparent execution of non-native binaries with QEMU user emulation + +[Service] +Type=oneshot +# The source code for iiilinuxibmcom/qemu-user-static is at https://github.com/iii-i/qemu-user-static/tree/v6.1.0-1 +# TODO: replace it with multiarch/qemu-user-static once version >6.1 is available +ExecStart=/usr/bin/docker run --rm --interactive --privileged iiilinuxibmcom/qemu-user-static --reset -p yes + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/Makefile.in new file mode 100644 index 000000000..f0478bfdc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/Makefile.in @@ -0,0 +1,147 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +AVX512FLAG=-mavx512f -mavx512dq -mavx512vl -mavx512bw +AVX512VNNIFLAG=-mavx512vnni +AVX2FLAG=-mavx2 +SSE2FLAG=-msse2 +SSSE3FLAG=-mssse3 +SSE42FLAG=-msse4.2 +PCLMULFLAG=-mpclmul +VPCLMULFLAG=-mvpclmulqdq +XSAVEFLAG=-mxsave +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + x86_features.o x86_features.lo \ + adler32_avx2.o adler32_avx2.lo \ + adler32_avx512.o adler32_avx512.lo \ + adler32_avx512_vnni.o adler32_avx512_vnni.lo \ + adler32_sse42.o adler32_sse42.lo \ + adler32_ssse3.o adler32_ssse3.lo \ + chunkset_avx2.o chunkset_avx2.lo \ + chunkset_sse2.o chunkset_sse2.lo \ + chunkset_ssse3.o chunkset_ssse3.lo \ + compare256_avx2.o compare256_avx2.lo \ + compare256_sse2.o compare256_sse2.lo \ + insert_string_sse42.o insert_string_sse42.lo \ + crc32_pclmulqdq.o crc32_pclmulqdq.lo \ + crc32_vpclmulqdq.o crc32_vpclmulqdq.lo \ + slide_hash_avx2.o slide_hash_avx2.lo \ + slide_hash_sse2.o slide_hash_sse2.lo + +x86_features.o: + $(CC) $(CFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +x86_features.lo: + $(CC) $(SFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +chunkset_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_ssse3.o: + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +chunkset_ssse3.lo: + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +compare256_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +compare256_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +insert_string_sse42.o: + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +insert_string_sse42.lo: + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +crc32_pclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_pclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_vpclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +crc32_vpclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +slide_hash_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +slide_hash_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +adler32_avx2.o: $(SRCDIR)/adler32_avx2.c + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx2.lo: $(SRCDIR)/adler32_avx2.c + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx512.o: $(SRCDIR)/adler32_avx512.c + $(CC) $(CFLAGS) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512.lo: $(SRCDIR)/adler32_avx512.c + $(CC) $(SFLAGS) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512_vnni.o: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(CFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_avx512_vnni.lo: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(SFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_ssse3.o: $(SRCDIR)/adler32_ssse3.c + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_ssse3.lo: $(SRCDIR)/adler32_ssse3.c + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_sse42.o: $(SRCDIR)/adler32_sse42.c + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +adler32_sse42.lo: $(SRCDIR)/adler32_sse42.c + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2.c new file mode 100644 index 000000000..797d299e0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2.c @@ -0,0 +1,17 @@ +/* adler32_avx2.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#ifdef X86_AVX2 + +#include "adler32_avx2_tpl.h" + +#define COPY +#include "adler32_avx2_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_p.h new file mode 100644 index 000000000..f0f8a4a88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_p.h @@ -0,0 +1,32 @@ +/* adler32_avx2_p.h -- adler32 avx2 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_AVX2_P_H_ +#define ADLER32_AVX2_P_H_ + +#if defined(X86_AVX2) || defined(X86_AVX512VNNI) + +/* 32 bit horizontal sum, adapted from Agner Fog's vector library. */ +static inline uint32_t hsum256(__m256i x) { + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(x, 1), + _mm256_castsi256_si128(x)); + __m128i sum2 = _mm_add_epi32(sum1, _mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +static inline uint32_t partial_hsum256(__m256i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros */ + const __m256i perm_vec = _mm256_setr_epi32(0, 2, 4, 6, 1, 1, 1, 1); + __m256i non_zero = _mm256_permutevar8x32_epi32(x, perm_vec); + __m128i non_zero_sse = _mm256_castsi256_si128(non_zero); + __m128i sum2 = _mm_add_epi32(non_zero_sse,_mm_unpackhi_epi64(non_zero_sse, non_zero_sse)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_tpl.h new file mode 100644 index 000000000..a94f44b4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx2_tpl.h @@ -0,0 +1,141 @@ +/* adler32_avx2_tpl.h -- adler32 avx2 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include +#include "../../adler32_fold.h" +#include "../../adler32_p.h" +#include "../../fallback_builtins.h" +#include "adler32_avx2_p.h" + +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *src, size_t len); + +#define copy_sub32(a, b, c, d) adler32_fold_copy_sse42(a, b, c, d) +#define sub32(a, b, c) adler32_ssse3(a, b, c) +#else +#define copy_sub32(a, b, c, d) adler32_copy_len_16(adler0, c, b, d, adler1) +#define sub32(a, b, c) adler32_len_16(adler0, b, c, adler1) +#endif + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx2(uint32_t adler, const uint8_t *src, size_t len) { +#endif + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { +#ifdef COPY + return adler32_copy_len_16(adler0, src, dst, len, adler1); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } else if (len < 32) { +#ifdef COPY + return copy_sub32(adler, dst, src, len); +#else + return sub32(adler, src, len); +#endif + } + + __m256i vs1, vs2; + + const __m256i dot2v = _mm256_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m256i dot3v = _mm256_set1_epi16(1); + const __m256i zero = _mm256_setzero_si256(); + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 32 vs1 + sum( (32-i+1) c[i] ) + */ + __m256i vbuf = _mm256_loadu_si256((__m256i*)src); + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf, zero); // Sum of abs diff, resulting in 2 x int32's + // +#ifdef COPY + _mm256_storeu_si256((__m256i*)dst, vbuf); + dst += 32; +#endif + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + __m256i v_short_sum2 = _mm256_maddubs_epi16(vbuf, dot2v); // sum 32 uint8s to 16 shorts + __m256i vsum2 = _mm256_madd_epi16(v_short_sum2, dot3v); // sum 16 shorts to 8 uint32s + vs2 = _mm256_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + /* Defer the multiplication with 32 to outside of the loop */ + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + + /* The compiler is generating the following sequence for this integer modulus + * when done the scalar way, in GPRs: + + adler = (s1_unpack[0] % BASE) + (s1_unpack[1] % BASE) + (s1_unpack[2] % BASE) + (s1_unpack[3] % BASE) + + (s1_unpack[4] % BASE) + (s1_unpack[5] % BASE) + (s1_unpack[6] % BASE) + (s1_unpack[7] % BASE); + + mov $0x80078071,%edi // move magic constant into 32 bit register %edi + ... + vmovd %xmm1,%esi // move vector lane 0 to 32 bit register %esi + mov %rsi,%rax // zero-extend this value to 64 bit precision in %rax + imul %rdi,%rsi // do a signed multiplication with magic constant and vector element + shr $0x2f,%rsi // shift right by 47 + imul $0xfff1,%esi,%esi // do a signed multiplication with value truncated to 32 bits with 0xfff1 + sub %esi,%eax // subtract lower 32 bits of original vector value from modified one above + ... + // repeats for each element with vpextract instructions + + This is tricky with AVX2 for a number of reasons: + 1.) There's no 64 bit multiplication instruction, but there is a sequence to get there + 2.) There's ways to extend vectors to 64 bit precision, but no simple way to truncate + back down to 32 bit precision later (there is in AVX512) + 3.) Full width integer multiplications aren't cheap + + We can, however, and do a relatively cheap sequence for horizontal sums. + Then, we simply do the integer modulus on the resulting 64 bit GPR, on a scalar value. It was + previously thought that casting to 64 bit precision was needed prior to the horizontal sum, but + that is simply not the case, as NMAX is defined as the maximum number of scalar sums that can be + performed on the maximum possible inputs before overflow + */ + + + /* In AVX2-land, this trip through GPRs will probably be unvoidable, as there's no cheap and easy + * conversion from 64 bit integer to 32 bit (needed for the inexpensive modulus with a constant). + * This casting to 32 bit is cheap through GPRs (just register aliasing). See above for exactly + * what the compiler is doing to avoid integer divisions. */ + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + if (len) { + goto rem_peel; + } + + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512.c new file mode 100644 index 000000000..e6ebb05dc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512.c @@ -0,0 +1,16 @@ +/* adler32_avx512.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512 + +#include "adler32_avx512_tpl.h" + +#define COPY +#include "adler32_avx512_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_p.h new file mode 100644 index 000000000..5b79d2ab6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_p.h @@ -0,0 +1,46 @@ +#ifndef AVX512_FUNCS_H +#define AVX512_FUNCS_H + +#include +#include +/* Written because *_add_epi32(a) sets off ubsan */ +static inline uint32_t _mm512_reduce_add_epu32(__m512i x) { + __m256i a = _mm512_extracti64x4_epi64(x, 1); + __m256i b = _mm512_extracti64x4_epi64(x, 0); + + __m256i a_plus_b = _mm256_add_epi32(a, b); + __m128i c = _mm256_extracti128_si256(a_plus_b, 1); + __m128i d = _mm256_extracti128_si256(a_plus_b, 0); + __m128i c_plus_d = _mm_add_epi32(c, d); + + __m128i sum1 = _mm_unpackhi_epi64(c_plus_d, c_plus_d); + __m128i sum2 = _mm_add_epi32(sum1, c_plus_d); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + + return _mm_cvtsi128_si32(sum4); +} + +static inline uint32_t partial_hsum(__m512i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros. Marking this const so the compiler stands + * a better chance of keeping this resident in a register through entire + * loop execution. We certainly have enough zmm registers (32) */ + const __m512i perm_vec = _mm512_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14, + 1, 1, 1, 1, 1, 1, 1, 1); + + __m512i non_zero = _mm512_permutexvar_epi32(perm_vec, x); + + /* From here, it's a simple 256 bit wide reduction sum */ + __m256i non_zero_avx = _mm512_castsi512_si256(non_zero); + + /* See Agner Fog's vectorclass for a decent reference. Essentially, phadd is + * pretty slow, much slower than the longer instruction sequence below */ + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(non_zero_avx, 1), + _mm256_castsi256_si128(non_zero_avx)); + __m128i sum2 = _mm_add_epi32(sum1,_mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2,_mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_tpl.h new file mode 100644 index 000000000..7546afef5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_tpl.h @@ -0,0 +1,106 @@ +/* adler32_avx512_tpl.h -- adler32 avx512 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "adler32_avx512_p.h" + +#ifdef X86_AVX512 + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx512(uint32_t adler, const uint8_t *src, size_t len) { +#endif + + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 64) { + /* This handles the remaining copies, just call normal adler checksum after this */ +#ifdef COPY + __mmask64 storemask = (0xFFFFFFFFFFFFFFFFUL >> (64 - len)); + __m512i copy_vec = _mm512_maskz_loadu_epi8(storemask, src); + _mm512_mask_storeu_epi8(dst, storemask, copy_vec); +#endif + +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + __m512i vbuf, vs1_0, vs3; + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + const __m512i dot3v = _mm512_set1_epi16(1); + const __m512i zero = _mm512_setzero_si512(); + size_t k; + + while (len >= 64) { + __m512i vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + __m512i vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + vs1_0 = vs1; + vs3 = _mm512_setzero_si512(); + + k = MIN(len, NMAX); + k -= k % 64; + len -= k; + + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf = _mm512_loadu_si512(src); +#ifdef COPY + _mm512_storeu_si512(dst, vbuf); + dst += 64; +#endif + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf, zero); + __m512i v_short_sum2 = _mm512_maddubs_epi16(vbuf, dot2v); + vs1 = _mm512_add_epi32(vs1_sad, vs1); + vs3 = _mm512_add_epi32(vs3, vs1_0); + __m512i vsum2 = _mm512_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm512_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_vnni.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_vnni.c new file mode 100644 index 000000000..8dcc93d05 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_avx512_vnni.c @@ -0,0 +1,225 @@ +/* adler32_avx512_vnni.c -- compute the Adler-32 checksum of a data stream + * Based on Brian Bockelman's AVX2 version + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512VNNI + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "../../adler32_fold.h" +#include "adler32_avx512_p.h" +#include "adler32_avx2_p.h" + +Z_INTERNAL uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 32) +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + if (len < 64) +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + + const __m512i zero = _mm512_setzero_si512(); + __m512i vs1, vs2; + + while (len >= 64) { + vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 64; + len -= k; + __m512i vs1_0 = vs1; + __m512i vs3 = _mm512_setzero_si512(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m512i vs2_1 = _mm512_setzero_si512(); + __m512i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 128) { + vbuf1 = _mm512_loadu_si512((__m512i*)src); + + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + vs2 = _mm512_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 128) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm512_loadu_si512((__m512i*)src); + vbuf1 = _mm512_loadu_si512((__m512i*)(src + 64)); + src += 128; + k -= 128; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf0, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm512_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm512_add_epi32(vs3, vs1); + vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs2_1 = _mm512_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + vs2 = _mm512_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +Z_INTERNAL uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel_copy: + if (len < 32) { + /* This handles the remaining copies, just call normal adler checksum after this */ + __mmask32 storemask = (0xFFFFFFFFUL >> (32 - len)); + __m256i copy_vec = _mm256_maskz_loadu_epi8(storemask, src); + _mm256_mask_storeu_epi8(dst, storemask, copy_vec); + +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + const __m256i dot2v = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); + + const __m256i zero = _mm256_setzero_si256(); + __m256i vs1, vs2; + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m256i vs2_1 = _mm256_setzero_si256(); + __m256i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 64) { + vbuf1 = _mm256_loadu_si256((__m256i*)src); + _mm256_storeu_si256((__m256i*)dst, vbuf1); + dst += 32; + + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + vs2 = _mm256_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm256_loadu_si256((__m256i*)src); + vbuf1 = _mm256_loadu_si256((__m256i*)(src + 32)); + _mm256_storeu_si256((__m256i*)dst, vbuf0); + _mm256_storeu_si256((__m256i*)(dst + 32), vbuf1); + dst += 64; + src += 64; + k -= 64; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf0, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm256_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm256_add_epi32(vs3, vs1); + vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs2_1 = _mm256_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + vs2 = _mm256_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel_copy; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_sse42.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_sse42.c new file mode 100644 index 000000000..257a36098 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_sse42.c @@ -0,0 +1,121 @@ +/* adler32_sse42.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "adler32_ssse3_p.h" +#include + +#ifdef X86_SSE42 + +Z_INTERNAL uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { + return adler32_copy_len_16(adler0, src, dst, len, adler1); + } + + __m128i vbuf, vbuf_0; + __m128i vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + v_sad_sum2, vsum2, vsum2_0; + __m128i zero = _mm_setzero_si128(); + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + size_t k; + + while (len >= 16) { + + k = MIN(len, NMAX); + k -= k % 16; + len -= k; + + vs1 = _mm_cvtsi32_si128(adler0); + vs2 = _mm_cvtsi32_si128(adler1); + + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + vbuf_0 = _mm_loadu_si128((__m128i*)(src + 16)); + src += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + _mm_storeu_si128((__m128i*)dst, vbuf); + _mm_storeu_si128((__m128i*)(dst + 16), vbuf_0); + dst += 32; + + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + vs2 = _mm_add_epi32(vsum2, vs2); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + src += 16; + k -= 16; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + + _mm_storeu_si128((__m128i*)dst, vbuf); + dst += 16; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = hsum(vs2) % BASE; + } + + /* If this is true, there's fewer than 16 elements remaining */ + if (len) { + goto rem_peel; + } + + return adler0 | (adler1 << 16); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3.c new file mode 100644 index 000000000..99ce79582 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3.c @@ -0,0 +1,156 @@ +/* adler32_ssse3.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "adler32_ssse3_p.h" + +#ifdef X86_SSSE3 + +#include + +Z_INTERNAL uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + const __m128i zero = _mm_setzero_si128(); + + __m128i vbuf, vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + vbuf_0, v_sad_sum2, vsum2, vsum2_0; + + /* If our buffer is unaligned (likely), make the determination whether + * or not there's enough of a buffer to consume to make the scalar, aligning + * additions worthwhile or if it's worth it to just eat the cost of an unaligned + * load. This is a pretty simple test, just test if 16 - the remainder + len is + * < 16 */ + size_t max_iters = NMAX; + size_t rem = (uintptr_t)buf & 15; + size_t align_offset = 16 - rem; + size_t k = 0; + if (rem) { + if (len < 16 + align_offset) { + /* Let's eat the cost of this one unaligned load so that + * we don't completely skip over the vectorization. Doing + * 16 bytes at a time unaligned is is better than 16 + <= 15 + * sums */ + vbuf = _mm_loadu_si128((__m128i*)buf); + len -= 16; + buf += 16; + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs1_0 = vs1; + goto unaligned_jmp; + } + + for (size_t i = 0; i < align_offset; ++i) { + adler += *(buf++); + sum2 += adler; + } + + /* lop off the max number of sums based on the scalar sums done + * above */ + len -= align_offset; + max_iters -= align_offset; + } + + + while (len >= 16) { + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + k = (len < max_iters ? len : max_iters); + k -= k % 16; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + vbuf_0 = _mm_load_si128((__m128i*)(buf + 16)); + buf += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + vs2 = _mm_add_epi32(vsum2, vs2); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + buf += 16; + k -= 16; + +unaligned_jmp: + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + /* We don't actually need to do a full horizontal sum, since psadbw is actually doing + * a partial reduction sum implicitly and only summing to integers in vector positions + * 0 and 2. This saves us some contention on the shuffle port(s) */ + adler = partial_hsum(vs1) % BASE; + sum2 = hsum(vs2) % BASE; + max_iters = NMAX; + } + + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3_p.h new file mode 100644 index 000000000..d7ec3fe0d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/adler32_ssse3_p.h @@ -0,0 +1,29 @@ +/* adler32_ssse3_p.h -- adler32 ssse3 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_SSSE3_P_H_ +#define ADLER32_SSSE3_P_H_ + +#ifdef X86_SSSE3 + +#include +#include + +static inline uint32_t partial_hsum(__m128i x) { + __m128i second_int = _mm_srli_si128(x, 8); + __m128i sum = _mm_add_epi32(x, second_int); + return _mm_cvtsi128_si32(sum); +} + +static inline uint32_t hsum(__m128i x) { + __m128i sum1 = _mm_unpackhi_epi64(x, x); + __m128i sum2 = _mm_add_epi32(x, sum1); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + return _mm_cvtsi128_si32(sum4); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_avx2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_avx2.c new file mode 100644 index 000000000..f309878b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_avx2.c @@ -0,0 +1,135 @@ +/* chunkset_avx2.c -- AVX2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" + +#ifdef X86_AVX2 +#include +#include "../generic/chunk_permute_table.h" + +typedef __m256i chunk_t; + +#define CHUNK_SIZE 32 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +/* Populate don't cares so that this is a direct lookup (with some indirection into the permute table), because dist can + * never be 0 - 2, we'll start with an offset, subtracting 3 from the input */ +static const lut_rem_pair perm_idx_lut[29] = { + { 0, 2}, /* 3 */ + { 0, 0}, /* don't care */ + { 1 * 32, 2}, /* 5 */ + { 2 * 32, 2}, /* 6 */ + { 3 * 32, 4}, /* 7 */ + { 0 * 32, 0}, /* don't care */ + { 4 * 32, 5}, /* 9 */ + { 5 * 32, 22}, /* 10 */ + { 6 * 32, 21}, /* 11 */ + { 7 * 32, 20}, /* 12 */ + { 8 * 32, 6}, /* 13 */ + { 9 * 32, 4}, /* 14 */ + {10 * 32, 2}, /* 15 */ + { 0 * 32, 0}, /* don't care */ + {11 * 32, 15}, /* 17 */ + {11 * 32 + 16, 14}, /* 18 */ + {11 * 32 + 16 * 2, 13}, /* 19 */ + {11 * 32 + 16 * 3, 12}, /* 20 */ + {11 * 32 + 16 * 4, 11}, /* 21 */ + {11 * 32 + 16 * 5, 10}, /* 22 */ + {11 * 32 + 16 * 6, 9}, /* 23 */ + {11 * 32 + 16 * 7, 8}, /* 24 */ + {11 * 32 + 16 * 8, 7}, /* 25 */ + {11 * 32 + 16 * 9, 6}, /* 26 */ + {11 * 32 + 16 * 10, 5}, /* 27 */ + {11 * 32 + 16 * 11, 4}, /* 28 */ + {11 * 32 + 16 * 12, 3}, /* 29 */ + {11 * 32 + 16 * 13, 2}, /* 30 */ + {11 * 32 + 16 * 14, 1} /* 31 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm256_loadu_si256((__m256i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm256_storeu_si256((__m256i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m256i ret_vec; + /* While technically we only need to read 4 or 8 bytes into this vector register for a lot of cases, GCC is + * compiling this to a shared load for all branches, preferring the simpler code. Given that the buf value isn't in + * GPRs to begin with the 256 bit load is _probably_ just as inexpensive */ + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 32 - dist); +#endif + + if (dist < 16) { + /* This simpler case still requires us to shuffle in 128 bit lanes, so we must apply a static offset after + * broadcasting the first vector register to both halves. This is _marginally_ faster than doing two separate + * shuffles and combining the halves later */ + const __m256i permute_xform = + _mm256_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16); + __m256i perm_vec = _mm256_load_si256((__m256i*)(permute_table+lut_rem.idx)); + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + perm_vec = _mm256_add_epi8(perm_vec, permute_xform); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + ret_vec = _mm256_shuffle_epi8(ret_vec, perm_vec); + } else if (dist == 16) { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + return _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + } else { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + __m128i ret_vec1 = _mm_loadu_si128((__m128i*)(buf + 16)); + /* Take advantage of the fact that only the latter half of the 256 bit vector will actually differ */ + __m128i perm_vec1 = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + __m128i xlane_permutes = _mm_cmpgt_epi8(_mm_set1_epi8(16), perm_vec1); + __m128i xlane_res = _mm_shuffle_epi8(ret_vec0, perm_vec1); + /* Since we can't wrap twice, we can simply keep the later half exactly how it is instead of having to _also_ + * shuffle those values */ + __m128i latter_half = _mm_blendv_epi8(ret_vec1, xlane_res, xlane_permutes); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), latter_half, 1); + } + + return ret_vec; +} + +#define CHUNKSIZE chunksize_avx2 +#define CHUNKCOPY chunkcopy_avx2 +#define CHUNKUNROLL chunkunroll_avx2 +#define CHUNKMEMSET chunkmemset_avx2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_avx2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_avx2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_sse2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_sse2.c new file mode 100644 index 000000000..c402c0ee1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_sse2.c @@ -0,0 +1,56 @@ +/* chunkset_sse2.c -- SSE2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#ifdef X86_SSE2 +#include + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +#define CHUNKSIZE chunksize_sse2 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 +#define CHUNKMEMSET chunkmemset_sse2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_sse2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_ssse3.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_ssse3.c new file mode 100644 index 000000000..0bd626385 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/chunkset_ssse3.c @@ -0,0 +1,103 @@ +/* chunkset_ssse3.c -- SSSE3 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +/* This requires SSE2 support. While it's implicit with SSSE3, we can minimize + * code size by sharing the chunkcopy functions, which will certainly compile + * to identical machine code */ +#if defined(X86_SSSE3) && defined(X86_SSE2) +#include +#include "../generic/chunk_permute_table.h" + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG +#define HAVE_CHUNKCOPY +#define HAVE_CHUNKUNROLL + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m128i perm_vec, ret_vec; +#ifdef Z_MEMORY_SANITIZER + /* Important to note: + * This is _not_ to subvert the memory sanitizer but to instead unpoison some + * bytes we willingly and purposefully load uninitialized that we swizzle over + * in a vector register, anyway. If what we assume is wrong about what is used, + * the memory sanitizer will still usefully flag it */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + ret_vec = _mm_loadu_si128((__m128i*)buf); + *chunk_rem = lut_rem.remval; + + perm_vec = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + ret_vec = _mm_shuffle_epi8(ret_vec, perm_vec); + + return ret_vec; +} + +extern uint8_t* chunkcopy_sse2(uint8_t *out, uint8_t const *from, unsigned len); +extern uint8_t* chunkunroll_sse2(uint8_t *out, unsigned *dist, unsigned *len); + +#define CHUNKSIZE chunksize_ssse3 +#define CHUNKMEMSET chunkmemset_ssse3 +#define CHUNKMEMSET_SAFE chunkmemset_safe_ssse3 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_ssse3 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_avx2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_avx2.c new file mode 100644 index 000000000..1318a0e33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_avx2.c @@ -0,0 +1,63 @@ +/* compare256_avx2.c -- AVX2 version of compare256 + * Copyright Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) + +#include +#ifdef _MSC_VER +# include +#endif + +static inline uint32_t compare256_avx2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + __m256i ymm_src0, ymm_src1, ymm_cmp; + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); /* non-identical bytes = 00, identical bytes = FF */ + unsigned mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); /* Invert bits so identical = 0 */ + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); + mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1) { + return compare256_avx2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_sse2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_sse2.c new file mode 100644 index 000000000..aad4bd240 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/compare256_sse2.c @@ -0,0 +1,96 @@ +/* compare256_sse2.c -- SSE2 version of compare256 + * Copyright Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) + +#include + +static inline uint32_t compare256_sse2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + int align_offset = ((uintptr_t)src0) & 15; + const uint8_t *end0 = src0 + 256; + const uint8_t *end1 = src1 + 256; + __m128i xmm_src0, xmm_src1, xmm_cmp; + + /* Do the first load unaligned, than all subsequent ones we have at least + * one aligned load. Sadly aligning both loads is probably unrealistic */ + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + unsigned mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + int align_adv = 16 - align_offset; + len += align_adv; + src0 += align_adv; + src1 += align_adv; + + /* Do a flooring division (should just be a shift right) */ + int num_iter = (256 - len) / 16; + + for (int i = 0; i < num_iter; ++i) { + xmm_src0 = _mm_load_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + len += 16, src0 += 16, src1 += 16; + } + + if (align_offset) { + src0 = end0 - 16; + src1 = end1 - 16; + len = 256 - 16; + + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + } + + return 256; +} + +Z_INTERNAL uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1) { + return compare256_sse2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_pclmulqdq_tpl.h new file mode 100644 index 000000000..3e7992831 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_pclmulqdq_tpl.h @@ -0,0 +1,186 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +Z_INTERNAL void CRC32_FOLD_COPY(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL void CRC32_FOLD(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { +#endif + unsigned long algn_diff; + __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i xmm_crc_part = _mm_setzero_si128(); +#ifdef COPY + char ALIGNED_(16) partial_buf[16] = { 0 }; +#else + __m128i xmm_initial = _mm_cvtsi32_si128(init_crc); + int32_t first = init_crc != 0; + + /* Technically the CRC functions don't even call this for input < 64, but a bare minimum of 31 + * bytes of input is needed for the aligning load that occurs. If there's an initial CRC, to + * carry it forward through the folded CRC there must be 16 - src % 16 + 16 bytes available, which + * by definition can be up to 15 bytes + one full vector load. */ + assert(len >= 31 || first == 0); +#endif + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + if (len < 16) { +#ifdef COPY + if (len == 0) + return; + + memcpy(partial_buf, src, len); + xmm_crc_part = _mm_load_si128((const __m128i *)partial_buf); + memcpy(dst, partial_buf, len); +#endif + goto partial; + } + + algn_diff = ((uintptr_t)16 - ((uintptr_t)src & 0xF)) & 0xF; + if (algn_diff) { + xmm_crc_part = _mm_loadu_si128((__m128i *)src); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_crc_part); + dst += algn_diff; +#else + XOR_INITIAL128(xmm_crc_part); + + if (algn_diff < 4 && init_crc != 0) { + xmm_t0 = xmm_crc_part; + xmm_crc_part = _mm_loadu_si128((__m128i*)src + 1); + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + src += 16; + len -= 16; + } +#endif + + partial_fold(algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + + src += algn_diff; + len -= algn_diff; + } + +#ifdef X86_VPCLMULQDQ + if (len >= 256) { +#ifdef COPY + size_t n = fold_16_vpclmulqdq_copy(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, dst, src, len); + dst += n; +#else + size_t n = fold_16_vpclmulqdq(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, src, len, + xmm_initial, first); + first = 0; +#endif + len -= n; + src += n; + } +#endif + + while (len >= 64) { + len -= 64; + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + xmm_t3 = _mm_load_si128((__m128i *)src + 3); + src += 64; + + fold_4(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + _mm_storeu_si128((__m128i *)dst + 3, xmm_t3); + dst += 64; +#else + XOR_INITIAL128(xmm_t0); +#endif + + xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); + } + + /* + * len = num bytes left - 64 + */ + if (len >= 48) { + len -= 48; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + src += 48; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + dst += 48; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_3(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); + } else if (len >= 32) { + len -= 32; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + src += 32; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + dst += 32; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_2(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); + } else if (len >= 16) { + len -= 16; + xmm_t0 = _mm_load_si128((__m128i *)src); + src += 16; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + dst += 16; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + } + +partial: + if (len) { + memcpy(&xmm_crc_part, src, len); +#ifdef COPY + _mm_storeu_si128((__m128i *)partial_buf, xmm_crc_part); + memcpy(dst, partial_buf, len); +#endif + partial_fold(len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + } + + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_vpclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_vpclmulqdq_tpl.h new file mode 100644 index 000000000..67f08e128 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_fold_vpclmulqdq_tpl.h @@ -0,0 +1,116 @@ +/* crc32_fold_vpclmulqdq_tpl.h -- VPCMULQDQ-based CRC32 folding template. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len) { +#else +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, + __m128i init_crc, int32_t first) { + __m512i zmm_initial = _mm512_zextsi128_si512(init_crc); +#endif + __m512i zmm_t0, zmm_t1, zmm_t2, zmm_t3; + __m512i zmm_crc0, zmm_crc1, zmm_crc2, zmm_crc3; + __m512i z0, z1, z2, z3; + size_t len_tmp = len; + const __m512i zmm_fold4 = _mm512_set4_epi32( + 0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596); + const __m512i zmm_fold16 = _mm512_set4_epi32( + 0x00000001, 0x1542778a, 0x00000001, 0x322d1430); + + // zmm register init + zmm_crc0 = _mm512_setzero_si512(); + zmm_t0 = _mm512_loadu_si512((__m512i *)src); +#ifndef COPY + XOR_INITIAL512(zmm_t0); +#endif + zmm_crc1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_crc2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_crc3 = _mm512_loadu_si512((__m512i *)src + 3); + + /* already have intermediate CRC in xmm registers + * fold4 with 4 xmm_crc to get zmm_crc0 + */ + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc0, 0); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc1, 1); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc2, 2); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc3, 3); + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_xor_si512(z0, zmm_crc0); + zmm_crc0 = _mm512_xor_si512(zmm_crc0, zmm_t0); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_crc1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_crc2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_crc3); + dst += 256; +#endif + len -= 256; + src += 256; + + // fold-16 loops + while (len >= 256) { + zmm_t0 = _mm512_loadu_si512((__m512i *)src); + zmm_t1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_t2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_t3 = _mm512_loadu_si512((__m512i *)src + 3); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x01); + z1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x01); + z2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x01); + z3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x01); + + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x10); + zmm_crc1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x10); + zmm_crc2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x10); + zmm_crc3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x10); + + zmm_crc0 = _mm512_xor_si512(z0, zmm_crc0); + zmm_crc1 = _mm512_xor_si512(z1, zmm_crc1); + zmm_crc2 = _mm512_xor_si512(z2, zmm_crc2); + zmm_crc3 = _mm512_xor_si512(z3, zmm_crc3); + + zmm_crc0 = _mm512_xor_si512(zmm_crc0, zmm_t0); + zmm_crc1 = _mm512_xor_si512(zmm_crc1, zmm_t1); + zmm_crc2 = _mm512_xor_si512(zmm_crc2, zmm_t2); + zmm_crc3 = _mm512_xor_si512(zmm_crc3, zmm_t3); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_t1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_t2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_t3); + dst += 256; +#endif + len -= 256; + src += 256; + } + // zmm_crc[0,1,2,3] -> zmm_crc0 + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_xor_si512(z0, zmm_crc0); + zmm_crc0 = _mm512_xor_si512(zmm_crc0, zmm_crc1); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_xor_si512(z0, zmm_crc0); + zmm_crc0 = _mm512_xor_si512(zmm_crc0, zmm_crc2); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_xor_si512(z0, zmm_crc0); + zmm_crc0 = _mm512_xor_si512(zmm_crc0, zmm_crc3); + + // zmm_crc0 -> xmm_crc[0, 1, 2, 3] + *xmm_crc0 = _mm512_extracti32x4_epi32(zmm_crc0, 0); + *xmm_crc1 = _mm512_extracti32x4_epi32(zmm_crc0, 1); + *xmm_crc2 = _mm512_extracti32x4_epi32(zmm_crc0, 2); + *xmm_crc3 = _mm512_extracti32x4_epi32(zmm_crc0, 3); + + return (len_tmp - len); // return n bytes processed +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq.c new file mode 100644 index 000000000..9383b7a2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq.c @@ -0,0 +1,30 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_PCLMULQDQ_CRC + +#define CRC32_FOLD_COPY crc32_fold_pclmulqdq_copy +#define CRC32_FOLD crc32_fold_pclmulqdq +#define CRC32_FOLD_RESET crc32_fold_pclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_pclmulqdq_final +#define CRC32 crc32_pclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq_tpl.h new file mode 100644 index 000000000..0d66663cb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_pclmulqdq_tpl.h @@ -0,0 +1,363 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include +#include +#include // _mm_extract_epi32 +#ifdef X86_VPCLMULQDQ +# include +#endif + +#include "../../crc32_fold.h" +#include "../../crc32_braid_p.h" +#include "../../fallback_builtins.h" +#include + +#ifdef X86_VPCLMULQDQ +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, __m128i init_crc, + int32_t first); +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +static void fold_1(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc3, ps_res; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res = _mm_xor_ps(ps_crc0, ps_crc3); + + *xmm_crc0 = *xmm_crc1; + *xmm_crc1 = *xmm_crc2; + *xmm_crc2 = x_tmp3; + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static void fold_2(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3, x_tmp2; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res31, ps_res20; + + x_tmp3 = *xmm_crc3; + x_tmp2 = *xmm_crc2; + + *xmm_crc3 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res31 = _mm_xor_ps(ps_crc3, ps_crc1); + + *xmm_crc2 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res20 = _mm_xor_ps(ps_crc0, ps_crc2); + + *xmm_crc0 = x_tmp2; + *xmm_crc1 = x_tmp3; + *xmm_crc2 = _mm_castps_si128(ps_res20); + *xmm_crc3 = _mm_castps_si128(ps_res31); +} + +static void fold_3(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res32, ps_res21, ps_res10; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc2; + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res32 = _mm_xor_ps(ps_crc2, ps_crc3); + + *xmm_crc2 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res21 = _mm_xor_ps(ps_crc1, ps_crc2); + + *xmm_crc1 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res10 = _mm_xor_ps(ps_crc0, ps_crc1); + + *xmm_crc0 = x_tmp3; + *xmm_crc1 = _mm_castps_si128(ps_res10); + *xmm_crc2 = _mm_castps_si128(ps_res21); + *xmm_crc3 = _mm_castps_si128(ps_res32); +} + +static void fold_4(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp0, x_tmp1, x_tmp2, x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3; + __m128 ps_t0, ps_t1, ps_t2, ps_t3; + __m128 ps_res0, ps_res1, ps_res2, ps_res3; + + x_tmp0 = *xmm_crc0; + x_tmp1 = *xmm_crc1; + x_tmp2 = *xmm_crc2; + x_tmp3 = *xmm_crc3; + + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + x_tmp0 = _mm_clmulepi64_si128(x_tmp0, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_t0 = _mm_castsi128_ps(x_tmp0); + ps_res0 = _mm_xor_ps(ps_crc0, ps_t0); + + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + x_tmp1 = _mm_clmulepi64_si128(x_tmp1, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_t1 = _mm_castsi128_ps(x_tmp1); + ps_res1 = _mm_xor_ps(ps_crc1, ps_t1); + + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + x_tmp2 = _mm_clmulepi64_si128(x_tmp2, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_t2 = _mm_castsi128_ps(x_tmp2); + ps_res2 = _mm_xor_ps(ps_crc2, ps_t2); + + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x01); + x_tmp3 = _mm_clmulepi64_si128(x_tmp3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_t3 = _mm_castsi128_ps(x_tmp3); + ps_res3 = _mm_xor_ps(ps_crc3, ps_t3); + + *xmm_crc0 = _mm_castps_si128(ps_res0); + *xmm_crc1 = _mm_castps_si128(ps_res1); + *xmm_crc2 = _mm_castps_si128(ps_res2); + *xmm_crc3 = _mm_castps_si128(ps_res3); +} + +static const unsigned ALIGNED_(32) pshufb_shf_table[60] = { + 0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d, /* shl 15 (16 - 1)/shr1 */ + 0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e, /* shl 14 (16 - 3)/shr2 */ + 0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f, /* shl 13 (16 - 4)/shr3 */ + 0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100, /* shl 12 (16 - 4)/shr4 */ + 0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201, /* shl 11 (16 - 5)/shr5 */ + 0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302, /* shl 10 (16 - 6)/shr6 */ + 0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403, /* shl 9 (16 - 7)/shr7 */ + 0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504, /* shl 8 (16 - 8)/shr8 */ + 0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605, /* shl 7 (16 - 9)/shr9 */ + 0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706, /* shl 6 (16 -10)/shr10*/ + 0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807, /* shl 5 (16 -11)/shr11*/ + 0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908, /* shl 4 (16 -12)/shr12*/ + 0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09, /* shl 3 (16 -13)/shr13*/ + 0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a, /* shl 2 (16 -14)/shr14*/ + 0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b /* shl 1 (16 -15)/shr15*/ +}; + +static void partial_fold(const size_t len, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, + __m128i *xmm_crc3, __m128i *xmm_crc_part) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + const __m128i xmm_mask3 = _mm_set1_epi32((int32_t)0x80808080); + + __m128i xmm_shl, xmm_shr, xmm_tmp1, xmm_tmp2, xmm_tmp3; + __m128i xmm_a0_0, xmm_a0_1; + __m128 ps_crc3, psa0_0, psa0_1, ps_res; + + xmm_shl = _mm_load_si128((__m128i *)(pshufb_shf_table + (4 * (len - 1)))); + xmm_shr = xmm_shl; + xmm_shr = _mm_xor_si128(xmm_shr, xmm_mask3); + + xmm_a0_0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shl); + + *xmm_crc0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shr); + xmm_tmp1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shl); + *xmm_crc0 = _mm_or_si128(*xmm_crc0, xmm_tmp1); + + *xmm_crc1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shr); + xmm_tmp2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shl); + *xmm_crc1 = _mm_or_si128(*xmm_crc1, xmm_tmp2); + + *xmm_crc2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shr); + xmm_tmp3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shl); + *xmm_crc2 = _mm_or_si128(*xmm_crc2, xmm_tmp3); + + *xmm_crc3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shr); + *xmm_crc_part = _mm_shuffle_epi8(*xmm_crc_part, xmm_shl); + *xmm_crc3 = _mm_or_si128(*xmm_crc3, *xmm_crc_part); + + xmm_a0_1 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x10); + xmm_a0_0 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x01); + + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + psa0_0 = _mm_castsi128_ps(xmm_a0_0); + psa0_1 = _mm_castsi128_ps(xmm_a0_1); + + ps_res = _mm_xor_ps(ps_crc3, psa0_0); + ps_res = _mm_xor_ps(ps_res, psa0_1); + + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static inline void crc32_fold_load(__m128i *fold, __m128i *fold0, __m128i *fold1, __m128i *fold2, __m128i *fold3) { + *fold0 = _mm_load_si128(fold + 0); + *fold1 = _mm_load_si128(fold + 1); + *fold2 = _mm_load_si128(fold + 2); + *fold3 = _mm_load_si128(fold + 3); +} + +static inline void crc32_fold_save(__m128i *fold, const __m128i *fold0, const __m128i *fold1, + const __m128i *fold2, const __m128i *fold3) { + _mm_storeu_si128(fold + 0, *fold0); + _mm_storeu_si128(fold + 1, *fold1); + _mm_storeu_si128(fold + 2, *fold2); + _mm_storeu_si128(fold + 3, *fold3); +} + +Z_INTERNAL uint32_t CRC32_FOLD_RESET(crc32_fold *crc) { + __m128i xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); + __m128i xmm_zero = _mm_setzero_si128(); + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_zero, &xmm_zero, &xmm_zero); + return 0; +} + +#define ONCE(op) if (first) { first = 0; op; } +#define XOR_INITIAL128(where) ONCE(where = _mm_xor_si128(where, xmm_initial)) +#ifdef X86_VPCLMULQDQ +# define XOR_INITIAL512(where) ONCE(where = _mm512_xor_si512(where, zmm_initial)) +#endif + +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" +#define COPY +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" + +static const unsigned ALIGNED_(16) crc_k[] = { + 0xccaa009e, 0x00000000, /* rk1 */ + 0x751997d0, 0x00000001, /* rk2 */ + 0xccaa009e, 0x00000000, /* rk5 */ + 0x63cd6124, 0x00000001, /* rk6 */ + 0xf7011640, 0x00000001, /* rk7 */ + 0xdb710640, 0x00000001 /* rk8 */ +}; + +static const unsigned ALIGNED_(16) crc_mask[4] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 +}; + +static const unsigned ALIGNED_(16) crc_mask2[4] = { + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +Z_INTERNAL uint32_t CRC32_FOLD_FINAL(crc32_fold *crc) { + const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); + const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; + + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + /* + * k1 + */ + crc_fold = _mm_load_si128((__m128i *)crc_k); + + x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); + xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); + xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); + + x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); + xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); + xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); + + x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); + xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); + xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + + /* + * k5 + */ + crc_fold = _mm_load_si128((__m128i *)(crc_k + 4)); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); + + /* + * k7 + */ + xmm_crc1 = xmm_crc3; + xmm_crc2 = xmm_crc3; + crc_fold = _mm_load_si128((__m128i *)(crc_k + 8)); + + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); + + xmm_crc2 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); + + crc->value = ~((uint32_t)_mm_extract_epi32(xmm_crc3, 2)); + + return crc->value; +} + +Z_INTERNAL uint32_t CRC32(uint32_t crc32, const uint8_t *buf, size_t len) { + /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for + * these short lengths might also prove to be effective */ + if (len < 64) + return PREFIX(crc32_braid)(crc32, buf, len); + + crc32_fold ALIGNED_(16) crc_state; + CRC32_FOLD_RESET(&crc_state); + CRC32_FOLD(&crc_state, buf, len, crc32); + return CRC32_FOLD_FINAL(&crc_state); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_vpclmulqdq.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_vpclmulqdq.c new file mode 100644 index 000000000..ec641b432 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/crc32_vpclmulqdq.c @@ -0,0 +1,17 @@ +/* crc32_vpclmulqdq.c -- VPCMULQDQ-based CRC32 folding implementation. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + +#define X86_VPCLMULQDQ +#define CRC32_FOLD_COPY crc32_fold_vpclmulqdq_copy +#define CRC32_FOLD crc32_fold_vpclmulqdq +#define CRC32_FOLD_RESET crc32_fold_vpclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_vpclmulqdq_final +#define CRC32 crc32_vpclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/insert_string_sse42.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/insert_string_sse42.c new file mode 100644 index 000000000..565d92f97 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/insert_string_sse42.c @@ -0,0 +1,50 @@ +/* insert_string_sse42.c -- insert_string integer hash variant using SSE4.2's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "../../zbuild.h" +#include +#ifdef _MSC_VER +# include +#endif +#include "../../deflate.h" + +#ifdef X86_SSE42_CRC_INTRIN +# ifdef _MSC_VER +# define HASH_CALC(s, h, val)\ + h = _mm_crc32_u32(h, val) +# else +# define HASH_CALC(s, h, val)\ + h = __builtin_ia32_crc32si(h, val) +# endif +#else +# ifdef _MSC_VER +# define HASH_CALC(s, h, val) {\ + __asm mov edx, h\ + __asm mov eax, val\ + __asm crc32 eax, edx\ + __asm mov h, eax\ + } +# else +# define HASH_CALC(s, h, val) \ + __asm__ __volatile__ (\ + "crc32 %1,%0\n\t"\ + : "+r" (h)\ + : "r" (val)\ + ); +# endif +#endif + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_sse42 +#define INSERT_STRING insert_string_sse42 +#define QUICK_INSERT_STRING quick_insert_string_sse42 + +#ifdef X86_SSE42 +# include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_avx2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_avx2.c new file mode 100644 index 000000000..94fe10c7b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_avx2.c @@ -0,0 +1,39 @@ +/* + * AVX2 optimized hash slide, based on Intel's slide_sse implementation + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * Mika T. Lindqvist + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include + +static inline void slide_hash_chain(Pos *table, uint32_t entries, const __m256i wsize) { + table += entries; + table -= 16; + + do { + __m256i value, result; + + value = _mm256_loadu_si256((__m256i *)table); + result = _mm256_subs_epu16(value, wsize); + _mm256_storeu_si256((__m256i *)table, result); + + table -= 16; + entries -= 16; + } while (entries > 0); +} + +Z_INTERNAL void slide_hash_avx2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m256i ymm_wsize = _mm256_set1_epi16((short)wsize); + + slide_hash_chain(s->head, HASH_SIZE, ymm_wsize); + slide_hash_chain(s->prev, wsize, ymm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_sse2.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_sse2.c new file mode 100644 index 000000000..5daac4a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/slide_hash_sse2.c @@ -0,0 +1,62 @@ +/* + * SSE optimized hash slide + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include +#include + +static inline void slide_hash_chain(Pos *table0, Pos *table1, uint32_t entries0, + uint32_t entries1, const __m128i wsize) { + uint32_t entries; + Pos *table; + __m128i value0, value1, result0, result1; + + int on_chain = 0; + +next_chain: + table = (on_chain) ? table1 : table0; + entries = (on_chain) ? entries1 : entries0; + + table += entries; + table -= 16; + + /* ZALLOC allocates this pointer unless the user chose a custom allocator. + * Our alloc function is aligned to 64 byte boundaries */ + do { + value0 = _mm_load_si128((__m128i *)table); + value1 = _mm_load_si128((__m128i *)(table + 8)); + result0 = _mm_subs_epu16(value0, wsize); + result1 = _mm_subs_epu16(value1, wsize); + _mm_store_si128((__m128i *)table, result0); + _mm_store_si128((__m128i *)(table + 8), result1); + + table -= 16; + entries -= 16; + } while (entries > 0); + + ++on_chain; + if (on_chain > 1) { + return; + } else { + goto next_chain; + } +} + +Z_INTERNAL void slide_hash_sse2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m128i xmm_wsize = _mm_set1_epi16((short)wsize); + + assert(((uintptr_t)s->head & 15) == 0); + assert(((uintptr_t)s->prev & 15) == 0); + + slide_hash_chain(s->head, s->prev, HASH_SIZE, wsize, xmm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.c b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.c new file mode 100644 index 000000000..3272e3fdd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.c @@ -0,0 +1,97 @@ +/* x86_features.c - x86 feature check + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Author: + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "x86_features.h" + +#ifdef _WIN32 +# include +#else +// Newer versions of GCC and clang come with cpuid.h +# include +#endif + +#include + +static inline void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuid((int *)registers, info); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid(info, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline void cpuidex(int info, int subinfo, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuidex((int *)registers, info, subinfo); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid_count(info, subinfo, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline uint64_t xgetbv(unsigned int xcr) { +#ifdef _WIN32 + return _xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ ( ".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (uint64_t)(edx) << 32 | eax; +#endif +} + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) { + unsigned eax, ebx, ecx, edx; + unsigned maxbasic; + + cpuid(0, &maxbasic, &ebx, &ecx, &edx); + cpuid(1 /*CPU_PROCINFO_AND_FEATUREBITS*/, &eax, &ebx, &ecx, &edx); + + features->has_sse2 = edx & 0x4000000; + features->has_ssse3 = ecx & 0x200; + features->has_sse42 = ecx & 0x100000; + features->has_pclmulqdq = ecx & 0x2; + + if (ecx & 0x08000000) { + uint64_t xfeature = xgetbv(0); + + features->has_os_save_ymm = ((xfeature & 0x06) == 0x06); + features->has_os_save_zmm = ((xfeature & 0xe6) == 0xe6); + } + + if (maxbasic >= 7) { + cpuidex(7, 0, &eax, &ebx, &ecx, &edx); + + // check BMI1 bit + // Reference: https://software.intel.com/sites/default/files/article/405250/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf + features->has_vpclmulqdq = ecx & 0x400; + + // check AVX2 bit if the OS supports saving YMM registers + if (features->has_os_save_ymm) { + features->has_avx2 = ebx & 0x20; + } + + // check AVX512 bits if the OS supports saving ZMM registers + if (features->has_os_save_zmm) { + features->has_avx512 = ebx & 0x00010000; + features->has_avx512vnni = ecx & 0x800; + } + } +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.h new file mode 100644 index 000000000..4a36bde83 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/arch/x86/x86_features.h @@ -0,0 +1,24 @@ +/* x86_features.h -- check for CPU features +* Copyright (C) 2013 Intel Corporation Jim Kukunas +* For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#ifndef X86_FEATURES_H_ +#define X86_FEATURES_H_ + +struct x86_cpu_features { + int has_avx2; + int has_avx512; + int has_avx512vnni; + int has_sse2; + int has_ssse3; + int has_sse42; + int has_pclmulqdq; + int has_vpclmulqdq; + int has_os_save_ymm; + int has_os_save_zmm; +}; + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features); + +#endif /* CPU_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/chunkset.c b/internal-complibs/zlib-ng-2.1.0-beta1/chunkset.c new file mode 100644 index 000000000..7b2bb7ba3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/chunkset.c @@ -0,0 +1,42 @@ +/* chunkset.c -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +typedef uint64_t chunk_t; + +#define CHUNK_SIZE 8 + +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint8_t *dest = (uint8_t *)chunk; + memcpy(dest, from, sizeof(uint32_t)); + memcpy(dest+4, from, sizeof(uint32_t)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + memcpy(chunk, from, sizeof(uint64_t)); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + memcpy(chunk, (uint8_t *)s, sizeof(uint64_t)); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + memcpy(out, chunk, sizeof(uint64_t)); +} + +#define CHUNKSIZE chunksize_c +#define CHUNKCOPY chunkcopy_c +#define CHUNKUNROLL chunkunroll_c +#define CHUNKMEMSET chunkmemset_c +#define CHUNKMEMSET_SAFE chunkmemset_safe_c + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_c + +#include "inffast_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/chunkset_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/chunkset_tpl.h new file mode 100644 index 000000000..f909a1255 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/chunkset_tpl.h @@ -0,0 +1,200 @@ +/* chunkset_tpl.h -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include + +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) +extern uint8_t* chunkmemset_ssse3(uint8_t *out, unsigned dist, unsigned len); +#endif + +/* Returns the chunk size */ +Z_INTERNAL uint32_t CHUNKSIZE(void) { + return sizeof(chunk_t); +} + +/* Behave like memcpy, but assume that it's OK to overwrite at least + chunk_t bytes of output even if the length is shorter than this, + that the length is non-zero, and that `from` lags `out` by at least + sizeof chunk_t bytes (or that they don't overlap at all or simply that + the distance is less than the length of the copy). + + Aside from better memory bus utilisation, this means that short copies + (chunk_t bytes or fewer) will fall straight through the loop + without iteration, which will hopefully make the branch prediction more + reliable. */ +#ifndef HAVE_CHUNKCOPY +Z_INTERNAL uint8_t* CHUNKCOPY(uint8_t *out, uint8_t const *from, unsigned len) { + Assert(len > 0, "chunkcopy should never have a length 0"); + chunk_t chunk; + int32_t align = ((len - 1) % sizeof(chunk_t)) + 1; + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += align; + from += align; + len -= align; + while (len > 0) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += sizeof(chunk_t); + from += sizeof(chunk_t); + len -= sizeof(chunk_t); + } + return out; +} +#endif + +/* Perform short copies until distance can be rewritten as being at least + sizeof chunk_t. + + This assumes that it's OK to overwrite at least the first + 2*sizeof(chunk_t) bytes of output even if the copy is shorter than this. + This assumption holds because inflate_fast() starts every iteration with at + least 258 bytes of output space available (258 being the maximum length + output from a single token; see inflate_fast()'s assumptions below). */ +#ifndef HAVE_CHUNKUNROLL +Z_INTERNAL uint8_t* CHUNKUNROLL(uint8_t *out, unsigned *dist, unsigned *len) { + unsigned char const *from = out - *dist; + chunk_t chunk; + while (*dist < *len && *dist < sizeof(chunk_t)) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += *dist; + *len -= *dist; + *dist += *dist; + } + return out; +} +#endif + +#ifndef HAVE_CHUNK_MAG +/* Loads a magazine to feed into memory of the pattern */ +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + /* This code takes string of length dist from "from" and repeats + * it for as many times as can fit in a chunk_t (vector register) */ + uint32_t cpy_dist; + uint32_t bytes_remaining = sizeof(chunk_t); + chunk_t chunk_load; + uint8_t *cur_chunk = (uint8_t *)&chunk_load; + while (bytes_remaining) { + cpy_dist = MIN(dist, bytes_remaining); + memcpy(cur_chunk, buf, cpy_dist); + bytes_remaining -= cpy_dist; + cur_chunk += cpy_dist; + /* This allows us to bypass an expensive integer division since we're effectively + * counting in this loop, anyway */ + *chunk_rem = cpy_dist; + } + + return chunk_load; +} +#endif + +/* Copy DIST bytes from OUT - DIST into OUT + DIST * k, for 0 <= k < LEN/DIST. + Return OUT + LEN. */ +Z_INTERNAL uint8_t* CHUNKMEMSET(uint8_t *out, unsigned dist, unsigned len) { + /* Debug performance related issues when len < sizeof(uint64_t): + Assert(len >= sizeof(uint64_t), "chunkmemset should be called on larger chunks"); */ + Assert(dist > 0, "chunkmemset cannot have a distance 0"); + /* Only AVX2 */ +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) + if (len <= 16) { + return chunkmemset_ssse3(out, dist, len); + } +#endif + + uint8_t *from = out - dist; + + if (dist == 1) { + memset(out, *from, len); + return out + len; + } else if (dist > sizeof(chunk_t)) { + return CHUNKCOPY(out, out - dist, len); + } + + chunk_t chunk_load; + uint32_t chunk_mod = 0; + + /* TODO: possibly build up a permutation table for this if not an even modulus */ +#ifdef HAVE_CHUNKMEMSET_2 + if (dist == 2) { + chunkmemset_2(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_4 + if (dist == 4) { + chunkmemset_4(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_8 + if (dist == 8) { + chunkmemset_8(from, &chunk_load); + } else if (dist == sizeof(chunk_t)) { + loadchunk(from, &chunk_load); + } else +#endif + { + chunk_load = GET_CHUNK_MAG(from, &chunk_mod, dist); + } + + /* If we're lucky enough and dist happens to be an even modulus of our vector length, + * we can do two stores per loop iteration, which for most ISAs, especially x86, is beneficial */ + if (chunk_mod == 0) { + while (len >= (2 * sizeof(chunk_t))) { + storechunk(out, &chunk_load); + storechunk(out + sizeof(chunk_t), &chunk_load); + out += 2 * sizeof(chunk_t); + len -= 2 * sizeof(chunk_t); + } + } + + /* If we don't have a "dist" length that divides evenly into a vector + * register, we can write the whole vector register but we need only + * advance by the amount of the whole string that fits in our chunk_t. + * If we do divide evenly into the vector length, adv_amount = chunk_t size*/ + uint32_t adv_amount = sizeof(chunk_t) - chunk_mod; + while (len >= sizeof(chunk_t)) { + storechunk(out, &chunk_load); + len -= adv_amount; + out += adv_amount; + } + + if (len) { + memcpy(out, &chunk_load, len); + out += len; + } + + return out; +} + +Z_INTERNAL uint8_t* CHUNKMEMSET_SAFE(uint8_t *out, unsigned dist, unsigned len, unsigned left) { +#if !defined(UNALIGNED64_OK) +# if !defined(UNALIGNED_OK) + static const uint32_t align_mask = 7; +# else + static const uint32_t align_mask = 3; +# endif +#endif + + len = MIN(len, left); + uint8_t *from = out - dist; +#if !defined(UNALIGNED64_OK) + while (((uintptr_t)out & align_mask) && (len > 0)) { + *out++ = *from++; + --len; + --left; + } +#endif + if (left < (unsigned)(3 * sizeof(chunk_t))) { + while (len > 0) { + *out++ = *from++; + --len; + } + return out; + } + if (len) + return CHUNKMEMSET(out, dist, len); + + return out; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.c b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.c new file mode 100644 index 000000000..ff1a05a25 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.c @@ -0,0 +1,111 @@ +// archdetect.c -- Detect compiler architecture and raise preprocessor error +// containing a simple arch identifier. +// Copyright (C) 2019 Hans Kristian Rosbach +// Licensed under the Zlib license, see LICENSE.md for details + +// x86_64 +#if defined(__x86_64__) || defined(_M_X64) + #error archfound x86_64 + +// x86 +#elif defined(__i386) || defined(_M_IX86) + #error archfound i686 + +// ARM +#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) + #error archfound aarch64 +#elif defined(__arm__) || defined(__arm) || defined(_M_ARM) || defined(__TARGET_ARCH_ARM) + #if defined(__ARM64_ARCH_8__) || defined(__ARMv8__) || defined(__ARMv8_A__) + #error archfound armv8 + #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) + #error archfound armv7 + #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__) + #error archfound armv6 + #elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) + #error archfound armv5 + #elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARCH_5E__) + #error archfound armv4 + #elif defined(__ARM_ARCH_3__) || defined(__TARGET_ARCH_3M__) + #error archfound armv3 + #elif defined(__ARM_ARCH_2__) + #error archfound armv2 + #endif + +// PowerPC +#elif defined(__powerpc__) || defined(_ppc__) || defined(__PPC__) + #if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #error archfound powerpc64le + #else + #error archfound powerpc64 + #endif + #else + #error archfound powerpc + #endif + +// --------------- Less common architectures alphabetically below --------------- + +// ALPHA +#elif defined(__alpha__) || defined(__alpha) + #error archfound alpha + +// Blackfin +#elif defined(__BFIN__) + #error archfound blackfin + +// Itanium +#elif defined(__ia64) || defined(_M_IA64) + #error archfound ia64 + +// MIPS +#elif defined(__mips__) || defined(__mips) + #error archfound mips + +// Motorola 68000-series +#elif defined(__m68k__) + #error archfound m68k + +// SuperH +#elif defined(__sh__) + #error archfound sh + +// SPARC +#elif defined(__sparc__) || defined(__sparc) + #if defined(__sparcv9) || defined(__sparc_v9__) + #error archfound sparc9 + #elif defined(__sparcv8) || defined(__sparc_v8__) + #error archfound sparc8 + #endif + +// SystemZ +#elif defined(__370__) + #error archfound s370 +#elif defined(__s390__) + #error archfound s390 +#elif defined(__s390x) || defined(__zarch__) + #error archfound s390x + +// PARISC +#elif defined(__hppa__) + #error archfound parisc + +// RS-6000 +#elif defined(__THW_RS6000) + #error archfound rs6000 + +// RISC-V +#elif defined(__riscv) + #if __riscv_xlen == 64 + #error archfound riscv64 + #elif __riscv_xlen == 32 + #error archfound riscv32 + #endif + +// Emscripten (WebAssembly) +#elif defined(__EMSCRIPTEN__) + #error archfound wasm32 + +// return 'unrecognized' if we do not know what architecture this is +#else + #error archfound unrecognized +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.cmake new file mode 100644 index 000000000..21c237d61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-arch.cmake @@ -0,0 +1,101 @@ +# detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH +# Copyright (C) 2019 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details +set(ARCHDETECT_FOUND TRUE) + +if(CMAKE_OSX_ARCHITECTURES) + # If multiple architectures are requested (universal build), pick only the first + list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH) +elseif(MSVC) + if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86") + set(ARCH "i686") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64") + set(ARCH "x86_64") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7") + set(ARCH "arm") + elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64") + set(ARCH "aarch64") + endif() +elseif(EMSCRIPTEN) + set(ARCH "wasm32") +elseif(CMAKE_CROSSCOMPILING) + set(ARCH ${CMAKE_C_COMPILER_TARGET}) +else() + # Let preprocessor parse archdetect.c and raise an error containing the arch identifier + enable_language(C) + try_run( + run_result_unused + compile_result_unused + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_LIST_DIR}/detect-arch.c + COMPILE_OUTPUT_VARIABLE RAWOUTPUT + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Find basearch tag, and extract the arch word into BASEARCH variable + string(REGEX REPLACE ".*archfound ([a-zA-Z0-9_]+).*" "\\1" ARCH "${RAWOUTPUT}") + if(NOT ARCH) + set(ARCH unknown) + endif() +endif() + +# Make sure we have ARCH set +if(NOT ARCH OR ARCH STREQUAL "unknown") + set(ARCH ${CMAKE_SYSTEM_PROCESSOR}) + message(STATUS "Arch not recognized, falling back to cmake arch: '${ARCH}'") +else() + message(STATUS "Arch detected: '${ARCH}'") +endif() + +# Base arch detection +if("${ARCH}" MATCHES "(x86_64|AMD64|i[3-6]86)") + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) +elseif("${ARCH}" MATCHES "(arm(v[0-9])?|aarch64)") + set(BASEARCH "arm") + set(BASEARCH_ARM_FOUND TRUE) +elseif("${ARCH}" MATCHES "ppc(64(le)?)?|powerpc(64(le)?)?") + set(BASEARCH "ppc") + set(BASEARCH_PPC_FOUND TRUE) +elseif("${ARCH}" MATCHES "alpha") + set(BASEARCH "alpha") + set(BASEARCH_ALPHA_FOUND TRUE) +elseif("${ARCH}" MATCHES "blackfin") + set(BASEARCH "blackfin") + set(BASEARCH_BLACKFIN_FOUND TRUE) +elseif("${ARCH}" MATCHES "ia64") + set(BASEARCH "ia64") + set(BASEARCH_IA64_FOUND TRUE) +elseif("${ARCH}" MATCHES "mips") + set(BASEARCH "mips") + set(BASEARCH_MIPS_FOUND TRUE) +elseif("${ARCH}" MATCHES "m68k") + set(BASEARCH "m68k") + set(BASEARCH_M68K_FOUND TRUE) +elseif("${ARCH}" MATCHES "sh") + set(BASEARCH "sh") + set(BASEARCH_SH_FOUND TRUE) +elseif("${ARCH}" MATCHES "sparc[89]?") + set(BASEARCH "sparc") + set(BASEARCH_SPARC_FOUND TRUE) +elseif("${ARCH}" MATCHES "s3[679]0x?") + set(BASEARCH "s360") + set(BASEARCH_S360_FOUND TRUE) +elseif("${ARCH}" MATCHES "parisc") + set(BASEARCH "parisc") + set(BASEARCH_PARISC_FOUND TRUE) +elseif("${ARCH}" MATCHES "rs6000") + set(BASEARCH "rs6000") + set(BASEARCH_RS6000_FOUND TRUE) +elseif("${ARCH}" MATCHES "riscv(32|64)") + set(BASEARCH "riscv") + set(BASEARCH_RISCV_FOUND TRUE) +elseif("${ARCH}" MATCHES "wasm32") + set(BASEARCH "wasm32") + set(BASEARCH_WASM32_FOUND TRUE) +else() + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) + message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.") +endif() +message(STATUS "Basearch of '${ARCH}' has been detected as: '${BASEARCH}'") diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-coverage.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-coverage.cmake new file mode 100644 index 000000000..8e67a085c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-coverage.cmake @@ -0,0 +1,46 @@ +# detect-coverage.cmake -- Detect supported compiler coverage flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_code_coverage) + # Check for -coverage flag support for Clang/GCC + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -coverage) + endif() + check_c_compiler_flag(-coverage HAVE_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_COVERAGE) + add_compile_options(-coverage) + add_link_options(-coverage) + message(STATUS "Code coverage enabled using: -coverage") + else() + # Some versions of GCC don't support -coverage shorthand + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -lgcov -fprofile-arcs) + endif() + check_c_compiler_flag("-ftest-coverage -fprofile-arcs -fprofile-values" HAVE_TEST_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_TEST_COVERAGE) + add_compile_options(-ftest-coverage -fprofile-arcs -fprofile-values) + add_link_options(-lgcov -fprofile-arcs) + message(STATUS "Code coverage enabled using: -ftest-coverage") + else() + message(WARNING "Compiler does not support code coverage") + set(WITH_CODE_COVERAGE OFF) + endif() + endif() + + # Set optimization level to zero for code coverage builds + if (WITH_CODE_COVERAGE) + # Use CMake compiler flag variables due to add_compile_options failure on Windows GCC + set(CMAKE_C_FLAGS "-O0 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-O0 ${CMAKE_CXX_FLAGS}") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-install-dirs.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-install-dirs.cmake new file mode 100644 index 000000000..d2225f327 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-install-dirs.cmake @@ -0,0 +1,43 @@ +# detect-install-dirs.cmake -- Detect install directory parameters +# Copyright (C) 2021 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details + +# Determine installation directory for executables +if (DEFINED BIN_INSTALL_DIR) + set(BIN_INSTALL_DIR "${BIN_INSTALL_DIR}" CACHE PATH "Installation directory for executables (Deprecated)" FORCE) + set(CMAKE_INSTALL_BINDIR "${BIN_INSTALL_DIR}") +elseif (DEFINED INSTALL_BIN_DIR) + set(CMAKE_INSTALL_BINDIR "${INSTALL_BIN_DIR}") +endif() + +# Determine installation directory for libraries +if (DEFINED LIB_INSTALL_DIR) + set(LIB_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Installation directory for libraries (Deprecated)" FORCE) + set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}") +elseif (DEFINED INSTALL_LIB_DIR) + set(CMAKE_INSTALL_LIBDIR "${INSTALL_LIB_DIR}") +endif() + +# Determine installation directory for include files +if (DEFINED INC_INSTALL_DIR) + set(INC_INSTALL_DIR "${INC_INSTALL_DIR}" CACHE PATH "Installation directory for headers (Deprecated)" FORCE) + set(CMAKE_INSTALL_INCLUDEDIR "${INC_INSTALL_DIR}") +elseif (DEFINED INSTALL_INC_DIR) + set(CMAKE_INSTALL_INCLUDEDIR "${INSTALL_INC_DIR}") +endif() + +# Determine installation directory for pkgconfig files +if (DEFINED PKGCONFIG_INSTALL_DIR) + set(PKGCONFIG_INSTALL_DIR "${PKGCONFIG_INSTALL_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED INSTALL_PKGCONFIG_DIR) + set(PKGCONFIG_INSTALL_DIR "${INSTALL_PKGCONFIG_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_FULL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_FULL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +else() + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") +endif() + +# Define GNU standard installation directories +include(GNUInstallDirs) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-intrinsics.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-intrinsics.cmake new file mode 100644 index 000000000..0491d53bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-intrinsics.cmake @@ -0,0 +1,524 @@ +# detect-intrinsics.cmake -- Detect compiler intrinsics support +# Licensed under the Zlib license, see LICENSE.md for details + +macro(check_acle_compiler_flag) + if(MSVC) + # Both ARM and ARM64-targeting msvc support intrinsics, but + # ARM msvc is missing some intrinsics introduced with ARMv8, e.g. crc32 + if(MSVC_C_ARCHITECTURE_ID STREQUAL "ARM64") + set(HAVE_ACLE_FLAG TRUE) + endif() + else() + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc" CACHE INTERNAL "Compiler option to enable ACLE support") + endif() + endif() + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG FAIL_REGEX "not supported") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc+simd" CACHE INTERNAL "Compiler option to enable ACLE support" FORCE) + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG2 FAIL_REGEX "not supported") + set(HAVE_ACLE_FLAG ${HAVE_ACLE_FLAG2} CACHE INTERNAL "Have compiler option to enable ACLE intrinsics" FORCE) + unset(HAVE_ACLE_FLAG2 CACHE) # Don't cache this internal variable + endif() + set(CMAKE_REQUIRED_FLAGS) + endif() +endmacro() + +macro(check_avx512_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + else() + set(AVX512FLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + # For CPUs that can benefit from AVX512, it seems GCC generates suboptimal + # instruction scheduling unless you specify a reasonable -mtune= target + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE) + if(HAVE_CASCADE_LAKE) + set(AVX512FLAG "${AVX512FLAG} -mtune=cascadelake") + else() + set(AVX512FLAG "${AVX512FLAG} -mtune=skylake-avx512") + endif() + unset(HAVE_CASCADE_LAKE) + endif() + endif() + elseif(MSVC) + set(AVX512FLAG "/arch:AVX512") + endif() + # Check whether compiler supports AVX512 intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; + }" + HAVE_AVX512_INTRIN + ) + + # Evidently both GCC and clang were late to implementing these + check_c_source_compile_or_run( + "#include + int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; + }" + HAVE_MASK_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx512vnni_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512VNNIFLAG "-mavx512f -mavx512bw -mavx512dq -mavx512vl -mavx512vnni") + else() + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX512VNNIFLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mavx512vnni") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=cascadelake") + endif() + endif() + elseif(MSVC) + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + + # Check whether compiler supports AVX512vnni intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512VNNIFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; + }" + HAVE_AVX512VNNI_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX2FLAG "-mavx2") + else() + set(AVX2FLAG "/arch:AVX2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX2FLAG "-mavx2") + endif() + elseif(MSVC) + set(AVX2FLAG "/arch:AVX2") + endif() + # Check whether compiler supports AVX2 intrinics + set(CMAKE_REQUIRED_FLAGS "${AVX2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; + }" + HAVE_AVX2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_compiler_flag) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports NEON flag + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main() { return 0; }" + MFPU_NEON_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_ld4_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports loading 4 neon vecs into a register range + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; + }" + NEON_HAS_LD4) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_pclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(PCLMULFLAG "-mpclmul") + endif() + endif() + # Check whether compiler supports PCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + # The pclmul code currently crashes on Mac in 32bit mode. Avoid for now. + set(CMAKE_REQUIRED_FLAGS "${PCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_PCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_PCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_vpclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(VPCLMULFLAG "-mvpclmulqdq -mavx512f") + endif() + endif() + # Check whether compiler supports VPCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + set(CMAKE_REQUIRED_FLAGS "${VPCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_VPCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_VPCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_ppc_intrinsics) + # Check if compiler supports AltiVec + set(CMAKE_REQUIRED_FLAGS "-maltivec") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_ALTIVEC + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_ALTIVEC) + set(PPCFLAGS "-maltivec") + endif() + + set(CMAKE_REQUIRED_FLAGS "-maltivec -mno-vsx") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_NOVSX + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_NOVSX) + set(PPCFLAGS "${PPCFLAGS} -mno-vsx") + endif() + + # Check if we have what we need for AltiVec optimizations + set(CMAKE_REQUIRED_FLAGS "${PPCFLAGS} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); + #else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); + #endif + }" + HAVE_VMX + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_power8_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER8FLAG "-mcpu=power8") + endif() + endif() + # Check if we have what we need for POWER8 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER8FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); + #else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); + #endif + }" + HAVE_POWER8_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_s390_intrinsics) + check_c_source_compiles( + "#include + #ifndef HWCAP_S390_VXRS + #define HWCAP_S390_VXRS HWCAP_S390_VX + #endif + int main() { + return (getauxval(AT_HWCAP) & HWCAP_S390_VXRS); + }" + HAVE_S390_INTRIN + ) +endmacro() + +macro(check_power9_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER9FLAG "-mcpu=power9") + endif() + endif() + # Check if we have what we need for POWER9 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER9FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { + return 0; + }" + HAVE_POWER9_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_sse2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE2FLAG "-msse2") + else() + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(MSVC) + if(NOT "${ARCH}" MATCHES "x86_64") + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE2FLAG "-msse2") + endif() + endif() + # Check whether compiler supports SSE2 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; + }" + HAVE_SSE2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_ssse3_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSSE3FLAG "-mssse3") + else() + set(SSSE3FLAG "/arch:SSSE3") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSSE3FLAG "-mssse3") + endif() + endif() + # Check whether compiler supports SSSE3 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSSE3FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; + }" + HAVE_SSSE3_INTRIN + ) +endmacro() + +macro(check_sse42_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE42FLAG "-msse4.2") + else() + set(SSE42FLAG "/arch:SSE4.2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE42FLAG "-msse4.2") + endif() + endif() + # Check whether compiler supports SSE4.2 CRC inline asm + set(CMAKE_REQUIRED_FLAGS "${SSE42FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "int main(void) { + unsigned val = 0, h = 0; + #if defined(_MSC_VER) + { __asm mov edx, h __asm mov eax, val __asm crc32 eax, edx __asm mov h, eax } + #else + __asm__ __volatile__ ( \"crc32 %1,%0\" : \"+r\" (h) : \"r\" (val) ); + #endif + return (int)h; + }" + HAVE_SSE42CRC_INLINE_ASM + ) + # Check whether compiler supports SSE4.2 CRC intrinsics + check_c_source_compile_or_run( + "#include + int main(void) { + unsigned crc = 0; + char c = 'c'; + #if defined(_MSC_VER) + crc = _mm_crc32_u32(crc, c); + #else + crc = __builtin_ia32_crc32qi(crc, c); + #endif + (void)crc; + return 0; + }" + HAVE_SSE42CRC_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_vgfma_intrinsics) + if(NOT NATIVEFLAG) + set(VGFMAFLAG "-march=z13") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set(VGFMAFLAG "${VGFMAFLAG} -mzarch") + endif() + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(VGFMAFLAG "${VGFMAFLAG} -fzvector") + endif() + endif() + # Check whether compiler supports "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic + set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; + }" + HAVE_VGFMA_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_xsave_intrinsics) + if(NOT NATIVEFLAG AND NOT MSVC) + set(XSAVEFLAG "-mxsave") + endif() + set(CMAKE_REQUIRED_FLAGS "${XSAVEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _WIN32 + # include + #else + # include + #endif + int main(void) { + return _xgetbv(0); + }" + HAVE_XSAVE_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-sanitizer.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-sanitizer.cmake new file mode 100644 index 000000000..f9521ec2f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/detect-sanitizer.cmake @@ -0,0 +1,166 @@ +# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_common_sanitizer_flags) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options(-g3) + endif() + check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER) + if(HAVE_NO_OMIT_FRAME_POINTER) + add_compile_options(-fno-omit-frame-pointer) + add_link_options(-fno-omit-frame-pointer) + endif() + check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS) + if(HAVE_NO_OPTIMIZE_SIBLING_CALLS) + add_compile_options(-fno-optimize-sibling-calls) + add_link_options(-fno-optimize-sibling-calls) + endif() +endmacro() + +macro(check_sanitizer_support known_checks supported_checks) + set(available_checks "") + + # Build list of supported sanitizer flags by incrementally trying compilation with + # known sanitizer checks + + foreach(check ${known_checks}) + if(available_checks STREQUAL "") + set(compile_checks "${check}") + else() + set(compile_checks "${available_checks},${check}") + endif() + + set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks}) + + check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check} + FAIL_REGEX "not supported|unrecognized command|unknown option") + + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_SANITIZER_${check}) + set(available_checks ${compile_checks}) + endif() + endforeach() + + set(${supported_checks} ${available_checks}) +endmacro() + +macro(add_address_sanitizer) + set(known_checks + address + pointer-compare + pointer-subtract + ) + + check_sanitizer_support("${known_checks}" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Address sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Address sanitizer is not supported") + endif() + + if(CMAKE_CROSSCOMPILING_EMULATOR) + # Only check for leak sanitizer if not cross-compiling due to qemu crash + message(WARNING "Leak sanitizer is not supported when cross compiling") + else() + # Leak sanitizer requires address sanitizer + check_sanitizer_support("leak" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Leak sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Leak sanitizer is not supported") + endif() + endif() +endmacro() + +macro(add_memory_sanitizer) + check_sanitizer_support("memory" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Memory sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + + check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS) + if(HAVE_MEMORY_TRACK_ORIGINS) + add_compile_options(-fsanitize-memory-track-origins) + add_link_options(-fsanitize-memory-track-origins) + endif() + else() + message(STATUS "Memory sanitizer is not supported") + endif() +endmacro() + +macro(add_thread_sanitizer) + check_sanitizer_support("thread" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Thread sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Thread sanitizer is not supported") + endif() +endmacro() + +macro(add_undefined_sanitizer) + set(known_checks + array-bounds + bool + bounds + builtin + enum + float-cast-overflow + float-divide-by-zero + function + integer-divide-by-zero + local-bounds + null + nonnull-attribute + pointer-overflow + return + returns-nonnull-attribute + shift + shift-base + shift-exponent + signed-integer-overflow + undefined + unsigned-integer-overflow + unsigned-shift-base + vla-bound + vptr + ) + + # Only check for alignment sanitizer flag if unaligned access is not supported + if(NOT WITH_UNALIGNED) + list(APPEND known_checks alignment) + endif() + # Object size sanitizer has no effect at -O0 and produces compiler warning if enabled + if(NOT CMAKE_C_FLAGS MATCHES "-O0") + list(APPEND known_checks object-size) + endif() + + check_sanitizer_support("${known_checks}" supported_checks) + + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + + # Group sanitizer flag -fsanitize=undefined will automatically add alignment, even if + # it is not in our sanitize flag list, so we need to explicitly disable alignment sanitizing. + if(WITH_UNALIGNED) + add_compile_options(-fno-sanitize=alignment) + endif() + + add_common_sanitizer_flags() + else() + message(STATUS "Undefined behavior sanitizer is not supported") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/fallback-macros.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/fallback-macros.cmake new file mode 100644 index 000000000..8bc6cf25b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/fallback-macros.cmake @@ -0,0 +1,19 @@ +# fallback-macros.cmake -- CMake fallback macros +# Copyright (C) 2022 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# CMake less than version 3.5.2 +if(NOT COMMAND add_compile_options) + macro(add_compile_options options) + string(APPEND CMAKE_C_FLAGS ${options}) + string(APPEND CMAKE_CXX_FLAGS ${options}) + endmacro() +endif() + +# CMake less than version 3.14 +if(NOT COMMAND add_link_options) + macro(add_link_options options) + string(APPEND CMAKE_EXE_LINKER_FLAGS ${options}) + string(APPEND CMAKE_SHARED_LINKER_FLAGS ${options}) + endmacro() +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-aarch64.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-aarch64.cmake new file mode 100644 index 000000000..1e2473107 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-aarch64.cmake @@ -0,0 +1,24 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") +set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-arm.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-arm.cmake new file mode 100644 index 000000000..1bdd8d2cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-arm.cmake @@ -0,0 +1,29 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +if(NOT DEFINED CMAKE_C_COMPILER_TARGET) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) +endif() +if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) +endif() + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-armhf.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-armhf.cmake new file mode 100644 index 000000000..007859caf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-armhf.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf) +set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-i686.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-i686.cmake new file mode 100644 index 000000000..b95e63f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-i686.cmake @@ -0,0 +1,35 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET i686-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES + ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-x86_64.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-x86_64.cmake new file mode 100644 index 000000000..8c660b0b1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-mingw-x86_64.cmake @@ -0,0 +1,34 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET x86_64-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc.cmake new file mode 100644 index 000000000..f09713370 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR powerpc) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc -cpu 7400 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64.cmake new file mode 100644 index 000000000..80d8b904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64le.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64le.cmake new file mode 100644 index 000000000..68381de12 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-powerpc64le.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64le) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-s390x.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-s390x.cmake new file mode 100644 index 000000000..9455a2bed --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-s390x.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR s390x) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET s390x-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET s390x-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-s390x -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-sparc64.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-sparc64.cmake new file mode 100644 index 000000000..16161a78c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cmake/toolchain-sparc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR sparc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET sparc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET sparc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-sparc64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/compare256.c b/internal-complibs/zlib-ng-2.1.0-beta1/compare256.c new file mode 100644 index 000000000..82551cdd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/compare256.c @@ -0,0 +1,180 @@ +/* compare256.c -- 256 byte memory comparison with match length return + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "fallback_builtins.h" + +/* ALIGNED, byte comparison */ +static inline uint32_t compare256_c_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1) { + return compare256_c_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +/* 16-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_16_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_16_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#ifdef HAVE_BUILTIN_CTZ +/* 32-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_32_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint32_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint32_t match_byte = __builtin_ctz(diff) / 8; + return len + match_byte; + } + + src0 += 4, src1 += 4, len += 4; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_32_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#endif + +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +/* UNALIGNED64_OK, 64-bit integer comparison */ +static inline uint32_t compare256_unaligned_64_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint64_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint64_t match_byte = __builtin_ctzll(diff) / 8; + return len + (uint32_t)match_byte; + } + + src0 += 8, src1 += 8, len += 8; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_64_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/compress.c b/internal-complibs/zlib-ng-2.1.0-beta1/compress.c new file mode 100644 index 000000000..66118e4f4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/compress.c @@ -0,0 +1,98 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_common.h" +#else +/* Returns the upper bound on compressed data length based on uncompressed data length, assuming default settings. + * Zero means that arch-specific deflation code behaves identically to the regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_COMPLEN(source_len) 0 +#endif + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int Z_EXPORT PREFIX(compress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, + z_uintmax_t sourceLen, int level) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_size_t left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(deflateInit)(&stream, level); + if (err != Z_OK) + return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (unsigned long)max ? max : (unsigned int)sourceLen; + sourceLen -= stream.avail_in; + } + err = PREFIX(deflate)(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + PREFIX(deflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int Z_EXPORT PREFIX(compress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(compress2)(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +z_uintmax_t Z_EXPORT PREFIX(compressBound)(z_uintmax_t sourceLen) { + z_uintmax_t complen = DEFLATE_BOUND_COMPLEN(sourceLen); + + if (complen > 0) + /* Architecture-specific code provided an upper bound. */ + return complen + ZLIB_WRAPLEN; + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + ZLIB_WRAPLEN; /* zlib wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + ZLIB_WRAPLEN; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/configure b/internal-complibs/zlib-ng-2.1.0-beta1/configure new file mode 100755 index 000000000..1f3ef7a02 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/configure @@ -0,0 +1,2316 @@ +#!/usr/bin/env bash +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +# start off configure.log +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +SRCDIR=$(cd $(dirname $0); pwd) +BUILDDIR=$(pwd) + +# set command prefix for cross-compilation +if [ -n "${CHOST}" ]; then + # normalize the chost before parsing it + NORM_CHOST=$(sh "$SRCDIR"/tools/config.sub $CHOST) + uname="$(echo "${NORM_CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')" + CROSS_PREFIX="${CHOST}-" + ARCH="$(echo "${NORM_CHOST}" | sed -e 's/-.*//')" +else + ARCH="$(uname -m)" +fi + +case "${ARCH}" in + x86_64) + case "${CFLAGS}" in + *-m32*) + ARCH=i686 + ;; + esac + ;; + i386 | i486 | i586 | i686) + case "${CFLAGS}" in + *-m64*) + ARCH=x86_64 + ;; + esac + ;; +esac + +# destination name for windows import library +IMPORTLIB= + +# establish commands for library building +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi + +# set defaults before processing command line options +LDCONFIG=${LDCONFIG-"ldconfig"} +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +bindir=${bindir-'${exec_prefix}/bin'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +gzfileops=1 +unalignedok=1 +compat=0 +cover=0 +build32=0 +build64=0 +buildvpclmulqdq=1 +buildacle=1 +buildaltivec=1 +buildpower8=1 +buildpower9=1 +buildneon=1 +builddfltccdeflate=0 +builddfltccinflate=0 +buildcrc32vx=1 +floatabi= +native=0 +forcesse2=0 +# For CPUs that can benefit from AVX512, it seems GCC generates suboptimal +# instruction scheduling unless you specify a reasonable -mtune= target +avx512flag="-mavx512f -mavx512dq -mavx512bw -mavx512vl" +avx512vnniflag="-mavx512vnni ${avx512flag}" +avx2flag="-mavx2" +sse2flag="-msse2" +ssse3flag="-mssse3" +sse42flag="-msse4.2" +pclmulflag="-mpclmul" +vpclmulflag="-mvpclmulqdq -mavx512f" +xsaveflag="-mxsave" +acleflag= +neonflag= +noltoflag="-fno-lto" +vgfmaflag="-march=z13" +vmxflag="-maltivec" +symbol_prefix="" +without_optimizations=0 +without_new_strategies=0 +reducedmem=0 +gcc=0 +warn=0 +debug=0 +visibility=1 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +INSTALLTARGETS="install-shared install-static" +UNINSTALLTARGETS="uninstall-shared uninstall-static" + +TEST="teststatic" + +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + +# process command line options +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--32] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + echo ' [--sprefix=SYMBOL_PREFIX] Adds a prefix to all exported symbols' | tee -a configure.log + echo ' [--warn] Enables extra compiler warnings' | tee -a configure.log + echo ' [--debug] Enables extra debug prints during operation' | tee -a configure.log + echo ' [--zlib-compat] Compiles for zlib-compatible API instead of zlib-ng API' | tee -a configure.log + echo ' [--without-unaligned] Compiles without fast unaligned access' | tee -a configure.log + echo ' [--without-gzfileops] Compiles without the gzfile parts of the API enabled' | tee -a configure.log + echo ' [--without-optimizations] Compiles without support for optional instruction sets' | tee -a configure.log + echo ' [--without-new-strategies] Compiles without using new additional deflate strategies' | tee -a configure.log + echo ' [--without-acle] Compiles without ARM C Language Extensions' | tee -a configure.log + echo ' [--without-neon] Compiles without ARM Neon SIMD instruction set' | tee -a configure.log + echo ' [--without-altivec] Compiles without PPC AltiVec support' | tee -a configure.log + echo ' [--without-power8] Compiles without Power8 instruction set' | tee -a configure.log + echo ' [--with-dfltcc-deflate] Use DEFLATE CONVERSION CALL instruction for compression on IBM Z' | tee -a configure.log + echo ' [--with-dfltcc-inflate] Use DEFLATE CONVERSION CALL instruction for decompression on IBM Z' | tee -a configure.log + echo ' [--without-crc32-vx] Build without vectorized CRC32 on IBM Z' | tee -a configure.log + echo ' [--with-reduced-mem] Reduced memory usage for special cases (reduces performance)' | tee -a configure.log + echo ' [--force-sse2] Assume SSE2 instructions are always available (disabled by default on x86, enabled on x86_64)' | tee -a configure.log + echo ' [--native] Compiles with full instruction set supported on this host' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -e*=* | --eprefix=*) exec_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -m*=* | --sprefix=*) symbol_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -l*=* | --libdir=*) libdir=$(echo $1 | sed 's/.*=//'); shift ;; + --sharedlibdir=*) sharedlibdir=$(echo $1 | sed 's/.*=//'); shift ;; + -i*=* | --includedir=*) includedir=$(echo $1 | sed 's/.*=//');shift ;; + -u*=* | --uname=*) uname=$(echo $1 | sed 's/.*=//');shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -m* | --sprefix) symbol_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --zlib-compat) compat=1; shift ;; + --without-unaligned) unalignedok=0; shift ;; + --without-gzfileops) gzfileops=0; shift ;; + --cover) cover=1; shift ;; + -3* | --32) build32=1; shift ;; + -6* | --64) build64=1; shift ;; + --without-vpclmulqdq) buildvpclmulqdq=0; shift ;; + --without-acle) buildacle=0; shift ;; + --without-neon) buildneon=0; shift ;; + --without-altivec) buildaltivec=0 ; shift ;; + --without-power8) buildpower8=0 ; shift ;; + --without-power9) buildpower9=0 ; shift ;; + --with-dfltcc-deflate) builddfltccdeflate=1; shift ;; + --with-dfltcc-inflate) builddfltccinflate=1; shift ;; + --without-crc32-vx) buildcrc32vx=0; shift ;; + --with-reduced-mem) reducedmem=1; shift ;; + --force-sse2) forcesse2=1; shift ;; + -n | --native) native=1; shift ;; + -a*=* | --archs=*) ARCHS=$(echo $1 | sed 's/.*=//'); shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + -noopt | --without-optimizations) without_optimizations=1; shift;; + -oldstrat | --without-new-strategies) without_new_strategies=1; shift;; + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; + + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + leave 1;; + esac +done + +# temporary file name +test=ztest$$ + +# put arguments in log, also put test file in log if used in arguments +show() +{ + case "$*" in + *$test.c*) + echo "=== $test.c ===" >> configure.log + cat $test.c >> configure.log + echo "===" >> configure.log;; + esac + echo $* >> configure.log +} + +# check for gcc vs. cc and set compile and link flags based on the system identified by uname +cat > $test.c <&1) in + *gcc*) gcc=1 ;; + *clang*) gcc=1 ;; +esac + +if test $native -eq 1; then + avx512flag="" + avx512vnniflag="" + avx2flag="" + sse2flag="" + ssse3flag="" + sse42flag="" + pclmulflag="" + vpclmulflag="" + xsaveflag="" + noltoflag="" +fi + +if test $build32 -eq 1; then + CFLAGS="${CFLAGS} -m32" + SFLAGS="${SFLAGS} -m32" + LDFLAGS="${LDFLAGS} -m32" +fi +if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + LDFLAGS="${LDFLAGS} -m64" +fi + +# Set library name depending on zlib-compat option +if test $compat -eq 0; then + LIBNAME=libz-ng + LIBNAME2=zlib-ng + SUFFIX=-ng +else + LIBNAME=libz + LIBNAME2=zlib + SUFFIX="" +fi + +STATICLIB=${LIBNAME}.a +MAPNAME=${LIBNAME2}.map + +# extract zlib version numbers from zlib.h +if test $compat -eq 0; then + VER=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER3=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER2=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER1=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) +else + VER=$(sed -n -e '/ZLIB_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib.h.in) + VER3=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib.h.in) + VER2=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) + VER1=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) +fi + +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc $CFLAGS -c $test.c) >> configure.log 2>&1; then + echo "$cc" | tee -a configure.log + CC="$cc" + CFLAGS="${CFLAGS} -std=c11" + + # Re-check ARCH if the compiler is a cross-compiler. + if $CC -print-multiarch 1> /dev/null 2>&1 && test -n "$($CC -print-multiarch)" 1> /dev/null 2>&1; then + CC_ARCH=$($CC $CFLAGS -print-multiarch | sed 's/-.*//g') + else + CC_ARCH=$($CC $CFLAGS -dumpmachine | sed 's/-.*//g') + fi + case $CC_ARCH in + i386 | i486 | i586 | i686) + # Honor user choice if gcc is multilib and 64-bit is requested + if test $build64 -eq 1; then + ARCH=x86_64 + else + ARCH=$CC_ARCH + fi ;; + x86_64) + # Honor user choice if gcc is multilib and 32-bit is requested + if test $build32 -ne 1; then + ARCH=$CC_ARCH + fi ;; + arm | armeb) + if test $native -eq 0; then + ARCH=arm + else + ARCH=native + fi + if test "${uname}" = "eabi"; then + # No ACLE support + uname=arm + if test $buildacle -eq 1; then + echo ACLE support not available + buildacle=0 + fi + fi + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH=armv8-a+crc + fi + fi ;; + armv8l) + if test $native -eq 0; then + ARCH=armv8-a + else + ARCH=native + fi ;; + aarch64 | aarch64_be | arm64) + if test "${uname}" = "elf"; then + uname=aarch64 + fi + if test $native -eq 0; then + ARCH=aarch64 + else + ARCH=native + fi ;; + powerpc | ppc) + ARCH=powerpc ;; + powerpc64 | ppc64) + ARCH=powerpc64 ;; + powerpc64le | ppc64le) + ARCH=powerpc64le ;; + esac + CFLAGS="-O2 ${CFLAGS}" + if test -n "${ARCHS}"; then + CFLAGS="${CFLAGS} ${ARCHS}" + LDFLAGS="${LDFLAGS} ${ARCHS}" + fi + CFLAGS="${CFLAGS} -Wall" + SFLAGS="${CFLAGS} -fPIC" + if test $native -eq 1; then + case $ARCH in + powerpc*) + NATIVE_FLAG="-mcpu=native" ;; + *) + NATIVE_FLAG="-march=native" ;; + esac + CFLAGS="${CFLAGS} ${NATIVE_FLAG}" + SFLAGS="${SFLAGS} ${NATIVE_FLAG}" + fi + if test "$warn" -eq 1; then + CFLAGS="${CFLAGS} -Wextra" + fi + if test $debug -eq 1; then + CFLAGS="${CFLAGS} -DZLIB_DEBUG" + SFLAGS="${SFLAGS} -DZLIB_DEBUG" + else + CFLAGS="${CFLAGS} -DNDEBUG" + SFLAGS="${SFLAGS} -DNDEBUG" + fi + if test -z "$uname"; then + uname=$((uname -s || echo unknown) 2>/dev/null) + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=cygz-ng$shared_ext + else + SHAREDLIB=cygz$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB},--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MSYS* | msys*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=msys-z-ng$shared_ext + else + SHAREDLIB=msys-z$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MINGW* | mingw*) + visibility=0 + ARFLAGS="rcs" + CFLAGS="${CFLAGS} -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1 -Wno-pedantic-ms-format" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + SHAREDLIB=${LIBNAME}-$VER1$shared_ext + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib=${IMPORTLIB} -Wl,--version-script=${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + if [ "$CC" == "mingw32-gcc" ]; then + case $ARCH in + i386 | i486 | i586 | i686) RCFLAGS="${RCFLAGS} -F pe-i386";; + esac; + fi + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-h${LIBNAME}.so.${VER1}" ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=${LIBNAME}$shared_ext + SHAREDLIBV=${LIBNAME}.$VER$shared_ext + SHAREDLIBM=${LIBNAME}.$VER1$shared_ext + SHAREDTARGET=$SHAREDLIBV + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3" + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi + ARFLAGS="-o" ;; + aarch64) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1} -Wl,--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="-Wl,--start-group -lc -lrdimon -Wl,--end-group" ;; + *) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo "$CC" | tee -a configure.log + if test -z "$uname"; then + uname=$((uname -sr || echo unknown) 2>/dev/null) + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"ld"} + LDSHAREDFLAGS="-b" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc"} + LDSHAREDFLAGS="-G" ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc"} + LDSHAREDFLAGS="-shared" ;; + esac +fi + +# Simplify some later conditionals +case "$uname" in +Linux* | linux*) + LINUX=1 ;; +*) + LINUX=0 ;; +esac + +# destination names for shared library if not defined above +SHAREDLIB=${SHAREDLIB-"${LIBNAME}$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"${LIBNAME}$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"${LIBNAME}$shared_ext.$VER1"} +SHAREDTARGET=${SHAREDTARGET-"${LIBNAME}$shared_ext.$VER"} + +echo >> configure.log + +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "$(\( $* \) 2>&1 | tee -a configure.log)" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code $ret)" >> configure.log + fi + return $ret + } +fi + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + +# see if shared library build supported +cat > $test.c <> configure.log + +# check for large file support, and if none, check for fseeko() +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main() { + _off64_t dummy = 0; + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for _off64_t... Yes." | tee -a configure.log + else + echo "Checking for _off64_t... No." | tee -a configure.log + fi + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = 0; + int ret = posix_memalign(&ptr, 64, 10); + if (ptr) + free(ptr); + return ret; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for posix_memalign... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_POSIX_MEMALIGN" + SFLAGS="${SFLAGS} -DHAVE_POSIX_MEMALIGN" +else + echo "Checking for posix_memalign... No." | tee -a configure.log +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = aligned_alloc(64, 10); + if (ptr) + free(ptr); + return 0; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for aligned_alloc... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_ALIGNED_ALLOC" + SFLAGS="${SFLAGS} -DHAVE_ALIGNED_ALLOC" +else + echo "Checking for aligned_alloc... No." | tee -a configure.log +fi +echo >> configure.log + +# check for strerror() for use by gz* functions +cat > $test.c < +#include +int main() { return strlen(strerror(errno)); } +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for strerror... Yes." | tee -a configure.log +else + CFLAGS="${CFLAGS} -DNO_STRERROR" + SFLAGS="${SFLAGS} -DNO_STRERROR" + echo "Checking for strerror... No." | tee -a configure.log +fi + +# check for getauxval() or elf_aux_info() for architecture feature detection at run-time +cat > $test.c < +int main() { +#ifdef __FreeBSD__ + int test; + return elf_aux_info(AT_PAGESZ, &test, sizeof(test)); +#else + return getauxval(0); +#endif +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for getauxval() or elf_aux_info() in sys/auxv.h... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_SYS_AUXV_H" + SFLAGS="${SFLAGS} -DHAVE_SYS_AUXV_H" +else + echo "Checking for getauxval() in sys/auxv.h... No." | tee -a configure.log +fi + +# We need to remove consigured files (zconf.h etc) from source directory if building outside of it +if [ "$SRCDIR" != "$BUILDDIR" ]; then + rm -f $SRCDIR/zconf${SUFFIX}.h + rm -f $SRCDIR/zlib${SUFFIX}.h + rm -f $SRCDIR/zlib_name_mangling${SUFFIX}.h +fi + +# Rename @ZLIB_SYMBOL_PREFIX@ to $symbol_prefix in gzread.c, zlib.h and zlib_name_mangling.h +sed < $SRCDIR/gzread.c.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > gzread.c +sed < $SRCDIR/zlib${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib${SUFFIX}.h +if [[ ! -z $symbol_prefix ]]; then + sed < $SRCDIR/zlib_name_mangling${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib_name_mangling${SUFFIX}.h +else + # symbol_prefix is not set, copy the empty mangling header + cp -p $SRCDIR/zlib_name_mangling.h.empty zlib_name_mangling${SUFFIX}.h +fi + +# copy clean zconf.h for subsequent edits +cp -p $SRCDIR/zconf${SUFFIX}.h.in zconf${SUFFIX}.h + +echo >> configure.log + +# check for unistd.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be set to #if 1/ 0\1 was set to #if 0/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +# check for ptrdiff_t and save result in zconf.h +echo -n "Checking for ptrdiff_t... " | tee -a configure.log +cat > $test.c < +int fun(ptrdiff_t *a) { (void)a; return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Yes." | tee -a configure.log +else + echo "No." | tee -a configure.log + sed < zconf${SUFFIX}.h "/^#ifdef NEED_PTRDIFF_T.* may be/s/def NEED_PTRDIFF_T\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + + echo -n "Checking for sizeof(void *)... " | tee -a configure.log + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int32_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int32_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int32_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int64_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int64_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int64_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + echo "unknown." | tee -a configure.log + exit 1 + fi + fi +fi + +# if --zlib-compat was requested +if test $compat -eq 1; then + gzfileops=1 + CFLAGS="${CFLAGS} -DZLIB_COMPAT" + SFLAGS="${SFLAGS} -DZLIB_COMPAT" + case "$uname" in + CYGWIN* | Cygwin* | cygwin* | MSYS* | msys* | MINGW* | mingw*) + DEFFILE="win32/zlibcompat.def" ;; + esac +fi + +if [[ ! -z $DEFFILE ]]; then + mkdir -p win32 + sed < $SRCDIR/$DEFFILE.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > $DEFFILE +fi + +# if --gzfileops was requested +if test $gzfileops -eq 1; then + CFLAGS="${CFLAGS} -DWITH_GZFILEOP" + SFLAGS="${SFLAGS} -DWITH_GZFILEOP" + OBJC="${OBJC} \$(OBJG)" + PIC_OBJC="${PIC_OBJC} \$(PIC_OBJG)" +else + TESTOBJG="\$(OBJG)" + PIC_TESTOBJG="\$(OBJG)" +fi + +# set architecture alignment requirements +if test $unalignedok -eq 0; then + CFLAGS="${CFLAGS} -DNO_UNALIGNED" + SFLAGS="${SFLAGS} -DNO_UNALIGNED" + echo "Unaligned reads manually disabled." | tee -a configure.log +fi + +# enable reduced memory configuration +if test $reducedmem -eq 1; then + echo "Configuring for reduced memory environment." | tee -a configure.log + CFLAGS="${CFLAGS} -DHASH_SIZE=32768u -DGZBUFSIZE=8192" +fi + +# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" + LDFLAGS="${LDFLAGS} -fprofile-arcs -ftest-coverage" + if test -n "$GCC_CLASSIC"; then + CC=$GCC_CLASSIC + fi +fi + +echo >> configure.log + +# Check for ANSI C compliant compiler +cat > $test.c < +#include +#include +#include "zconf${SUFFIX}.h" +int main() { +#ifdef STDC + return 0; +#endif + return 1; +} +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking for ANSI C compliant compiler... Yes." | tee -a configure.log + : +else + echo "Checking for ANSI C compliant compiler... No." | tee -a configure.log + echo "Error: ANSI C compatible compiler needed, cannot continue." | tee -a configure.log + leave 1 +fi + +# Check for -fno-semantic-interposition compiler support +echo "" > test.c + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-semantic-interposition... Yes." | tee -a configure.log + SFLAGS="$SFLAGS -fno-semantic-interposition" +else + echo "Checking for -fno-semantic-interposition... No." | tee -a configure.log +fi + +# Check for -fno-lto compiler support +if test $gcc -eq 1 -a $without_optimizations -eq 0 -a $native -eq 0; then + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-lto... Yes." | tee -a configure.log + else + echo "Checking for -fno-lto... No." | tee -a configure.log + noltoflag="" + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using hidden +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(hidden)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(hidden)) support... No." | tee -a configure.log + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using internal +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(internal)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(internal)) support... No." | tee -a configure.log + fi +fi + +# Check for attribute(aligned) support in compiler +cat > $test.c << EOF +int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for attribute(aligned) ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_ATTRIBUTE_ALIGNED" + SFLAGS="$SFLAGS -DHAVE_ATTRIBUTE_ALIGNED" +else + echo "Checking for attribute(aligned) ... No." | tee -a configure.log +fi + +# Check for _Thread_local support in compiler +cat > $test.c << EOF +_Thread_local int test; +int main(void) { + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for _Thread_local ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_THREAD_LOCAL" + SFLAGS="$SFLAGS -DHAVE_THREAD_LOCAL" +else + echo "Checking for _Thread_local ... No." | tee -a configure.log +fi + +# Check for __builtin_ctz() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctz ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZ" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZ" +else + echo "Checking for __builtin_ctz ... No." | tee -a configure.log +fi + +# Check for __builtin_ctzll() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned long long zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctzll ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZLL" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZLL" +else + echo "Checking for __builtin_ctzll ... No." | tee -a configure.log +fi + +check_avx2_intrinsics() { + # Check whether compiler supports AVX2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx2flag} $test.c; then + echo "Checking for AVX2 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX2_INTRIN=1 + else + echo "Checking for AVX2 intrinsics ... No." | tee -a configure.log + HAVE_AVX2_INTRIN=0 + fi +} + +check_avx512_intrinsics() { + # Check whether compiler supports AVX512 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for AVX512 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512_INTRIN=1 + else + echo "Checking for AVX512 intrinsics ... No." | tee -a configure.log + HAVE_AVX512_INTRIN=0 + fi +} + +check_mtune_skylake_avx512_compiler_flag() { + # Check whether -mtune=skylake-avx512 works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=skylake-avx512 $test.c; then + MTUNE_SKYLAKE_AVX512_AVAILABLE=1 + echo "Check whether -mtune=skylake-avx512 works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=skylake-avx512 works ... No." | tee -a configure.log + MTUNE_SKYLAKE_AVX512_AVAILABLE=0 + fi +} + +check_mtune_cascadelake_compiler_flag() { + # Check whether -mtune=cascadelake works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=cascadelake $test.c; then + MTUNE_CASCADELAKE_AVAILABLE=1 + echo "Check whether -mtune=cascadelake works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=cascadelake works ... No." | tee -a configure.log + MTUNE_CASCADELAKE_AVAILABLE=0 + check_mtune_skylake_avx512_compiler_flag + fi +} + +check_avx512vnni_intrinsics() { + # Check whether compiler supports AVX512-VNNI intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512vnniflag} $test.c; then + echo "Checking for AVX512VNNI intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=1 + else + echo "Checking for AVX512VNNI intrinsics ... No." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=0 + fi +} + +check_mask_intrinsics() { + # Check whether compiler supports AVX512 k-mask intrinsics + cat > $test.c << EOF +#include +int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for k-mask intrinsics ... Yes." | tee -a configure.log + HAVE_MASK_INTRIN=1 + else + echo "Checking for k-mask intrinsics ... No." | tee -a configure.log + HAVE_MASK_INTRIN=0 + fi +} + +check_acle_compiler_flag() { + # Check whether -march=armv8-a+crc works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -march=armv8-a+crc $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc works ... Yes." | tee -a configure.log + else + echo "Check whether -march=armv8-a+crc works ... No." | tee -a configure.log + if try $CC -c $CFLAGS -march=armv8-a+crc+simd $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc+simd works ... Yes." | tee -a configure.log + if test "$ARCH" = "armv8-a+crc"; then + ARCH=armv8-a+crc+simd + fi + else + ACLE_AVAILABLE=0 + echo "Check whether -march=armv8-a+crc+simd works ... No." | tee -a configure.log + fi + fi +} + +check_neon_compiler_flag() { + # Check whether -mfpu=neon is available on ARM processors. + cat > $test.c << EOF +#ifdef _M_ARM64 + # include + #else + # include +#endif +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mfpu=neon $test.c; then + MFPU_NEON_AVAILABLE=1 + echo "Check whether -mfpu=neon is available ... Yes." | tee -a configure.log + else + MFPU_NEON_AVAILABLE=0 + echo "Check whether -mfpu=neon is available ... No." | tee -a configure.log + fi +} + +check_neon_ld4_intrinsics() { + if test $buildneon -eq 1 && test $native -eq 0; then + if test "$CC_ARCH" = "aarch64" || test "$CC_ARCH" = "aarch64_be" || test "$CC_ARCH" = "arm64"; then + neonflag="-march=armv8-a+simd" + elif test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + fi + cat > $test.c << EOF +#ifdef _M_ARM64 +# include +#else +# include +#endif +int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; +} +EOF + if try $CC -c $CFLAGS $neonflag $test.c; then + NEON_HAS_LD4=1 + echo "check whether compiler supports 4 wide register loads ... Yes." | tee -a configure.log + else + NEON_HAS_LD4=0 + echo "check whether compiler supports 4 wide register loads ... No." | tee -a configure.log + fi +} + +check_pclmulqdq_intrinsics() { + # Check whether compiler supports PCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${pclmulflag} $test.c; then + echo "Checking for PCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=1 + else + echo "Checking for PCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=0 + fi +} + +check_vpclmulqdq_intrinsics() { + # Check whether compiler supports VPCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${vpclmulflag} $test.c; then + echo "Checking for VPCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=1 + else + echo "Checking for VPCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=0 + fi +} + +check_xsave_intrinsics() { + # Check whether compiler supports XSAVE intrinsics + cat > $test.c << EOF +#ifdef _WIN32 +# include +#else +# include +#endif +int main(void) { + return _xgetbv(0); +} +EOF + if try ${CC} ${CFLAGS} ${xsaveflag} $test.c; then + echo "Checking for XSAVE intrinsics ... Yes." | tee -a configure.log + HAVE_XSAVE_INTRIN=1 + else + echo "Checking for XSAVE intrinsics ... No." | tee -a configure.log + HAVE_XSAVE_INTRIN=0 + fi +} + +check_ppc_intrinsics() { + cat > $test.c << EOF +#include +int main(void) +{ + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; +} +EOF + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec $test.c; then + echo "Checking for AltiVec intrinsics ... Yes." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=1 + else + echo "Checking for AltiVec intrinsics ... No." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=0 + fi + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec -mno-vsx $test.c; then + echo "Checking if -mno-vsx is supported ... Yes." | tee -a configure.log + vmxflag="$vmxflag -mno-vsx" + else + echo "Checking if -mno-vsx is supported ... No." | tee -a configure.log + fi + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); +#else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); +#endif +} +EOF + if try $CC -c $CFLAGS -maltivec $test.c; then + HAVE_VMX=1 + echo "Check whether VMX instructions are available ... Yes." | tee -a configure.log + else + HAVE_VMX=0 + echo "Check whether VMX instructions are available ... No." | tee -a configure.log + fi +} + +check_power8_intrinsics() { + # Check whether features needed by POWER8 optimisations are available + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); +#else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); +#endif +} +EOF + if test $buildpower8 -eq 1 && try $CC -c $CFLAGS -mcpu=power8 $test.c; then + HAVE_POWER8_INTRIN=1 + echo "Check whether POWER8 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER8_INTRIN=0 + echo "Check whether POWER8 instructions are available ... No." | tee -a configure.log + fi +} + +check_power9_intrinsics() { + # Check whether features needed by POWER9 optimisations are available + cat > $test.c << EOF +int main() { return 0; } +EOF + if test $buildpower9 -eq 1 && try $CC -c $CFLAGS -mcpu=power9 $test.c; then + HAVE_POWER9_INTRIN=1 + echo "Check whether POWER9 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER9_INTRIN=0 + echo "Check whether POWER9 instructions are available ... No." | tee -a configure.log + fi +} + +check_sse2_intrinsics() { + # Check whether compiler supports SSE2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse2flag} $test.c; then + echo "Checking for SSE2 intrinsics ... Yes." | tee -a configure.log + HAVE_SSE2_INTRIN=1 + else + echo "Checking for SSE2 intrinsics ... No." | tee -a configure.log + HAVE_SSE2_INTRIN=0 + fi +} + +check_sse42_intrinsics() { + # Check whether compiler supports SSE4.2 CRC inline asm + cat > $test.c << EOF +int main(void) { + unsigned val = 0, h = 0; + __asm__ __volatile__ ( "crc32 %1,%0" : "+r" (h) : "r" (val) ); + return (int) h; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC inline assembly ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=1 + else + echo "Checking for SSE4.2 CRC inline assembly ... No." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=0 + fi + + # Check whether compiler supports SSE4.2 CRC intrinsics + cat > $test.c << EOF +int main(void) { + unsigned crc = 0; + char c = 'c'; + crc = __builtin_ia32_crc32qi(crc, c); + (void)crc; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC intrinsics ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=1 + else + echo "Checking for SSE4.2 CRC intrinsics ... No." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=0 + fi +} + +check_ssse3_intrinsics() { + # Check whether compiler supports SSSE3 intrinsics + cat > $test.c << EOF +#include +int main(void) +{ + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${ssse3flag} $test.c; then + echo "Checking for SSSE3 intrinsics ... Yes." | tee -a configure.log + HAVE_SSSE3_INTRIN=1 + else + echo "Checking for SSSE3 intrinsics ... No." | tee -a configure.log + HAVE_SSSE3_INTRIN=0 + fi +} + +check_vgfma_intrinsics() { + # Check whether "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic is available + echo -n "Checking for -mzarch... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -mzarch; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -mzarch" + else + echo No. | tee -a configure.log + fi + echo -n "Checking for -fzvector... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -fzvector; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -fzvector" + else + echo No. | tee -a configure.log + fi + cat > $test.c << EOF +#include +int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; +} +EOF + echo -n "Checking for VGFMA support... " | tee -a configure.log + if try $CC -c $CFLAGS $vgfmaflag $test.c; then + HAVE_VGFMA_INTRIN=1 + echo "Yes." | tee -a configure.log + else + HAVE_VGFMA_INTRIN=0 + echo "No." | tee -a configure.log + fi +} + +case "${ARCH}" in + i386 | i486 | i586 | i686 | x86_64) + # Enable deflate_medium at level 1 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_QUICK_STRATEGY" + SFLAGS="${SFLAGS} -DNO_QUICK_STRATEGY" + fi + # Enable deflate_medium at level 4-6 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_MEDIUM_STRATEGY" + SFLAGS="${SFLAGS} -DNO_MEDIUM_STRATEGY" + fi + ;; +esac + +ARCHDIR='arch/generic' +ARCH_STATIC_OBJS='' +ARCH_SHARED_OBJS='' + +# Set ARCH specific FLAGS +case "${ARCH}" in + # x86/amd64 specific optimizations + i386 | i486 | i586 | i686 |x86_64) + ARCHDIR=arch/x86 + + # Enable arch-specific optimizations + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DX86_FEATURES" + SFLAGS="${SFLAGS} -DX86_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} x86_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} x86_features.lo" + + check_avx2_intrinsics + + if test ${HAVE_AVX2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX2" + SFLAGS="${SFLAGS} -DX86_AVX2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} slide_hash_avx2.o chunkset_avx2.o compare256_avx2.o adler32_avx2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} slide_hash_avx2.lo chunkset_avx2.lo compare256_avx2.lo adler32_avx2.lo" + fi + + check_avx512_intrinsics + + if test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512" + SFLAGS="${SFLAGS} -DX86_AVX512" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512.lo" + + check_mask_intrinsics + + if test ${HAVE_MASK_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_MASK_INTRIN" + SFLAGS="${SFLAGS} -DX86_MASK_INTRIN" + fi + fi + + check_mtune_cascadelake_compiler_flag + + if test ${MTUNE_CASCADELAKE_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=cascadelake" + else + if test ${MTUNE_SKYLAKE_AVX512_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=skylake-avx512" + fi + fi + + check_avx512vnni_intrinsics + + if test ${HAVE_AVX512VNNI_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512VNNI" + SFLAGS="${SFLAGS} -DX86_AVX512VNNI" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512_vnni.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512_vnni.lo" + fi + + check_sse42_intrinsics + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1 || test ${HAVE_SSE42CRC_INLINE_ASM} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42" + SFLAGS="${SFLAGS} -DX86_SSE42" + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42_CRC_INTRIN" + SFLAGS="${SFLAGS} -DX86_SSE42_CRC_INTRIN" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_sse42.o insert_string_sse42.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_sse42.lo insert_string_sse42.lo" + fi + + check_sse2_intrinsics + + if test ${HAVE_SSE2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE2" + SFLAGS="${SFLAGS} -DX86_SSE2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} chunkset_sse2.o compare256_sse2.o slide_hash_sse2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} chunkset_sse2.lo compare256_sse2.lo slide_hash_sse2.lo" + + if test $forcesse2 -eq 1; then + CFLAGS="${CFLAGS} -DX86_NOCHECK_SSE2" + SFLAGS="${SFLAGS} -DX86_NOCHECK_SSE2" + fi + fi + + check_ssse3_intrinsics + + if test ${HAVE_SSSE3_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSSE3" + SFLAGS="${SFLAGS} -DX86_SSSE3" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_ssse3.o chunkset_ssse3.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_ssse3.lo chunkset_ssse3.lo" + fi + + check_pclmulqdq_intrinsics + + if test ${HAVE_PCLMULQDQ_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_PCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_PCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_pclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_pclmulqdq.lo" + + if test $buildvpclmulqdq -eq 1; then + check_vpclmulqdq_intrinsics + + if test ${HAVE_VPCLMULQDQ_INTRIN} -eq 1 && test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_VPCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_VPCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_vpclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_vpclmulqdq.lo" + fi + fi + fi + + check_xsave_intrinsics + + if test ${HAVE_XSAVE_INTRIN} -eq 0; then + xsaveflag="" + fi + fi + ;; + + # ARM specific optimizations + arm*) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=arm + ARCHDIR=arch/arm + + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + cat > $test.c < +#include +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + else + echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + echo "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + fi + fi + + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=softfp && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=softfp" + else + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=hard && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=hard" + fi + fi + + if [ -z $floatabi ]; then + echo "ARM floating point arch not auto-detected" | tee -a configure.log + else + echo "ARM floating point arch: ${floatabi}" | tee -a configure.log + + CFLAGS="${CFLAGS} ${floatabi}" + SFLAGS="${SFLAGS} ${floatabi}" + fi + + if test $without_optimizations -eq 0; then + check_acle_compiler_flag + check_neon_compiler_flag + check_neon_ld4_intrinsics + fi + + case "${ARCH}" in + armv[345]*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + armv6l | armv6hl) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + arm | armv7*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a | armv8-a+simd) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a+crc | armv8-a+crc+simd | armv8.[1234]-a | armv8.[1234]-a+simd) + acleflag="-march=${ARCH}" + + if test $without_optimizations -eq 0; then + if test $ACLE_AVAILABLE -eq 1; then + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + esac + + ;; + # 64-bit ARM specific optimizations + aarch64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=aarch64 + ARCHDIR=arch/arm + + if test $native -eq 0; then + ARCH="armv8-a" + else + ARCH="native" + fi + + if test $without_optimizations -eq 0; then + check_neon_ld4_intrinsics + + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + echo "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+crc" + fi + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+simd" + fi + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + + neonflag="-march=${ARCH}" + acleflag="-march=${ARCH}" + ;; + powerpc*) + case "${ARCH}" in + powerpc) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc + ;; + powerpc64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64 + ;; + powerpc64le) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64le + ;; + esac + + ARCHDIR=arch/power + + if test $without_optimizations -eq 0; then + + check_ppc_intrinsics + check_power8_intrinsics + check_power9_intrinsics + + if test $HAVE_VMX -eq 1; then + CFLAGS="${CFLAGS} -DPPC_FEATURES" + SFLAGS="${SFLAGS} -DPPC_FEATURES" + fi + if test $HAVE_VMX -eq 1 -o $HAVE_POWER8_INTRIN -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} power_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} power_features.lo" + fi + if test $HAVE_VMX -eq 1 -a $HAVE_ALTIVEC_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPPC_VMX" + SFLAGS="${SFLAGS} -DPPC_VMX" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_vmx.o slide_hash_vmx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_vmx.lo slide_hash_vmx.lo" + fi + if test $HAVE_POWER8_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_power8.o chunkset_power8.o slide_hash_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_power8.lo chunkset_power8.lo slide_hash_power8.lo" + case "${ARCH}" in + powerpc64*) + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_power8.lo" + CFLAGS="${CFLAGS} -DPOWER8_VSX_CRC32" + SFLAGS="${SFLAGS} -DPOWER8_VSX_CRC32" + ;; + esac + fi + if test $HAVE_POWER9_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER9 -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER9 -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} compare256_power9.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} compare256_power9.lo" + fi + fi + ;; + s390x) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=s390x + ARCHDIR=arch/s390 + + if test $without_optimizations -eq 0; then + if test $buildcrc32vx -eq 1; then + CFLAGS="${CFLAGS} -DS390_FEATURES" + SFLAGS="${SFLAGS} -DS390_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} s390_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} s390_features.lo" + fi + + if test $builddfltccdeflate -eq 1 -o $builddfltccinflate -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_common.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_common.lo" + fi + + if test $builddfltccdeflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_DEFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_DEFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_deflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_deflate.lo" + ARCH="${ARCH}+dfltcc-deflate" + fi + + if test $builddfltccinflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_INFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_INFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_inflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_inflate.lo" + ARCH="${ARCH}+dfltcc-inflate" + fi + + if test $buildcrc32vx -eq 1; then + check_vgfma_intrinsics + if test $HAVE_VGFMA_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DS390_CRC32_VX" + SFLAGS="${SFLAGS} -DS390_CRC32_VX" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32-vx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32-vx.lo" + ARCH="${ARCH}+crc32-vx" + fi + fi + fi + ;; + *) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=$ARCH + ;; +esac + +echo "ARCH: ${ARCH}" +echo "Using arch directory: ${ARCHDIR}" +echo "Architecture-specific static object files:${ARCH_STATIC_OBJS}" +echo "Architecture-specific shared object files:${ARCH_SHARED_OBJS}" + +# show the results in the log +echo >> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDFLAGS = $LDSHAREDFLAGS >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo DEFFILE = $DEFFILE >> configure.log +echo RC = $RC >> configure.log +echo RCFLAGS = $RCFLAGS >> configure.log +echo RCOBJS = $RCOBJS >> configure.log +echo STRIP = $STRIP >> configure.log +echo OBJC = $OBJC >> configure.log +echo TESTOBJG = $TESTOBJG >> configure.log +echo PIC_TESTOBJG = $PIC_TESTOBJG >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo SHAREDTARGET = $SHAREDTARGET >> configure.log +echo IMPORTLIB = $IMPORTLIB >> configure.log +echo INSTALLTARGETS = $INSTALLTARGETS >> configure.log +echo UNINSTALLTARGETS = $UNINSTALLTARGETS >> configure.log +echo SRCDIR = $SRCDIR >> configure.log +echo BUILDDIR = $BUILDDIR >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo bindir = $bindir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo symbol_prefix = $symbol_prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log +echo sse2flag = $sse2flag >> configure.log +echo ssse3flag = $ssse3flag >> configure.log +echo sse42flag = $sse42flag >> configure.log +echo pclmulflag = $pclmulflag >> configure.log +echo vpclmulflag = $vpclmulflag >> configure.log +echo xsaveflag = $xsaveflag >> configure.log +echo acleflag = $acleflag >> configure.log +echo neonflag = $neonflag >> configure.log +echo ARCHDIR = ${ARCHDIR} >> configure.log +echo ARCH_STATIC_OBJS = ${ARCH_STATIC_OBJS} >> configure.log +echo ARCH_SHARED_OBJS = ${ARCH_SHARED_OBJS} >> configure.log + +# Handle sed incompatibilities when using -i +replace_in_file() { + if [ "$OS" = 'Darwin' ]; then + sed -i '.tmp' -e "$1" "$2" + else + sed -i'.tmp' -e "$1" "$2" + fi +} + +# update Makefile with the configure results + +INCLUDES="-I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then INCLUDES="-I$BUILDDIR ${INCLUDES}"; fi + +sed < $SRCDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^LIBNAME1 *=/s#=.*#=$LIBNAME# +/^LIBNAME2 *=/s#=.*#=$LIBNAME2# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^SHAREDTARGET *=/s#=.*#=$SHAREDTARGET# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^VER *=/s#=.*#=$VER# +/^VER1 *=/s#=.*#=$VER1# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^DEFFILE *=/s#=.*#=$DEFFILE# +/^RC *=/s#=.*#=$RC# +/^RCFLAGS *=/s#=.*#=$RCFLAGS# +/^RCOBJS *=/s#=.*#=$RCOBJS# +/^STRIP *=/s#=.*#=$STRIP# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#= $prefix# +/^exec_prefix *=/s#=.*#= $exec_prefix# +/^bindir *=/s#=.*#= $bindir# +/^symbol_prefix *=/s#=.*#= $symbol_prefix# +/^libdir *=/s#=.*#= $libdir# +/^sharedlibdir *=/s#=.*#= $sharedlibdir# +/^includedir *=/s#=.*#= $includedir# +/^mandir *=/s#=.*#= $mandir# +/^SRCDIR *=/s#=.*#=$SRCDIR# +/^INCLUDES *=/s#=.*#=$INCLUDES# +/^OBJC *=/s#=.*#= $OBJC# +/^TESTOBJG *=/s#=.*#= $TESTOBJG# +/^PIC_TESTOBJG *=/s#=.*#= $PIC_TESTOBJG# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^install-libs: */s#:.*#: $INSTALLTARGETS# +/^uninstall-libs: */s#:.*#: $UNINSTALLTARGETS# +/^ARCHDIR *=/s#=.*#=$ARCHDIR# +/^ARCH_STATIC_OBJS *=/s#=.*#=$ARCH_STATIC_OBJS# +/^ARCH_SHARED_OBJS *=/s#=.*#=$ARCH_SHARED_OBJS# +" > Makefile + +# Append header files dependences. +for file in $SRCDIR/*.c $SRCDIR/test/*.c $SRCDIR/test/fuzz/*.c $SRCDIR/$ARCHDIR/*.c $SRCDIR/tools/*.c; do + short_name=$(echo $file | sed -e "s#$SRCDIR/##g") + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$ARCHDIR/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + + if grep -q "^$obj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + + # In case this is one of the ARCHDIR files, append a dependence line + # that will force the `$(MAKE) -C $(ARCHDIR)` generic rule. Without this + # we would only execute the copy rule from ARCHDIR to SRCDIR. + if test -e $SRCDIR/$ARCHDIR/$(basename $file); then + echo "$ARCHDIR/$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi + fi + + if grep -q "^$lobj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi +done + +# Generate Makefile in arch dir +mkdir -p $ARCHDIR + +ARCHINCLUDES="-I$SRCDIR/$ARCHDIR -I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then ARCHINCLUDES="-I$BUILDDIR ${ARCHINCLUDES}"; fi + +sed < $SRCDIR/$ARCHDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^INCLUDES *=/s#=.*#=$ARCHINCLUDES# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^SRCDIR *=/s#=.*#=$SRCDIR/$ARCHDIR# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^BUILDDIR *=/s#=.*#=$BUILDDIR# +/^AVX2FLAG *=/s#=.*#=$avx2flag# +/^AVX512FLAG *=/s#=.*#=$avx512flag# +/^AVX512VNNIFLAG *=/s#=.*#=$avx512vnniflag# +/^SSE2FLAG *=/s#=.*#=$sse2flag# +/^SSSE3FLAG *=/s#=.*#=$ssse3flag# +/^SSE42FLAG *=/s#=.*#=$sse42flag# +/^PCLMULFLAG *=/s#=.*#=$pclmulflag# +/^VPCLMULFLAG *=/s#=.*#=$vpclmulflag# +/^XSAVEFLAG *=/s#=.*#=$xsaveflag# +/^ACLEFLAG *=/s#=.*#=$acleflag# +/^NEONFLAG *=/s#=.*#=$neonflag# +/^NOLTOFLAG *=/s#=.*#=$noltoflag# +/^VGFMAFLAG *=/s#=.*#=$vgfmaflag# +/^PPCFLAGS *=/s#=.*#=$vmxflag# +" > $ARCHDIR/Makefile + +# Append header files dependences. +for file in $SRCDIR/$ARCHDIR/*.c; do + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCTOP)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + short_name=$(basename $file) + if grep -q "^$obj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi + + if grep -q "^$lobj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi +done + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if test "$CHOST" != "wasm32"; then + TEST="${TEST} ghtests" +fi + +# Determine emulator to use when running tests +if test -z "$EMU_RUN" && test $QEMU_ARCH; then + EMU_RUN="qemu-$QEMU_ARCH -L /usr/${CHOST}/" +fi +if test -n "$EMU_RUN"; then + echo "Using cross-compile emulator: $EMU_RUN" +fi + +# Generate Makefile in test dir +mkdir -p test +sed < $SRCDIR/test/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^EXE *=/s#=.*#=$EXE# +/^alltests: */s#:.*#: $TEST# +/^SRCDIR *=/s#=.*#=$SRCDIR/test# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^EMU_RUN *=/s#=.*#=$EMU_RUN# +/^LIBNAME *=/s#=.*#=$LIBNAME# +" > test/Makefile + +# create zlib.pc with the configure results +sed < $SRCDIR/zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^bindir *=/s#=.*#=$bindir# +/^symbol_prefix *=/s#=.*#=$symbol_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +s/\@SUFFIX\@/$SUFFIX/g; +" > ${LIBNAME2}.pc + +# done +leave 0 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.c b/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.c new file mode 100644 index 000000000..b69a01304 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.c @@ -0,0 +1,21 @@ +/* cpu_features.c -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "cpu_features.h" +#include + +Z_INTERNAL void cpu_check_features(struct cpu_features *features) { + memset(features, 0, sizeof(struct cpu_features)); +#if defined(X86_FEATURES) + x86_check_features(&features->x86); +#elif defined(ARM_FEATURES) + arm_check_features(&features->arm); +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + power_check_features(&features->power); +#elif defined(S390_FEATURES) + s390_check_features(&features->s390); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.h new file mode 100644 index 000000000..2e1a888e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/cpu_features.h @@ -0,0 +1,270 @@ +/* cpu_features.h -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CPU_FEATURES_H_ +#define CPU_FEATURES_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +#if defined(X86_FEATURES) +# include "arch/x86/x86_features.h" +# include "fallback_builtins.h" +#elif defined(ARM_FEATURES) +# include "arch/arm/arm_features.h" +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) +# include "arch/power/power_features.h" +#elif defined(S390_FEATURES) +# include "arch/s390/s390_features.h" +#endif + +struct cpu_features { +#if defined(X86_FEATURES) + struct x86_cpu_features x86; +#elif defined(ARM_FEATURES) + struct arm_cpu_features arm; +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + struct power_cpu_features power; +#elif defined(S390_FEATURES) + struct s390_cpu_features s390; +#else + char empty; +#endif +}; + +extern void cpu_check_features(struct cpu_features *features); + +/* adler32 */ +typedef uint32_t (*adler32_func)(uint32_t adler, const uint8_t *buf, size_t len); + +extern uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len); +#ifdef ARM_NEON +extern uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef PPC_VMX +extern uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_SSSE3 +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_avx2(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_avx512(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef POWER8_VSX +extern uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len); +#endif + +/* adler32 folding */ +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +/* CRC32 folding */ +#ifdef X86_PCLMULQDQ_CRC +extern uint32_t crc32_fold_pclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_pclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_pclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_pclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_pclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) +extern uint32_t crc32_fold_vpclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_vpclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_vpclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_vpclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif + +/* memory chunking */ +extern uint32_t chunksize_c(void); +extern uint8_t* chunkmemset_safe_c(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#ifdef X86_SSE2 +extern uint32_t chunksize_sse2(void); +extern uint8_t* chunkmemset_safe_sse2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_SSSE3 +extern uint8_t* chunkmemset_safe_ssse3(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_AVX2 +extern uint32_t chunksize_avx2(void); +extern uint8_t* chunkmemset_safe_avx2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef ARM_NEON +extern uint32_t chunksize_neon(void); +extern uint8_t* chunkmemset_safe_neon(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef POWER8_VSX +extern uint32_t chunksize_power8(void); +extern uint8_t* chunkmemset_safe_power8(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +/* inflate fast loop */ +extern void inflate_fast_c(PREFIX3(stream) *strm, uint32_t start); +#ifdef X86_SSE2 +extern void inflate_fast_sse2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_SSSE3 +extern void inflate_fast_ssse3(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_AVX2 +extern void inflate_fast_avx2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef ARM_NEON +extern void inflate_fast_neon(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef POWER8_VSX +extern void inflate_fast_power8(PREFIX3(stream) *strm, uint32_t start); +#endif + +/* CRC32 */ +typedef uint32_t (*crc32_func)(uint32_t crc32, const uint8_t *buf, size_t len); + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); +#ifdef ARM_ACLE +extern uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(POWER8_VSX) +extern uint32_t crc32_power8(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(S390_CRC32_VX) +extern uint32_t crc32_s390_vx(uint32_t crc, const uint8_t *buf, size_t len); +#endif + +/* compare256 */ +typedef uint32_t (*compare256_func)(const uint8_t *src0, const uint8_t *src1); + +extern uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1); +#endif +#ifdef POWER9 +extern uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1); +#endif + +#ifdef DEFLATE_H_ +/* insert_string */ +extern void insert_string_c(deflate_state *const s, const uint32_t str, uint32_t count); +#ifdef X86_SSE42 +extern void insert_string_sse42(deflate_state *const s, const uint32_t str, uint32_t count); +#elif defined(ARM_ACLE) +extern void insert_string_acle(deflate_state *const s, const uint32_t str, uint32_t count); +#endif + +/* longest_match */ +extern uint32_t longest_match_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_unaligned_16(deflate_state *const s, Pos cur_match); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t longest_match_unaligned_32(deflate_state *const s, Pos cur_match); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_power9(deflate_state *const s, Pos cur_match); +#endif + +/* longest_match_slow */ +extern uint32_t longest_match_slow_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_slow_unaligned_16(deflate_state *const s, Pos cur_match); +extern uint32_t longest_match_slow_unaligned_32(deflate_state *const s, Pos cur_match); +#ifdef UNALIGNED64_OK +extern uint32_t longest_match_slow_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_slow_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_slow_power9(deflate_state *const s, Pos cur_match); +#endif + +/* quick_insert_string */ +extern Pos quick_insert_string_c(deflate_state *const s, const uint32_t str); +#ifdef X86_SSE42 +extern Pos quick_insert_string_sse42(deflate_state *const s, const uint32_t str); +#elif defined(ARM_ACLE) +extern Pos quick_insert_string_acle(deflate_state *const s, const uint32_t str); +#endif + +/* slide_hash */ +typedef void (*slide_hash_func)(deflate_state *s); + +#ifdef X86_SSE2 +extern void slide_hash_sse2(deflate_state *s); +#elif defined(ARM_NEON) +extern void slide_hash_neon(deflate_state *s); +#endif +#if defined(PPC_VMX) +extern void slide_hash_vmx(deflate_state *s); +#endif +#if defined(POWER8_VSX) +extern void slide_hash_power8(deflate_state *s); +#endif +#ifdef X86_AVX2 +extern void slide_hash_avx2(deflate_state *s); +#endif + +/* update_hash */ +extern uint32_t update_hash_c(deflate_state *const s, uint32_t h, uint32_t val); +#ifdef X86_SSE42 +extern uint32_t update_hash_sse42(deflate_state *const s, uint32_t h, uint32_t val); +#elif defined(ARM_ACLE) +extern uint32_t update_hash_acle(deflate_state *const s, uint32_t h, uint32_t val); +#endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid.c b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid.c new file mode 100644 index 000000000..96754b53d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid.c @@ -0,0 +1,267 @@ +/* crc32_braid.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "functable.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" + +/* ========================================================================= */ + +const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) { + return (const uint32_t *)crc_table; +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return (unsigned long)functable.crc32((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return functable.crc32(crc, buf, len); +} +#endif + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32)(unsigned long crc, const unsigned char *buf, unsigned int len) { + return (unsigned long)PREFIX(crc32_z)((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t len) { + return PREFIX(crc32_z)(crc, buf, len); +} +#endif + +/* ========================================================================= */ + +/* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32 tables would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. +*/ + +/* ========================================================================= */ + +#if BYTE_ORDER == LITTLE_ENDIAN +# define ZSWAPWORD(word) (word) +# define BRAID_TABLE crc_braid_table +#elif BYTE_ORDER == BIG_ENDIAN +# if W == 8 +# define ZSWAPWORD(word) ZSWAP64(word) +# elif W == 4 +# define ZSWAPWORD(word) ZSWAP32(word) +# endif +# define BRAID_TABLE crc_braid_big_table +#else +# error "No endian defined" +#endif +#define DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +#ifdef W +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +#if BYTE_ORDER == LITTLE_ENDIAN +static uint32_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (uint32_t)data; +} +#elif BYTE_ORDER == BIG_ENDIAN +static z_word_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} +#endif /* BYTE_ORDER */ + +#endif /* W */ + +/* ========================================================================= */ +Z_INTERNAL uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + + /* Pre-condition the CRC */ + c = (~crc) & 0xffffffff; + +#ifdef W + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + size_t blks; + z_word_t const *words; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((uintptr_t)buf & (W - 1)) != 0) { + len--; + DO1; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + /* Initialize the CRC for each braid. */ + crc0 = ZSWAPWORD(c); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + /* Process the first blks-1 blocks, computing the CRCs on each braid independently. */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should get unrolled. */ + crc0 = BRAID_TABLE[0][word0 & 0xff]; +#if N > 1 + crc1 = BRAID_TABLE[0][word1 & 0xff]; +#if N > 2 + crc2 = BRAID_TABLE[0][word2 & 0xff]; +#if N > 3 + crc3 = BRAID_TABLE[0][word3 & 0xff]; +#if N > 4 + crc4 = BRAID_TABLE[0][word4 & 0xff]; +#if N > 5 + crc5 = BRAID_TABLE[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= BRAID_TABLE[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= BRAID_TABLE[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= BRAID_TABLE[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= BRAID_TABLE[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= BRAID_TABLE[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= BRAID_TABLE[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* Process the last block, combining the CRCs of the N braids at the same time. */ + comb = crc_word(crc0 ^ words[0]); +#if N > 1 + comb = crc_word(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + c = ZSWAPWORD(comb); + + /* Update the pointer to the remaining bytes to process. */ + buf = (const unsigned char *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + DO8; + } + while (len) { + len--; + DO1; + } + + /* Return the CRC, post-conditioned. */ + return c ^ 0xffffffff; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb.c b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb.c new file mode 100644 index 000000000..75fb47425 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb.c @@ -0,0 +1,57 @@ +/* crc32_braid_comb.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" +#include "crc32_braid_comb_p.h" + +/* ========================================================================= */ +static uint32_t crc32_combine_(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; +} +static uint32_t crc32_combine_gen_(z_off64_t len2) { + return x2nmodp(len2, 3); +} +static uint32_t crc32_combine_op_(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return multmodp(op, crc1) ^ crc2; +} + +/* ========================================================================= */ + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off64_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_gen)(z_off_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_op)(unsigned long crc1, unsigned long crc2, const unsigned long op) { + return (unsigned long)crc32_combine_op_((uint32_t)crc1, (uint32_t)crc2, (uint32_t)op); +} +#else +uint32_t Z_EXPORT PREFIX4(crc32_combine)(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return crc32_combine_(crc1, crc2, len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_op)(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return crc32_combine_op_(crc1, crc2, op); +} +#endif + +/* ========================================================================= */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb_p.h new file mode 100644 index 000000000..a269e7f5b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_comb_p.h @@ -0,0 +1,42 @@ +#ifndef CRC32_BRAID_COMB_P_H_ +#define CRC32_BRAID_COMB_P_H_ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +static uint32_t multmodp(uint32_t a, uint32_t b) { + uint32_t m, p; + + m = (uint32_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +static uint32_t x2nmodp(z_off64_t n, unsigned k) { + uint32_t p; + + p = (uint32_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#endif /* CRC32_BRAID_COMB_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_p.h new file mode 100644 index 000000000..1d8a07068 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_p.h @@ -0,0 +1,50 @@ +#ifndef CRC32_BRAID_P_H_ +#define CRC32_BRAID_P_H_ + +#include "zbuild.h" +#include "zendian.h" + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifndef W +# if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 + typedef uint64_t z_word_t; +# else +# undef W +# define W 4 + typedef uint32_t z_word_t; +# endif +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); + +#endif /* CRC32_BRAID_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_tbl.h b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_tbl.h new file mode 100644 index 000000000..84d79a69e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_braid_tbl.h @@ -0,0 +1,9446 @@ +#ifndef CRC32_BRAID_TBL_H_ +#define CRC32_BRAID_TBL_H_ + +/* crc32_braid_tbl.h -- tables for braided CRC calculation + * Generated automatically by makecrct.c + */ + +static const uint32_t crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +static const z_word_t crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +static const z_word_t crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#endif /* W */ + +#if N == 1 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif /* W */ + +#endif /* N == 1 */ +#if N == 2 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif /* W */ + +#endif /* N == 2 */ +#if N == 3 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif /* W */ + +#endif /* N == 3 */ +#if N == 4 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif /* W */ + +#endif /* N == 4 */ +#if N == 5 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif /* W */ + +#endif /* N == 5 */ +#if N == 6 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif /* W */ + +#endif /* N == 6 */ + +static const uint32_t x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; + +#endif /* CRC32_BRAID_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.c b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.c new file mode 100644 index 000000000..5b3c7c459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.c @@ -0,0 +1,33 @@ +/* crc32_fold.c -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" +#include "functable.h" + +#include "crc32_fold.h" + +#include + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc) { + crc->value = CRC32_INITIAL_VALUE; + return crc->value; +} + +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { + crc->value = functable.crc32(crc->value, src, len); + memcpy(dst, src, len); +} + +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { + /* Note: while this is basically the same thing as the vanilla CRC function, we still need + * a functable entry for it so that we can generically dispatch to this function with the + * same arguments for the versions that _do_ do a folding CRC but we don't want a copy. The + * init_crc is an unused argument in this context */ + Z_UNUSED(init_crc); + crc->value = functable.crc32(crc->value, src, len); +} + +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc) { + return crc->value; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.h b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.h new file mode 100644 index 000000000..0d2ff6696 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/crc32_fold.h @@ -0,0 +1,21 @@ +/* crc32_fold.h -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef CRC32_FOLD_H_ +#define CRC32_FOLD_H_ + +#define CRC32_FOLD_BUFFER_SIZE (16 * 4) +/* sizeof(__m128i) * (4 folds) */ + +typedef struct crc32_fold_s { + uint8_t fold[CRC32_FOLD_BUFFER_SIZE]; + uint32_t value; +} crc32_fold; + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc); +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate.c new file mode 100644 index 000000000..3ea92a82d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate.c @@ -0,0 +1,1427 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in https://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef deflateInit +# undef deflateInit2 +#endif + +const char PREFIX(deflate_copyright)[] = " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_deflate.h" +#else +/* Memory management for the deflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_DEFLATE_STATE(strm) ((deflate_state *)ZALLOC(strm, 1, sizeof(deflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_DEFLATE_STATE(dst, src) memcpy(dst, src, sizeof(deflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define TRY_FREE_WINDOW(strm, addr) TRY_FREE(strm, addr) +/* Invoked at the beginning of deflateSetDictionary(). Useful for checking arch-specific window data. */ +# define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of deflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the end of deflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of deflateParams(). Useful for updating arch-specific compression parameters. */ +# define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) +/* Returns whether the last deflate(flush) operation did everything it's supposed to do. */ +# define DEFLATE_DONE(strm, flush) 1 +/* Adjusts the upper bound on compressed data length based on compression parameters and uncompressed data length. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) +/* Returns whether an optimistic upper bound on compressed data length should *not* be used. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 +/* Invoked for each deflate() call. Useful for plugging arch-specific deflation code. */ +# define DEFLATE_HOOK(strm, flush, bstate) 0 +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific deflation code already does that. */ +# define DEFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether reproducibility parameter can be set to a given value. */ +# define DEFLATE_CAN_SET_REPRODUCIBLE(strm, reproducible) 1 +#endif + +/* =========================================================================== + * Function prototypes. + */ +static int deflateStateCheck (PREFIX3(stream) *strm); +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush); +Z_INTERNAL block_state deflate_fast (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_quick (deflate_state *s, int flush); +#ifndef NO_MEDIUM_STRATEGY +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush); +#endif +Z_INTERNAL block_state deflate_slow (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_rle (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_huff (deflate_state *s, int flush); +static void lm_set_level (deflate_state *s, int level); +static void lm_init (deflate_state *s); +Z_INTERNAL unsigned read_buf (PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +extern uint32_t update_hash_roll (deflate_state *const s, uint32_t h, uint32_t val); +extern void insert_string_roll (deflate_state *const s, uint32_t str, uint32_t count); +extern Pos quick_insert_string_roll(deflate_state *const s, uint32_t str); + +/* =========================================================================== + * Local data + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + uint16_t good_length; /* reduce lazy search above this match length */ + uint16_t max_lazy; /* do not perform lazy search above this match length */ + uint16_t nice_length; /* quit search above this match length */ + uint16_t max_chain; + compress_func func; +} config; + +static const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ + +#ifdef NO_QUICK_STRATEGY +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +#else +/* 1 */ {0, 0, 0, 0, deflate_quick}, +/* 2 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +#endif + +#ifdef NO_MEDIUM_STRATEGY +/* 3 */ {4, 6, 32, 32, deflate_fast}, +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +#else +/* 3 */ {4, 6, 16, 6, deflate_medium}, +/* 4 */ {4, 12, 32, 24, deflate_medium}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_medium}, +/* 6 */ {8, 16, 128, 128, deflate_medium}, +#endif + +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ + +/* Note: the deflate() code requires max_lazy >= STD_MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + + +/* =========================================================================== + * Initialize the hash table. prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) do { \ + memset((unsigned char *)s->head, 0, HASH_SIZE * sizeof(*s->head)); \ + } while (0) + +/* ========================================================================= */ +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy) { + /* Todo: ignore strm->next_in if we use it as window */ + uint32_t window_padding = 0; + deflate_state *s; + int wrap = 1; + + if (strm == NULL) + return Z_STREAM_ERROR; + + strm->msg = NULL; + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; +#ifdef GZIP + } else if (windowBits > MAX_WBITS) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; +#endif + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < MIN_WBITS || + windowBits > MAX_WBITS || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED || + (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) + windowBits = 9; /* until 256-byte window bug fixed */ + + s = ZALLOC_DEFLATE_STATE(strm); + if (s == NULL) + return Z_MEM_ERROR; + strm->state = (struct internal_state *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = NULL; + s->w_bits = (unsigned int)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + s->window = (unsigned char *) ZALLOC_WINDOW(strm, s->w_size + window_padding, 2*sizeof(unsigned char)); + s->prev = (Pos *) ZALLOC(strm, s->w_size, sizeof(Pos)); + memset(s->prev, 0, s->w_size * sizeof(Pos)); + s->head = (Pos *) ZALLOC(strm, HASH_SIZE, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n-2) bits have been written, just + * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * symbols are written.) The closest the writing gets to what is unread is + * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (unsigned char *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf_size = s->lit_bufsize * 4; + + if (s->window == NULL || s->prev == NULL || s->head == NULL || s->pending_buf == NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + PREFIX(deflateEnd)(strm); + return Z_MEM_ERROR; + } + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->block_open = 0; + s->reproducible = 0; + + return PREFIX(deflateReset)(strm); +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(deflateInit)(PREFIX3(stream) *strm, int32_t level) { + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit_)(PREFIX3(stream) *strm, int32_t level, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, method, windowBits, memLevel, strategy); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +static int deflateStateCheck (PREFIX3(stream) *strm) { + deflate_state *s; + if (strm == NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && +#endif + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + deflate_state *s; + unsigned int str, n; + int wrap; + uint32_t avail; + const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = functable.adler32(strm->adler, dictionary, dictLength); + DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const unsigned char *)dictionary; + PREFIX(fill_window)(s); + while (s->lookahead >= STD_MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (STD_MIN_MATCH - 1); + s->insert_string(s, str, n); + s->strstart = str + n; + s->lookahead = STD_MIN_MATCH - 1; + PREFIX(fill_window)(s); + } + s->strstart += s->lookahead; + s->block_start = (int)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->prev_length = 0; + s->match_available = 0; + strm->next_in = (z_const unsigned char *)next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + deflate_state *s; + unsigned int len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != NULL && len) + memcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateResetKeep)(PREFIX3(stream) *strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_reset(&s->crc_fold); + } else +#endif + strm->adler = ADLER32_INITIAL_VALUE; + s->last_flush = -2; + + zng_tr_init(s); + + DEFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateReset)(PREFIX3(stream) *strm) { + int ret; + + ret = PREFIX(deflateResetKeep)(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePending)(PREFIX3(stream) *strm, uint32_t *pending, int32_t *bits) { + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (pending != NULL) + *pending = strm->state->pending; + if (bits != NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + deflate_state *s; + uint64_t value64 = (uint64_t)value; + int32_t put; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + if (bits < 0 || bits > BIT_BUF_SIZE || bits > (int32_t)(sizeof(value) << 3) || + s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = BIT_BUF_SIZE - s->bi_valid; + put = MIN(put, bits); + + if (s->bi_valid == 0) + s->bi_buf = value64; + else + s->bi_buf |= (value64 & ((UINT64_C(1) << put) - 1)) << s->bi_valid; + s->bi_valid += put; + zng_tr_flush_bits(s); + value64 >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int32_t strategy) { + deflate_state *s; + compress_func func; + int hook_flush = Z_NO_FLUSH; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) + return Z_STREAM_ERROR; + DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); /* hook for IBM Z DFLTCC */ + func = configuration_table[s->level].func; + + if (((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2) + || hook_flush != Z_NO_FLUSH) { + /* Flush the last buffer. Use Z_BLOCK mode, unless the hook requests a "stronger" one. */ + int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK; + int err = PREFIX(deflate)(strm, flush); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || ((int)s->strstart - s->block_start) + s->lookahead || !DEFLATE_DONE(strm, flush)) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) { + functable.slide_hash(s); + } else { + CLEAR_HASH(s); + } + s->matches = 0; + } + + lm_set_level(s, level); + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateTune)(PREFIX3(stream) *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (unsigned int)good_length; + s->max_lazy_match = (unsigned int)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (unsigned int)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long sourceLen) { + deflate_state *s; + unsigned long complen, wraplen; + + /* conservative upper bound for compressed data */ + complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen); /* hook for IBM Z DFLTCC */ + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (deflateStateCheck(strm)) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = GZIP_WRAPLEN; + if (s->gzhead != NULL) { /* user-supplied gzip header */ + unsigned char *str; + if (s->gzhead->extra != NULL) { + wraplen += 2 + s->gzhead->extra_len; + } + str = s->gzhead->name; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + str = s->gzhead->comment; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = ZLIB_WRAPLEN; + } + + /* if not default parameters, return conservative bound */ + if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */ + s->w_bits != MAX_WBITS || HASH_BITS < 15) { + if (s->level == 0) { + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + complen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7; + } + + return complen + wraplen; + } + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + wraplen; /* none, zlib or gzip wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + wraplen; +#endif +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) { + uint32_t len; + deflate_state *s = strm->state; + + zng_tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) + len = strm->avail_out; + if (len == 0) + return; + + Tracev((stderr, "[FLUSH]")); + memcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) + s->pending_out = s->pending_buf; +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) { + int32_t old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) + return Z_STREAM_ERROR; + s = strm->state; + + if (strm->next_out == NULL || (strm->avail_in != 0 && strm->next_in == NULL) + || (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + unsigned int level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) + header |= PRESET_DICT; + header += 31 - (header % 31); + + put_short_msb(s, (uint16_t)header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) + put_uint32_msb(s, strm->adler); + strm->adler = ADLER32_INITIAL_VALUE; + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + functable.crc32_fold_reset(&s->crc_fold); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_uint32(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == NULL ? 0 : 4) + + (s->gzhead->name == NULL ? 0 : 8) + + (s->gzhead->comment == NULL ? 0 : 16) + ); + put_uint32(s, s->gzhead->time); + put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) + put_short(s, (uint16_t)s->gzhead->extra_len); + if (s->gzhead->hcrc) + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + uint32_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + + while (s->pending + left > s->pending_buf_size) { + uint32_t copy = s->pending_buf_size - s->pending; + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_short(s, (uint16_t)strm->adler); + functable.crc32_fold_reset(&s->crc_fold); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : /* hook for IBM Z DFLTCC */ + s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + zng_tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + zng_tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + } + } + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) + return Z_OK; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_final(&s->crc_fold); + + put_uint32(s, strm->adler); + put_uint32(s, (uint32_t)strm->total_in); + } else +#endif + { + if (s->wrap == 1) + put_uint32_msb(s, strm->adler); + } + PREFIX(flush_pending)(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) + s->wrap = -s->wrap; /* write the trailer only once! */ + if (s->pending == 0) { + Assert(s->bi_valid == 0, "bi_buf not flushed"); + return Z_STREAM_END; + } + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateEnd)(PREFIX3(stream) *strm) { + int32_t status; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE_WINDOW(strm, strm->state->window); + + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + */ +int32_t Z_EXPORT PREFIX(deflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + deflate_state *ds; + deflate_state *ss; + uint32_t window_padding = 0; + + if (deflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + + ss = source->state; + + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + + ds = ZALLOC_DEFLATE_STATE(dest); + if (ds == NULL) + return Z_MEM_ERROR; + dest->state = (struct internal_state *) ds; + ZCOPY_DEFLATE_STATE(ds, ss); + ds->strm = dest; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + ds->window = (unsigned char *) ZALLOC_WINDOW(dest, ds->w_size + window_padding, 2*sizeof(unsigned char)); + ds->prev = (Pos *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Pos *) ZALLOC(dest, HASH_SIZE, sizeof(Pos)); + ds->pending_buf = (unsigned char *) ZALLOC(dest, ds->lit_bufsize, 4); + + if (ds->window == NULL || ds->prev == NULL || ds->head == NULL || ds->pending_buf == NULL) { + PREFIX(deflateEnd)(dest); + return Z_MEM_ERROR; + } + + memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(unsigned char)); + memcpy((void *)ds->prev, (void *)ss->prev, ds->w_size * sizeof(Pos)); + memcpy((void *)ds->head, (void *)ss->head, HASH_SIZE * sizeof(Pos)); + memcpy(ds->pending_buf, ss->pending_buf, ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { + uint32_t len = strm->avail_in; + + len = MIN(len, size); + if (len == 0) + return 0; + + strm->avail_in -= len; + + if (!DEFLATE_NEED_CHECKSUM(strm)) { + memcpy(buf, strm->next_in, len); +#ifdef GZIP + } else if (strm->state->wrap == 2) { + functable.crc32_fold_copy(&strm->state->crc_fold, buf, strm->next_in, len); +#endif + } else { + if (strm->state->wrap == 1) + strm->adler = functable.adler32_fold_copy(strm->adler, buf, strm->next_in, len); + else + memcpy(buf, strm->next_in, len); + } + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Set longest match variables based on level configuration + */ +static void lm_set_level(deflate_state *s, int level) { + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + + /* Use rolling hash for deflate_slow algorithm with level 9. It allows us to + * properly lookup different hash chains to speed up longest_match search. Since hashing + * method changes depending on the level we cannot put this into functable. */ + if (s->max_chain_length > 1024) { + s->update_hash = &update_hash_roll; + s->insert_string = &insert_string_roll; + s->quick_insert_string = &quick_insert_string_roll; + } else { + s->update_hash = functable.update_hash; + s->insert_string = functable.insert_string; + s->quick_insert_string = functable.quick_insert_string; + } + + s->level = level; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +static void lm_init(deflate_state *s) { + s->window_size = 2 * s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + lm_set_level(s, s->level); + + s->strstart = 0; + s->block_start = 0; + s->lookahead = 0; + s->insert = 0; + s->prev_length = 0; + s->match_available = 0; + s->match_start = 0; + s->ins_h = 0; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s) { + unsigned n; + unsigned int more; /* Amount of free space at the end of the window. */ + unsigned int wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s->window_size - s->lookahead - s->strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + memcpy(s->window, s->window+wsize, (unsigned)wsize); + if (s->match_start >= wsize) { + s->match_start -= wsize; + } else { + s->match_start = 0; + s->prev_length = 0; + } + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (int)wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + functable.slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) + break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = PREFIX(read_buf)(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= STD_MIN_MATCH) { + unsigned int str = s->strstart - s->insert; + if (UNLIKELY(s->max_chain_length > 1024)) { + s->ins_h = s->update_hash(s, s->window[str], s->window[str+1]); + } else if (str >= 1) { + s->quick_insert_string(s, str + 2 - STD_MIN_MATCH); + } + unsigned int count; + if (UNLIKELY(s->lookahead == 1)) { + count = s->insert - 1; + } else { + count = s->insert; + } + if (count > 0) { + s->insert_string(s, str, count); + s->insert -= count; + } + } + /* If the whole input has less than STD_MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to STD_MAX_MATCH since the longest match + * routines allow scanning to strstart + STD_MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + unsigned int curr = s->strstart + s->lookahead; + unsigned int init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + memset(s->window + curr, 0, init); + s->high_water = curr + init; + } else if (s->high_water < curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + memset(s->window + s->high_water, 0, init); + s->high_water += init; + } + } + + Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +#ifndef ZLIB_COMPAT +/* ========================================================================= + * Checks whether buffer size is sufficient and whether this parameter is a duplicate. + */ +static int32_t deflateSetParamPre(zng_deflate_param_value **out, size_t min_size, zng_deflate_param_value *param) { + int32_t buf_error = param->size < min_size; + + if (*out != NULL) { + (*out)->status = Z_BUF_ERROR; + buf_error = 1; + } + *out = param; + return buf_error; +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + size_t i; + deflate_state *s; + zng_deflate_param_value *new_level = NULL; + zng_deflate_param_value *new_strategy = NULL; + zng_deflate_param_value *new_reproducible = NULL; + int param_buf_error; + int version_error = 0; + int buf_error = 0; + int stream_error = 0; + int ret; + int val; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + /* Check buffer sizes and detect duplicates. */ + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + param_buf_error = deflateSetParamPre(&new_level, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_STRATEGY: + param_buf_error = deflateSetParamPre(&new_strategy, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_REPRODUCIBLE: + param_buf_error = deflateSetParamPre(&new_reproducible, sizeof(int), ¶ms[i]); + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + param_buf_error = 0; + break; + } + if (param_buf_error) { + params[i].status = Z_BUF_ERROR; + buf_error = 1; + } + } + /* Exit early if small buffers or duplicates are detected. */ + if (buf_error) + return Z_BUF_ERROR; + + /* Apply changes, remember if there were errors. */ + if (new_level != NULL || new_strategy != NULL) { + ret = PREFIX(deflateParams)(strm, new_level == NULL ? s->level : *(int *)new_level->buf, + new_strategy == NULL ? s->strategy : *(int *)new_strategy->buf); + if (ret != Z_OK) { + if (new_level != NULL) + new_level->status = Z_STREAM_ERROR; + if (new_strategy != NULL) + new_strategy->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + if (new_reproducible != NULL) { + val = *(int *)new_reproducible->buf; + if (DEFLATE_CAN_SET_REPRODUCIBLE(strm, val)) { + s->reproducible = val; + } else { + new_reproducible->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + + /* Report version errors only if there are no real errors. */ + return stream_error ? Z_STREAM_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + deflate_state *s; + size_t i; + int32_t buf_error = 0; + int32_t version_error = 0; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->level; + break; + case Z_DEFLATE_STRATEGY: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->strategy; + break; + case Z_DEFLATE_REPRODUCIBLE: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->reproducible; + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + break; + } + if (params[i].status == Z_BUF_ERROR) + buf_error = 1; + } + return buf_error ? Z_BUF_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate.h b/internal-complibs/zlib-ng-2.1.0-beta1/deflate.h new file mode 100644 index 000000000..e4b971f88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate.h @@ -0,0 +1,403 @@ +#ifndef DEFLATE_H_ +#define DEFLATE_H_ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zutil.h" +#include "zendian.h" +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define BIT_BUF_SIZE 64 +/* size of bit buffer in bi_buf */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +# define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +# define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +# define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +# define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#endif +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + +#define HASH_BITS 16u /* log2(HASH_SIZE) */ +#ifndef HASH_SIZE +# define HASH_SIZE 65536u /* number of elements in hash table */ +#endif +#define HASH_MASK (HASH_SIZE - 1u) /* HASH_SIZE-1 */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + uint16_t freq; /* frequency count */ + uint16_t code; /* bit string */ + } fc; + union { + uint16_t dad; /* father node in Huffman tree */ + uint16_t len; /* length of bit string */ + } dl; +} ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} tree_desc; + +typedef uint16_t Pos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. + */ +/* Type definitions for hash callbacks */ +typedef struct internal_state deflate_state; + +typedef uint32_t (* update_hash_cb) (deflate_state *const s, uint32_t h, uint32_t val); +typedef void (* insert_string_cb) (deflate_state *const s, uint32_t str, uint32_t count); +typedef Pos (* quick_insert_string_cb)(deflate_state *const s, uint32_t str); + +struct internal_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + unsigned char *pending_buf; /* output still pending */ + unsigned char *pending_out; /* next pending byte to output to the stream */ + uint32_t pending_buf_size; /* size of pending_buf */ + uint32_t pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + uint32_t gzindex; /* where in extra, name, or comment */ + PREFIX(gz_headerp) gzhead; /* gzip header information to write */ + int status; /* as the name implies */ + int last_flush; /* value of flush param for previous deflate call */ + int reproducible; /* Whether reproducible compression results are required. */ + + int block_open; + /* Whether or not a block is currently open for the QUICK deflation scheme. + * This is set to 1 if there is an active block, or 0 if the block was just closed. + */ + + /* used by deflate.c: */ + + unsigned int w_size; /* LZ77 window size (32K by default) */ + unsigned int w_bits; /* log2(w_size) (8..16) */ + unsigned int w_mask; /* w_size - 1 */ + unsigned int lookahead; /* number of valid bytes ahead in window */ + + unsigned int high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + + unsigned int window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + unsigned char *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-STD_MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + Pos *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Pos *head; /* Heads of the hash chains or 0. */ + + uint32_t ins_h; /* hash index of string to be inserted */ + + int block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + unsigned int match_length; /* length of best match */ + Pos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + unsigned int strstart; /* start of string to insert */ + unsigned int match_start; /* start of matching string */ + + unsigned int prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + unsigned int max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this length. + * A higher limit improves compression ratio but degrades the speed. + */ + + unsigned int max_lazy_match; + /* Attempt to find a better match only when the current match is strictly smaller + * than this value. This mechanism is used only for compression levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + update_hash_cb update_hash; + insert_string_cb insert_string; + quick_insert_string_cb quick_insert_string; + /* Hash function callbacks that can be configured depending on the deflate + * algorithm being used */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + unsigned int good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + unsigned char depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + unsigned int lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + unsigned char *sym_buf; /* buffer for distances and literals/lengths */ + unsigned int sym_next; /* running index in sym_buf */ + unsigned int sym_end; /* symbol table full when sym_next reaches this */ + + unsigned long opt_len; /* bit length of current block with optimal trees */ + unsigned long static_len; /* bit length of current block with static trees */ + unsigned int matches; /* number of string matches in current block */ + unsigned int insert; /* bytes at end of window left to insert */ + + /* compressed_len and bits_sent are only used if ZLIB_DEBUG is defined */ + unsigned long compressed_len; /* total bit length of compressed file mod 2^32 */ + unsigned long bits_sent; /* bit length of compressed data sent mod 2^32 */ + + /* Reserved for future use and alignment purposes */ + char *reserved_p; + + uint64_t bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least significant bits). */ + + int32_t bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit are always zero. */ + + /* Reserved for future use and alignment purposes */ + int32_t reserved[11]; +} ALIGNED_(8); + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) { \ + s->pending_buf[s->pending++] = (unsigned char)(c); \ +} + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == BIG_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a short MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short_msb(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == LITTLE_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a 32-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == BIG_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 32-bit unsigned int MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32_msb(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == LITTLE_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 64-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint64(deflate_state *s, uint64_t lld) { +#if BYTE_ORDER == BIG_ENDIAN + lld = ZSWAP64(lld); +#endif + memcpy(&s->pending_buf[s->pending], &lld, sizeof(lld)); + s->pending += 8; +} + +#define MIN_LOOKAHEAD (STD_MAX_MATCH + STD_MIN_MATCH + 1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the STD_MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size - MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT STD_MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s); +void Z_INTERNAL slide_hash_c(deflate_state *s); + + /* in trees.c */ +void Z_INTERNAL zng_tr_init(deflate_state *s); +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s); +void Z_INTERNAL zng_tr_align(deflate_state *s); +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +uint16_t Z_INTERNAL PREFIX(bi_reverse)(unsigned code, int len); +void Z_INTERNAL PREFIX(flush_pending)(PREFIX3(streamp) strm); +#define d_code(dist) ((dist) < 256 ? zng_dist_code[dist] : zng_dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. zng_dist_code[256] and zng_dist_code[257] are never + * used. + */ + +/* Bit buffer and compress bits calculation debugging */ +#ifdef ZLIB_DEBUG +# define cmpr_bits_add(s, len) s->compressed_len += (len) +# define cmpr_bits_align(s) s->compressed_len = (s->compressed_len + 7) & ~7L +# define sent_bits_add(s, bits) s->bits_sent += (bits) +# define sent_bits_align(s) s->bits_sent = (s->bits_sent + 7) & ~7L +#else +# define cmpr_bits_add(s, len) Z_UNUSED(len) +# define cmpr_bits_align(s) +# define sent_bits_add(s, bits) Z_UNUSED(bits) +# define sent_bits_align(s) +#endif + +#endif /* DEFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_fast.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_fast.c new file mode 100644 index 000000000..3184aa718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_fast.c @@ -0,0 +1,102 @@ +/* deflate_fast.c -- compress data using the fast strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +Z_INTERNAL block_state deflate_fast(deflate_state *s, int flush) { + Pos hash_head; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match length < WANT_MIN_MATCH + */ + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = functable.longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + } + + if (match_len >= WANT_MIN_MATCH) { + check_match(s, s->strstart, s->match_start, match_len); + + bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_len <= s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match_len--; /* string at strstart already in table */ + s->strstart++; + + functable.insert_string(s, s->strstart, match_len); + s->strstart += match_len; + } else { + s->strstart += match_len; + functable.quick_insert_string(s, s->strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_huff.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_huff.c new file mode 100644 index 000000000..b197e24d7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_huff.c @@ -0,0 +1,45 @@ +/* deflate_huff.c -- compress data using huffman encoding only strategy + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +Z_INTERNAL block_state deflate_huff(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + PREFIX(fill_window)(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_medium.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_medium.c new file mode 100644 index 000000000..47796e322 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_medium.c @@ -0,0 +1,293 @@ +/* deflate_medium.c -- The deflate_medium deflate strategy + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Arjan van de Ven + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef NO_MEDIUM_STRATEGY +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +struct match { + uint16_t match_start; + uint16_t match_length; + uint16_t strstart; + uint16_t orgstart; +}; + +static int emit_match(deflate_state *s, struct match match) { + int bflush = 0; + + /* matches that are not long enough we need to emit as literals */ + if (match.match_length < WANT_MIN_MATCH) { + while (match.match_length) { + bflush += zng_tr_tally_lit(s, s->window[match.strstart]); + s->lookahead--; + match.strstart++; + match.match_length--; + } + return bflush; + } + + check_match(s, match.strstart, match.match_start, match.match_length); + + bflush += zng_tr_tally_dist(s, match.strstart - match.match_start, match.match_length - STD_MIN_MATCH); + + s->lookahead -= match.match_length; + return bflush; +} + +static void insert_match(deflate_state *s, struct match match) { + if (UNLIKELY(s->lookahead <= (unsigned int)(match.match_length + WANT_MIN_MATCH))) + return; + + /* matches that are not long enough we need to emit as literals */ + if (LIKELY(match.match_length < WANT_MIN_MATCH)) { + match.strstart++; + match.match_length--; + if (UNLIKELY(match.match_length > 0)) { + if (match.strstart >= match.orgstart) { + if (match.strstart + match.match_length - 1 >= match.orgstart) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + match.strstart += match.match_length; + match.match_length = 0; + } + } + return; + } + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match.match_length <= 16 * s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match.match_length--; /* string at strstart already in table */ + match.strstart++; + + if (LIKELY(match.strstart >= match.orgstart)) { + if (LIKELY(match.strstart + match.match_length - 1 >= match.orgstart)) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + } else if (match.orgstart < match.strstart + match.match_length) { + functable.insert_string(s, match.orgstart, match.strstart + match.match_length - match.orgstart); + } + match.strstart += match.match_length; + match.match_length = 0; + } else { + match.strstart += match.match_length; + match.match_length = 0; + + if (match.strstart >= (STD_MIN_MATCH - 2)) + functable.quick_insert_string(s, match.strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < WANT_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } +} + +static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { + Pos limit; + unsigned char *match, *orig; + int changed = 0; + struct match c, n; + /* step zero: sanity checks */ + + if (current->match_length <= 1) + return; + + if (UNLIKELY(current->match_length > 1 + next->match_start)) + return; + + if (UNLIKELY(current->match_length > 1 + next->strstart)) + return; + + match = s->window - current->match_length + 1 + next->match_start; + orig = s->window - current->match_length + 1 + next->strstart; + + /* quick exit check.. if this fails then don't bother with anything else */ + if (LIKELY(*match != *orig)) + return; + + c = *current; + n = *next; + + /* step one: try to move the "next" match to the left as much as possible */ + limit = next->strstart > MAX_DIST(s) ? next->strstart - (Pos)MAX_DIST(s) : 0; + + match = s->window + n.match_start - 1; + orig = s->window + n.strstart - 1; + + while (*match == *orig) { + if (UNLIKELY(c.match_length < 1)) + break; + if (UNLIKELY(n.strstart <= limit)) + break; + if (UNLIKELY(n.match_length >= 256)) + break; + if (UNLIKELY(n.match_start <= 1)) + break; + + n.strstart--; + n.match_start--; + n.match_length++; + c.match_length--; + match--; + orig--; + changed++; + } + + if (!changed) + return; + + if (c.match_length <= 1 && n.match_length != 2) { + n.orgstart++; + *current = c; + *next = n; + } else { + return; + } +} + +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { + /* Align the first struct to start on a new cacheline, this allows us to fit both structs in one cacheline */ + ALIGNED_(16) struct match current_match; + struct match next_match; + + /* For levels below 5, don't check the next position for a better match */ + int early_exit = s->level < 5; + + memset(¤t_match, 0, sizeof(struct match)); + memset(&next_match, 0, sizeof(struct match)); + + for (;;) { + Pos hash_head = 0; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next current_match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + next_match.match_length = 0; + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + + /* If we already have a future match from a previous round, just use that */ + if (!early_exit && next_match.match_length > 0) { + current_match = next_match; + next_match.match_length = 0; + } else { + hash_head = 0; + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + } + + current_match.strstart = (uint16_t)s->strstart; + current_match.orgstart = current_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + current_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + current_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(current_match.match_length < WANT_MIN_MATCH)) + current_match.match_length = 1; + if (UNLIKELY(current_match.match_start >= current_match.strstart)) { + /* this can happen due to some restarts */ + current_match.match_length = 1; + } + } else { + /* Set up the match to be a 1 byte literal */ + current_match.match_start = 0; + current_match.match_length = 1; + } + } + + insert_match(s, current_match); + + /* now, look ahead one */ + if (LIKELY(!early_exit && s->lookahead > MIN_LOOKAHEAD && (uint32_t)(current_match.strstart + current_match.match_length) < (s->window_size - MIN_LOOKAHEAD))) { + s->strstart = current_match.strstart + current_match.match_length; + hash_head = functable.quick_insert_string(s, s->strstart); + + next_match.strstart = (uint16_t)s->strstart; + next_match.orgstart = next_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + next_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + next_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(next_match.match_start >= next_match.strstart)) { + /* this can happen due to some restarts */ + next_match.match_length = 1; + } + if (next_match.match_length < WANT_MIN_MATCH) + next_match.match_length = 1; + else + fizzle_matches(s, ¤t_match, &next_match); + } else { + /* Set up the match to be a 1 byte literal */ + next_match.match_start = 0; + next_match.match_length = 1; + } + + s->strstart = current_match.strstart; + } else { + next_match.match_length = 0; + } + + /* now emit the current match */ + bflush = emit_match(s, current_match); + + /* move the "cursor" forward */ + s->strstart += current_match.match_length; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + + return block_done; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_p.h new file mode 100644 index 000000000..dd2021a0f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_p.h @@ -0,0 +1,116 @@ +/* deflate_p.h -- Private inline functions and macros shared with more than + * one deflate method + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef DEFLATE_P_H +#define DEFLATE_P_H + +/* Forward declare common non-inlined functions declared in deflate.c */ + +#ifdef ZLIB_DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +static inline void check_match(deflate_state *s, Pos start, Pos match, int length) { + /* check that the match length is valid*/ + if (length < STD_MIN_MATCH || length > STD_MAX_MATCH) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match length"); + } + /* check that the match isn't at the same position as the start string */ + if (match == start) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match position"); + } + /* check that the match is indeed a match */ + if (memcmp(s->window + match, s->window + start, length) != 0) { + int32_t i = 0; + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + do { + fprintf(stderr, " %03d: match [%02x] start [%02x]\n", i++, + s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr, "\\[%u,%d]", start-match, length); + do { + putc(s->window[start++], stderr); + } while (--length != 0); + } +} +#else +#define check_match(s, start, match, length) +#endif + +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm); +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + +extern const unsigned char Z_INTERNAL zng_length_code[]; +extern const unsigned char Z_INTERNAL zng_dist_code[]; + +static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { + /* c is the unmatched char */ + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = c; + s->dyn_ltree[c].Freq++; + Tracevv((stderr, "%c", c)); + Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); + return (s->sym_next == s->sym_end); +} + +static inline int zng_tr_tally_dist(deflate_state *s, uint32_t dist, uint32_t len) { + /* dist: distance of matched string */ + /* len: match length-STD_MIN_MATCH */ + s->sym_buf[s->sym_next++] = (uint8_t)(dist); + s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); + s->sym_buf[s->sym_next++] = (uint8_t)len; + s->matches++; + dist--; + Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, + "zng_tr_tally: bad match"); + + s->dyn_ltree[zng_length_code[len]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + return (s->sym_next == s->sym_end); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + zng_tr_flush_block(s, (s->block_start >= 0 ? \ + (char *)&s->window[(unsigned)s->block_start] : \ + NULL), \ + (uint32_t)((int)s->strstart - s->block_start), \ + (last)); \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Compression function. Returns the block state after the call. */ +typedef block_state (*compress_func) (deflate_state *s, int flush); +/* Match function. Returns the longest match. */ +typedef uint32_t (*match_func) (deflate_state *const s, Pos cur_match); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_quick.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_quick.c new file mode 100644 index 000000000..d616677c5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_quick.c @@ -0,0 +1,127 @@ +/* + * The deflate_quick deflate strategy, designed to be used when cycles are + * at a premium. + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "trees_emit.h" + +extern const ct_data static_ltree[L_CODES+2]; +extern const ct_data static_dtree[D_CODES]; + +#define QUICK_START_BLOCK(s, last) { \ + zng_tr_emit_tree(s, STATIC_TREES, last); \ + s->block_open = 1 + (int)last; \ + s->block_start = (int)s->strstart; \ +} + +#define QUICK_END_BLOCK(s, last) { \ + if (s->block_open) { \ + zng_tr_emit_end_block(s, static_ltree, last); \ + s->block_open = 0; \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ + if (s->strm->avail_out == 0) \ + return (last) ? finish_started : need_more; \ + } \ +} + +Z_INTERNAL block_state deflate_quick(deflate_state *s, int flush) { + Pos hash_head; + int64_t dist; + unsigned match_len, last; + + + last = (flush == Z_FINISH) ? 1 : 0; + if (UNLIKELY(last && s->block_open != 2)) { + /* Emit end of previous block */ + QUICK_END_BLOCK(s, 0); + /* Emit start of last block */ + QUICK_START_BLOCK(s, last); + } else if (UNLIKELY(s->block_open == 0 && s->lookahead > 0)) { + /* Start new block only when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + + for (;;) { + if (UNLIKELY(s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size)) { + PREFIX(flush_pending)(s->strm); + if (s->strm->avail_out == 0) { + return (last && s->strm->avail_in == 0 && s->bi_valid == 0 && s->block_open == 0) ? finish_started : need_more; + } + } + + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD)) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; + + if (UNLIKELY(s->block_open == 0)) { + /* Start new block when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + } + + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0) { + const uint8_t *str_start = s->window + s->strstart; + const uint8_t *match_start = s->window + hash_head; + + if (zng_memcmp_2(str_start, match_start) == 0) { + match_len = functable.compare256(str_start+2, match_start+2) + 2; + + if (match_len >= WANT_MIN_MATCH) { + if (UNLIKELY(match_len > s->lookahead)) + match_len = s->lookahead; + + check_match(s, s->strstart, hash_head, match_len); + + zng_tr_emit_dist(s, static_ltree, static_dtree, match_len - STD_MIN_MATCH, (uint32_t)dist); + s->lookahead -= match_len; + s->strstart += match_len; + continue; + } + } + } + } + + zng_tr_emit_lit(s, static_ltree, s->window[s->strstart]); + s->strstart++; + s->lookahead--; + } + + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(last)) { + QUICK_END_BLOCK(s, 1); + return finish_done; + } + + QUICK_END_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_rle.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_rle.c new file mode 100644 index 000000000..77df71f58 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_rle.c @@ -0,0 +1,80 @@ +/* deflate_rle.c -- compress data using RLE strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +Z_INTERNAL block_state deflate_rle(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + unsigned int prev; /* byte at distance one to match */ + unsigned char *scan, *strend; /* scan goes up to strend for length of run */ + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= STD_MAX_MATCH) { + PREFIX(fill_window)(s); + if (s->lookahead <= STD_MAX_MATCH && flush == Z_NO_FLUSH) + return need_more; + if (s->lookahead == 0) + break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + if (s->lookahead >= STD_MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) { + strend = s->window + s->strstart + STD_MAX_MATCH; + do { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + match_len = STD_MAX_MATCH - (unsigned int)(strend - scan); + match_len = MIN(match_len, s->lookahead); + } + Assert(scan <= s->window + s->window_size - 1, "wild scan"); + } + + /* Emit match if have run of STD_MIN_MATCH or longer, else emit literal */ + if (match_len >= STD_MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, match_len); + + bflush = zng_tr_tally_dist(s, 1, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + s->strstart += match_len; + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_slow.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_slow.c new file mode 100644 index 000000000..9f1c91346 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_slow.c @@ -0,0 +1,143 @@ +/* deflate_slow.c -- compress data using the slow strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Same as deflate_medium, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { + Pos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len; + match_func *longest_match; + + if (s->max_chain_length <= 1024) + longest_match = &functable.longest_match; + else + longest_match = &functable.longest_match_slow; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0; + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = s->quick_insert_string(s, s->strstart); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_match = (Pos)s->match_start; + match_len = STD_MIN_MATCH - 1; + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0 && s->prev_length < s->max_lazy_match && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = (*longest_match)(s, hash_head); + /* longest_match() sets match_start */ + + if (match_len <= 5 && (s->strategy == Z_FILTERED)) { + /* If prev_match is also WANT_MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_len = STD_MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= STD_MIN_MATCH && match_len <= s->prev_length) { + unsigned int max_insert = s->strstart + s->lookahead - STD_MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - STD_MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->prev_length -= 1; + s->lookahead -= s->prev_length; + + unsigned int mov_fwd = s->prev_length - 1; + if (max_insert > s->strstart) { + unsigned int insert_cnt = mov_fwd; + if (UNLIKELY(insert_cnt > max_insert - s->strstart)) + insert_cnt = max_insert - s->strstart; + s->insert_string(s, s->strstart + 1, insert_cnt); + } + s->prev_length = 0; + s->match_available = 0; + s->strstart += mov_fwd + 1; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]); + if (UNLIKELY(bflush)) + FLUSH_BLOCK_ONLY(s, 0); + s->prev_length = match_len; + s->strstart++; + s->lookahead--; + if (UNLIKELY(s->strm->avail_out == 0)) + return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->prev_length = match_len; + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert(flush != Z_NO_FLUSH, "no flush?"); + if (UNLIKELY(s->match_available)) { + (void) zng_tr_tally_lit(s, s->window[s->strstart-1]); + s->match_available = 0; + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/deflate_stored.c b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_stored.c new file mode 100644 index 000000000..6160896b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/deflate_stored.c @@ -0,0 +1,186 @@ +/* deflate_stored.c -- store data without compression using deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = (int)s->strstart - s->block_start; /* bytes left in window */ + if (len > (unsigned long)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + len = MIN(len, have); /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + zng_tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending -= 4; + put_short(s, (uint16_t)len); + put_short(s, (uint16_t)~len); + + /* Write the stored block header bytes. */ + PREFIX(flush_pending)(s->strm); + + /* Update debugging counts for the data about to be copied. */ + cmpr_bits_add(s, len << 3); + sent_bits_add(s, len << 3); + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + left = MIN(left, len); + memcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += (int)left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + PREFIX(read_buf)(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + memcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + s->insert = MIN(s->insert, s->strstart); + } + memcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = (int)s->strstart; + } + s->high_water = MAX(s->high_water, s->strstart); + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && s->strm->avail_in == 0 && (int)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (int)s->w_size) { + /* Slide the window down. */ + s->block_start -= (int)s->w_size; + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + s->insert = MIN(s->insert, s->strstart); + } + + have = MIN(have, s->strm->avail_in); + if (have) { + PREFIX(read_buf)(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + s->high_water = MAX(s->high_water, s->strstart); + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = (int)s->strstart - s->block_start; + if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0; + zng_tr_stored_block(s, (char *)s->window + s->block_start, len, last); + s->block_start += (int)len; + PREFIX(flush_pending)(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/doc/algorithm.txt b/internal-complibs/zlib-ng-2.1.0-beta1/doc/algorithm.txt new file mode 100644 index 000000000..acd099c9a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +https://tools.ietf.org/html/rfc1951 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/doc/crc-doc.1.0.pdf b/internal-complibs/zlib-ng-2.1.0-beta1/doc/crc-doc.1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d6942ecc09a3f8b2d7e4b6fbecc5955121e8e7cf GIT binary patch literal 776142 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

ha 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�rRb`0y|*v1_Y0K2x& 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 z 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%0A!*@!_1l*%gn{T*uEUOk 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

TW z_IDONo{|>HAW1G>TyRtpbmwk{?E;Qe^keeoFsDM3S=2db6)SXNcKE5%&&Ar#_N zpb@o8hS`1wgDDbLa&s+bs8dLKx3^4*zmN|i^7+?GCYx*0-1L2GVTM3%-hPWrrhz0e zbXNHB3HfPmGwCS)c;aGu`*;sb-s8nk=U{GPS59ihrvy=D!4Vx`q}533<6z$ck`Pyq z#Wp|O#O4)elSw*QD!!Er{iJ0~8m2>w=uzx@uM&gU0r$C!=YYmjU1aUBHf`trIflpm zFq{>9Y%Ab4N$mgk2oo{wij86SPzFIw|MoSMh>+=?vK%06Ri5?N6y32 zPWFhl#BhsY+gB&zX;_uy28Xzn@#4NH&UCg_=suUja2QPKb-V!m%U6KxcfYDXI(>KVeZLk1dpU8 zJ(yC4l)g7U9lQo+6a{OuE#k*r-jT#E>0I?o6F>I7yPufUqKPKv}ds~3-?2-x{@=kJ>}nO93O zI3+2XM938mPr#0cVU!2=Wwm_oC}TP=y|_@ywlY%`>@9xa$lSI=tkviJnbecM0g6D; z#gnR7xopbk>jjl(OpGP8cT&dDJ^}*|cYn&W;+mV3&0>yf)w#>nwHu1yokd8ym zQAEeQj_R{r_lrFHT8M}S83BAw2~OKeB5i}Q1uX)2R?d&}r0rzF4H>KEf;v|b}({Pj53@@LXZ!rbM&_B91^_?a$7^_jgH z_D&VwOkJ-?ckMq0-)0KKW|}6YyN3ro2heX%gbj1Kpnk|b734y1tAZb=i8QY5bMHOC zbUYV^l|Rp`f6{L!GWTHZr zoJeOTZ>=xYHk|0I*rr{Y?@X3*1y^kuJ3YGuir-S?3uMz24JJ&d@LXC^AIqx2430Mw zxhP8Ewks}5ddx7a%H&Pkvbe{q+$Hm?zRF9aZnQP@uchGsl#Cc}$!-uw4xA^8 zJTo>TdPw1Sw;2$~;fGv{;q(+?rngoV%qxM9sMp!{!D53t zHYX@;Z65KdeOE|7NY41K;ryCh*ITJZc-|E5k=47tbg`vkV>v}>cYd6|SMWCm>(jj> z(Y-IP3MMF`@7?wsDi;HW<_vO~T(l=k={JY>LsPax4pbFHZ{$NzksGQkw&_C{BRM

?-Y#xg4rj7}S3taUTj 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

{LABC35aZ+t^w!fb%kfniC0^^)fHUEz8(f& zZkI@Hv@qO!E{c5vJ;Q~ngmt0R@49m%bEOlLE`q{fxT<8K?M4>EV>cC%A7G`7 zFZ*39(yJLMARB%9jJR1t@p#b&N5`|dc6}mFt(Kx)61iaZ;qcHL=8tU48 zuWx01eZxu1-S9oR^A+2Y&3;t@bX>t&WI6AWf0R=3K!WZyWn0Q3_=x%?VSHUcY-n&b zY1aZ;D~ElWqF=n!@M(+~5lAa!}8B^X^8@ zC>op`4BMUK4O4>YQ^^!!OjK8oH;ZJku3DK0GM=jv=n^+n3S&^pLNxq= z9vje?14>+08ESB1CPo{lPj0@yo5EQr!N_G3#aB=aGtt@@c=wa!PzP!(?~4Ikxq*tM zvz!K8-06hf=uSmk!aYj?=lTi??MbSfgiBzhVutgFuKg0INU!_E5xVh}Lq|uxcZk9k zz*yj1BN1D!TVYIOKrw6u>|N4Y(BEz5A?o-GP8i}t0IEnZ1KJ}QZfg_qFUt5|L3+H~ z;7Iecbi8R^prcoK^q!)){lBJ=RQRiWB_kHlhh%ZE=WH@0bdcnSTNIV=MQKbv)vo0z zLznR~eQ<0fm#8SdZ`L%GDF*$q-(hP2&Op}~tNsXhKhF&uz%&OZ>3WSFe9+?Pz@IHe zmm4krr{TroMswCRICes2;Q8)tzS`K)3dy z^7j)0Job^R=jTTE@BK*7%S8^MKY0egCW&rwN?=KxpN`xdO7_S6&35mnHP;>Hz}>qx z*E&!cLyjgN@7DuGGvGh*$0;6q-r(4^+K_`qJss|ABkki>if%*}?zbV;F&L_cDKGt` zWsI1+EctsRN|GdSK_3dE`BL{wqR~{1w#D{WM7gxO0$=&wtyq~|T7qV}q6&HFLC3v! z4uc3(om0x!vgM?5kgEsrj?ddbg+M^3__DvX-%H=ZQQ7b|&*bU)Jjv_Nre+Apg^#c31 zdJqdpx%&x~g0%@v1fYD_ap8r6X_diVbe%PxQu@tnx`-J3LLPdj+gJ1s6532aJV%o~ z4vy6IYD6rnn$O89ndEGAN%j5R-*GNux8&&Y6X%>}w4Puc47tk+S*&qlfv;n|;4)>lJO1@;%bYvH5){K-DdD?SrAMNg* z8Am(5FM;oll!s?Bd1O;`7G9KzJ2agQ5pQTJU}VGk8Da%qw}=4V(1#siJk8Ccb?^x? zn;0&tIITYM#Gx1o zXUkO&QA$7Dq-l`E-zzsb%jBJsJ{85+AE5^D4O)9R8i8;c$>x1yLbp;u*_lr<IM&~)nK@z*i`fFeqrSZP<<567+PztO^rheLEz1<&vTTcP zyg(?(83oya{t8i$-LDpjtxavYU4gCs*z?6f#ze4dft66cAe)w^aN!g z%H4(87|H-?*n_f436y)& zmh(z?KIf)di#j4htA{*AemodBDSKYe60<8V*1#x@u3NA2vnw76jn3AkY>C-uo{JjV z-{Iba64_0#kP;fd)MfihT*D_S6T^wKI=&$0rJ`%5ay~r<+(gT~mnn`R*n;AF>=$IUzRi_tv}0pl8lzbI?(B#EF-RFEcalNBK>G!WRxiN+eUbRW$KXs#jW zKB%>w$9lp*rP9cq_e{@3Ch@&q=k-RDb(;B2#m%3X*pQIM?k+Z%)KrL#*JsP^;xX~@ z4t-v~VnE}if5*RPK2S^U=^`c+k~x&&&C~9N)yawZd)B5JK{E^bu&zR_vpSSsi(b>88JNDni>zTiC!JXDZu(kp=(3A z2n2ak$&H(g?P;+y(%eE?CK2L?g4L2sEkkHj0+Rw-(W>uo&y`>caf7+eSPAspfDGv* zV?FX#g&*@)tkJf4RE9CMfSe8~}1uj>@K@Xp49O5Q$(>9Fi2FNj2-`1tZpUb_yHmvn zMBxNGImDzK46U%;P?nUIfi5SX_VGw4Fq@DwR$Z2zx<=yUfD%YKKiC*h8tx~m5P#tE z>KBw$n63I*!EzF#^pkr5J+Frsz^Kxk5$f>%A~GPU^`xD~u4R0+4RsMeyhS^9*wp@B zqant5OQp-s_K31(@03AwE=dSK5%L+7zrjIVB;zjcQ||{3+xMRDG)Zldr(&NqPt&U! z?Vn}rDW$Z@#_gAdly~I2VB*w^(j&9V+nePlg9efEl?c~i6;c)$I{@&)Pj5sKA8 zLNB2^yR%~&AEp|AS@nVleoADku-O+awRJ}G-=|u~E2L(ZEoPYp1THp0t>^l`4pG-; z{x0Bx(n}-9vgk1y()C*$qWH+035clcr?1X!y2JO@`a4B|fh6ykvctMI1$Du_?tD8K zTU&BEXV9Pd?v+pan1hr6@Q1mi4U!OVS}>Oh9>+AN@ePE6^e|Hq3`|n zjsf_KwVo`hCq|+Gv%>%gh{UV|qlpkQ)z@*!`#1F5UBcA3%)qk_2w{H;_AG9EslP7n zwFd+G87e`B@2I2r>iQmrF001fYRKRzhQDh=j8O!arLNapSmr=G;E)}yPP{erE3JXC zSd^t4L5$W}wJxp|tk%R6yg5SC)|>bi#N^`kT2T~d;o0vZ{4bN>CCR@w(g#V}<#yr% z%SKlBR0_d&7l)bs6W|@QyhS_j(hCTM$7zmzTj&O5x5|77)?#uNsp8UX+Mqt`TwiH5 zBI)vr+IfCA(_keLDji*@0jzc;^T_Oj=i;~DAPX&5I~4N%sLQ%rmc^QnchE4KYwaT%xHFO zxdIoTEl@hexfgbH0x)t5Z*=+O=%u`KyVTKYoAY_JRjpkw{i0U87qpZ33W8(i!|D0k zY1lHn*V#r&5IpSHdRHasPwmV6fxumY;I6Jafr1r(`Wn}$W8iYNZLd1}-BVW1wtj*s z&pv5HyS%n-uSQk%{mhbpuHL6S%-uFAz@q0dWrz>R7wpU#8@kjMen2Px)?RS(@e%mt zBM771PD1(~lAy(lvwaj}A>H_ft$r(nrcIP!+Hy8Z853Y${6(6-RI2RWjC3)-?Vt4o ziCVb$s(!4zrEOM1|DaXxa9vd zK}i^3n3!+HLbehc*EviSIymlk2yGHVGc~?uGa*8`HK1`J+MhU zAQ0H_2p=h*agFu_jSfR0R!t}fisg$fJ}EH)vCe|u8h`@AEfJTp-zfCs10+>kSDxGa z{i8k(MGgUlg$9!y0OH(^$f+w4&DzD&gyUanxovr;BN76Wf1hKd6`Hqm$H;baAdoW3~gMJYkfxN4Ujr`cKA9WM=PqVC!H{ z_;fE>U%fx5f%NkX_pvQLki2_|@g`gK&6Nc;JO460+sui&>xa)Mbvz~rbM!rf-(Kv0 z@X6>abxhm21_}Eb?52$`Ga5PDy25g}KsS@un z8h~vqXz!i$7uy|g19I5jzZ4 zWi)UGcvMyuD(HU?Rk^KzxMbN;5))aLA(Fa0OV=Q$-(hSu(QNhGPd?`$dyhd8Ro})E zrk6flII4=t*R4XN+311i>HX$L!(0?Rho<_uaGl#t))mh3l)WRLW z@o{Bri9trl*Ql)$&UR5L9&7uwo2F9efRR6V?4uIpP*`hlty=<)W-pR6WvT*EZ&%)Y zo8Uq&A3ZjyLeAN(<>AySZ(If}fd#as(eLtMljATgc*-C3^3B$YNPH&G#zHm`JA$lV z-aCBFJ%P~am|u$bt8HM)>eDXnM$9WngPwS-f=8qhD~u@&Xe&9g)>$s%kpCfjFC*(| zjAZogX_Bn0$)8uSLFt=f*TC_MxqSX04#U)itPSM_5JH3ZX~2JK6xj?azdJEIc1LcH z08r5Ra%Xhh2QG{}L?SgWrqlwUZuv7u)A{c)3^EmIH3L=$>bf7q_bk64l5|x*sm+}uXj=^XEP z;OijUQ?sBPF@8Pam7p;Uno9kAYG%lHy!aNCbf!Lv?{K~$7rtuR###DJ1O2|R@xBtn zaT8hW@E>B22s(ZlfTG8evBIUuzV1Pj-3ueV z9*&@{t{DJt4hMXaX*M{w6X1drxbF{iO~>}uG6L)dH@7To{Aclz&KEGwt!o$Vi80@5 zN&E<~UAdAn(l+OVhwZc^rGf}dr1R4S>V`x{Vv1N4%OScB>=9r`MSR(~P%YkY3lGUBp&r_ z8)ZD36`)QW1}PwP^Za`?RJyN(QvWC0>R-F*f3vNAT&f={>i=L{{oDQ@(CQyqNdDiJ z{|2p?{?DM*kFWIq23q|PPygjvF)^|Jf9YA#{V$po-T$gtvHhb{{i|6q|D#zkG5<4& z|13<*KW@}dVPRy!W20xoWBkXF`q}=^`k(gyoARGH|HSxD`KJ#Swx8JlvQun$tUn$V z3*&#eV5~nj7%MaVk6HCon3;cADn>kJW>!2lCPq9~rk`WkSn*ise(L|M*?;!`6Nml> ztNJHNg{Irg8C{j>hJF#OZ=|3Aw= zpE%u*+eP<3!~bs^|BjJ~;eRq+KVI1XHPiL)wJ%RArRU%%XsT!bqp#7^{;Qxl{AgnT zTr2Xl|K0{74737z4o3gn7PS96_eLvXX8+$O|1fUC)&@3)X4WP@L9F?$9nAipZACX* zqkr#}|AkijfzST)M*rL9qGxAeXZVR|>1bsCj}7N&BxLjx(1`ZG_S66KB{2M4&km0E zMtWATP@`;$Zi0OG=g)jQR7A7w)^A2ZhQOM61nz^m!zWK^(v<2SmeBIulI}p&8z-cZ zX!1Hkue5}G1Tj}ujl~;m`hEZw^6x<9?49e|jpcPU2j;&(!~wFy%lew5T=gI+lD=0TUw$k79b|7C<>B3z)uGb5DID87a^s?X{QLMA2x(=Zr=< zejuo(zc^eLI5&=VJQY`LfP0@O0iuK{1L}M|%?TE2JLI}Rj+jJ)#+s7#^}R>U{7BZv z46j%w|FNT#=*%ZHz**S{x3j_^b+)><%`0<07EqI%Q5F+y{x*;PWp%K4iK~${NrKdf z2wtl_h3g$S*D=_6gY+1(LNn?4>={wbc%arPG96OAF`uyZP!qf`;>a%}&9+l?s&Z=k z-nP&C$a%zLO5M%6=%fKnY^D(45}unKIRg1zG0U3ohxpl9E@)tWOD7!JV|RQ;NhCyg z6F$4icZ|r8te1UMG*C+#-+vPALkYhY-OS2-J6Dn`HaX(wnj05=-gh+Ce8<^(@o;C3xo4uOJ5j50Db6@({P@H zTXHn7!QsPG5h96X#XTP`ySp__F8Ip8_(>mIddmi|Dev9S>Rpw3_7KIOHG|eNY zbvqC}{2?ivFjK*i9*V#ZCCAw(W-zEkW#*7L-t5`!60M>K-y%C$`T{MF`2`f3^0Bs? zERn{So1_56QHM?zPxYqPi>rubN*vCKcDaVUim@jjuK9Lxv8u|u>sRQ)U^ErN&=ZZ4 z*#K2YcWxcnif&#;f1yg32g`Ipf zEP@w%1=zPcFJgwj@{>_fcz;PjVdO-HHb;?ov&lC9dLDbz-i^0oh(=xUy0-C61nIOB zL7dXTE6s)_re5`7{(2YT6K%eEU}+}-j~V{n?Gee1S%L6!vOppu1oZAapKgWFoVSbW+n23Oqe|I7hFqGLyK1f$#7JyO?^kg9G89H5!g5CvMj#Zk z-zcw>=yr=3zD*k*Cc#bjW#U~AD#`#*;Ak}ph-q36rA1Q#8k#wZF*e(fo}z;@en3vz zNhla_Ot*ba1?Dp)BdExAn3yPPNy1;9uesSt2)rwZPjYCb@4hXkFhweP?g_lzJP`u@ zUnt-QjM+p~b0PSuko^-c^n^83fxl&GJPg8SqaPg;mSGq^w0<*u)}d`Z#JK68!$>IM zg^Yk}eAA41SS3119RJq;xU9hhmkJ$Dc>lg$J#8onvGQs)dQ0sq_iIg}d(qWUCji=L zZ=w|>2m9Q(G^#(K`{1r%AVt>w?fYm|(=&9^emS!9ng)!ST*n>q4a)_%hcT^ieI(t- z97MNa4<|MT)ol6q4lo&cF*^cyF?t52Ms|HR-$`HuS|+LytVmaMN@j9@r#C=(I;| zg4v)=q>}%gUdZ|GVSZl8hB8i2K{d2`z6|q>fw)H_j^Li!(B%M;4T|)}-CI$r`3_!6 zw|rE)FP;P8v0pv?+DkE;(Rgwp_5n=DEo?k7vS^_GVvl(W;@0KCy+6CfTjrQyt_Ipo$kw114NkA@Aya zRZit0j}1Ss_!XFEdDC!%|Fd&-6*uN;=Qvg0*DW|_yH7S+&(JDo=3YJ^7dz%qJ7IaV zT}TK;Y|&He%!^N^*ZgV1mq2mm3DiSArCC7xss$W`$IV$Bd36nTXjs9*9E@LXtlwe@ znrj|1k{TIKt|c*wm_$1g?$z#)og7 zV_FfpJKx1WA?qYb1PL#NlvI)&JQwC`a4u}ySCN}N+aN~e9YqofnU$s2qQngjAV2w%mvy3<45ds6OBrb4hy~WX1&WQt0>T zttgB0<3N5=z$}6;g>TM-sp) zP#o|lANw6;1X-8nae_HmqEqXKiS57}DCr~)0p@fdvq~uvDgy0YLqp4J zD^LYjyC<$eH#r1v|JW7beGmU-Psv$*R*NZ2NRjY$&-0Au6}k#FmBIcfXa`8MS)*dN zw_W~;;w{H!__}IoWJpQ#aJH5?Cbgz3irXo$Wx^=tsf=&(>le3i78&&W?yjFTU8GNf zqiXHAnDwNc*T{}juf!+G#;9m^lNAvql1H#=4mzCsXNft<$6!LST{Bk?aOjQzY5Wkc zV0IpUQ0`U1t+_~>y??<9R6!cJZQ@*G+fU%)c1(zcoOx%ojlr+VP)l$kf(e0oW88Ym z$=O(}i;^ zNC|pJtEB-leAC>*HAEDN9OM5JWtNf57e5jUhtai^@6LKMLpe4a4ztogXu#6wO?VqU4NA1ww7x`9A5p*MV-$lCj6m9`w-WwNqEZ< z{+sHmoQ$3$7TX&~<_ptLq?7jg-gzoSEqg?P-O+X}aWkrWzV>Ze(5r!GYQTuIy2$_? zJ9)Egf_$Pt=dTSiZzgD(j4%gC%}TvH+t@7r>frNdfQ)OAyQz5a(8LfbGAs)e z8a~6$(ad9KAfUnW!=(Kq8WC%|=P3hSHAJZJ%2&wQb7~r0@`B;0i>hD1hl*@%+EeiYk-B{H4`f#;r8VLP{lfgfW*Sz9W5LqkXamh zbB>#3o{E0WHS}tCa2$+{P^MWY>+7}#u9W(#F-E}kc?YwpG-1V4S2T*I z9bTtGBFI}^k_3BPgrz9{+ZhW8xGNEcL65fU&J6l8mL2_%rN)!GUTa9sc;3>&D~tP= zh`>>@&2h&gs@o<#nKq&`M&j(#WHIGk#<|fTK>G_!;Eu+9ON)IHVSiK|*DoVmT_5H| zN47J{-A|FO0yclI;+Nra9*LGuP@{$~)!bcsh`WtL_V)rtwHDSluXfT_6=1+WtZaep z!b;(d9gYWZKzkVwI209W2861(;f9u3QmPyBLm8mRB>=KMtVeAN!kW2dn)TK8Kk$my z3#>!Y(hlX7Cf&NLf{<`e{(iiXz%V*A_|V&<3qT3}hTnGiNlq(9MW-2y{h!YS)GpFl zhYfE00uTnZwUtwgzt5Yk6Gzw>WEonw`|X8xc=K1~!ff5ARn*97V{uSy?`@pKMPwoM z39wt;lH$BR#5%)b>gw7D+vd#fP43Imh9wM+(^*aGPZ*Bz$ML#E&K_-VzdS z{0?^?4%@BYQ<(-IqUWhB89kvNRRLzk`DN^>g|%;NjYv`0mW}VD_(8b4r0WyV{46(~^%e4h1 z?H$XY&J%Q9_K#+RT%yU3@Y0gqUr##r-Ua2UodssUM*{nZy(5K{`&6;`h9mHb&SgAT z|MyfK>9gHQe0O8!>kwhxe z4h3H!#yH&8I-+6n%4KS28LH!3BON7kPHw4mVK5T+ID!_z!7k2Y@DS5)_ zpY{05rOX!BUpjQ7-i=Gx$CNO*m=Zz`xlP(#qtjAoXIQ=p>y{Bf0D8tqI)eaH=7MzWOy6G(VQs*t>P)3ic$PYo zRiUQI!xNd}#6xw8c{1-=m!&ux4Sz*CoEr_Xxa&)qky&@Db_8eH4I7(Qi&R$eruObR z1xIc#yM~qjjmvT3M3ppbF9;Qi-eIyDj-|yhYLB<~BQ2ofY8A-?Bg#?lG4m8^X~wEA znT3H#GD%HN^W2SP`cy?Q_Zp=0eZk2^PUO~2$JwtvNrUoK3E8~lZ0h21DOdMo6ef*-5!v$qRXCOs*hdw0Iv~ z>XGcN)JYwuhLWu|{k<*?{o$7-l~1)mgI~Y#QvL2k`1?cG4Z|{3Uo$g*mw)vQipA9= z=}~O@sA1>8Zru#Ruv%tb ztCNA=t$;dQ3CXB&2rIa@Jx;aMlXT>auY$-MK#voEtoP!swMq72G(&eb6rAB4AcFQ2 z9G)InGbpG;;eRVn^sO3mG2CQ^gF_7?aJrOy=Iav?kEMTID}phx&dUb}53)^zW;3q4 zfAI7YNJss)c=Zoao^g@x!7Q?IwW2k znJQ?5lbRZjF`upy`SlgMJ2e_cf<^>xjSdTbVC-3?Fr+Us^CE`NA9P)mD4nqvJ0>dP z7fsAk<{=U?7%k01iX>(Q#7#XYaB8N-U-Os?YABJAr=a%{U!`00s;?)}TC|&$-MMbCz3tXu)Jbv!p6xDf z>#RDDL@Shul0L4e3|G}B0-c81C@Ouh4@XLNW{IoN-i5gG{E(q;lE)pJ?`9v-kG|9mFMgbIgxO}b3P9I&1jTj0lhTR^(FnraZ@?08&^ z*rv4&4LA6oXVMMfKy@BB@9sSc)isj;HFd-koHr8;|Hn~H$fe=4>F`cD_P9Dow?KoX zK~cf~Mw%g~jy0x17n+WR)(;2jwCQl=oj#*f1;qc+OFwZKgj>b{mAz80sV#>c>!RoC zk>wOFqX_WiYgbpT2p7D*zj|YX;fOZhlz}ufOlyU}x6V^!NCJAeb#ex?@R#N=Uz*>} z?{|(uaJ1#Z7Oi%Y(f9Z5ljvhxK208mk->R&ZHe3lfvKH7P@1<)LwH#Enkbj}CUN9Q zX<&N0>PAGzmG#sLso^Pk#U=tiKm{;@^qCuhe@ zWe#W6@UBSoj1jAEFOA?D!IZ+UAy}dwCn^9TEW(Q_aD*&w*V9~Dv!?n%SP%pfaoDwD zMPFO|-d`N>Mk~WtPP-k(+r|!gE*+fqK5TIcpa0sTRiOq&XoaP5z`WPpnHBk*pjOIw#!WO})>F%^n-Dkc7!0g?uF>T&yGrb?+eak4XOrI;YrvLg1 z$SoASZbP_UV|@=n(<0rAfp}cLV*vE%O3jlRa3?w~w_rmSVm9oJwU=Cj$hR(2wDet^ z2+Dz^6#oYvXy3&C;{>lEx`DBfy013yDx4G005%fV`6p>Q()wH%9Suf={xvD!zWY7Otu+w(;D(2&(1`INv89%oYT{!Xx6T=Onf_k&hOf zp*+#tCZcWD&}-yHhzl}@bgf=*UJoZFoDy@FF|ow`CYe3ODPI@oV`K7Dga>3$8Y5oL z@`@|re#WFP!`(gmC1`KO7n4N>@`5e0YvqGnwTK%XDQOlTWDnU^c#}#=(dfhapT$^k z8r0Q-{?p$GE#uKzl{Gf<*f*sqV$Yx^1yIG%pJx1+s61xutb9hh? zyUgR3*-zBuYMygotctQ3A=o=S6mA?$opto#dL7i&Mgs5*h=ci*t1Rb5S$W~{)J{9S zaQ57Knk@Q~t*hzNP^4P_mX?wJQDSH$Ak!^2L~`wO#M!PVYi#U00C!cZXtNfvE;|X5 z)Cz0;5(FVVX>0bGsc4ahW+rnna!OE}E8EhYGVg_orAvZt*GlzkZ|%VpsnuGN7)q^Y zh=4;#v47vKgOli#r)q^Cl*_HhH1XDp!Rx?qyynR+2aKLHAFTAf3y?tT`B%%K;xN!k|+zeZ3dpJ){tToqjl%Vje6@?pyLEt7l%B?5qoqLCT5+>kV?hHfB zOo|lZCY-+==0$JD;ca{)*e%38yG5`xPF@okH?mfH9IV2;9+nQY_bX?NEfHEyq&M_Y zy(IL$P7B__7=eFxC`m2)`=0>_pelIz%Ntv%KXj+0WD@I!dT`9ziQeF5*(Phd>fP@3 zr9mWemK0}XMVN?12emY^N_I-C#Ji)|x5a0>-V()5P1e5o6^9r<6mzcN|ugMl^^44DvuzWIy0UK^S3=0>?{_UB&(f8P5h z(%TkDbuM1F9*TyT53yk&!sC-n(nxYc-_DSxM7z4$-Je2%^@Evh(Uv7AADN^7W6qcm zU@Wf>afP@2qk=e`)93HXC#0`5I_Pc=JPGw#clpwGF-lKxr%C}XqZZmOLjO&bQ_O}=0V5jH0g5+ zUzYGt=WVNWgkHhcTJz-eFG_{Y*1K}H6w_^}d)i`;9%A>u!bM9N}F$($gkvG@Q zn5r3#mlua8nQcifDk^(e7%%j2FSl+JB4QG!xg3OttRf}o>yEY8DL4G9B)Z+a``|xu zca7eP4R(c3afaT(r_4DnBC~1=Bo^O$#CCd@ekghnc-V2itXT5$frz5R*9X#Y zu3jAUW5JT5oFSJ@_ff!wlS9%=Cj!qE3XnETc+Iq}O!q;xWK8KItpYfI^nUN2?RdC*vU4d$OFk80aJCw zqwH|;-nbN|v+L?kFGJ#zSpVIDHj4t(04FBm!{-yRDb?_P1NMO1cy%5m^RhXJF$NKM zOzI2bxtcZVeT(`sqSZ?&8k(yDHqmuwyaTPKO&CzAoYzWm2H&v}zY&8~LVf6i5bPgT zFPyU3zG4gqm1JD=nkXw*Fc1C7zQmIgY@1jx$G%>k#eW({)Qs>z%y-GfiZ}4jpK@(_ zDPt1x9{TlT4GKH+yb>thV-0I-jA`|me8oRCE`~Ql`5y=}1y1a`v$_PSB`M1$$Ma*W zEAALnMjDscI4@-uwLX_l00$^^+qVH0!eU<2BV1plKM7Dnir<;|BQ$fPPuw73hT!H=b$sxk{m~9W$~Ar%W}y5C1&&;*PKICk8e<29 z(XXtDgkP(oHz2GB4d$gJa-ZcGqvO5Oh&;u@|0qIj!)%AIY0CrBm@Lq+@hxpbSKp(R zJ^dt;v5{@L?|@2-#$7_DCDJLyCx$uKXlJ65_#|5$w}$03Vbqvf3cts3jNoI}Eh zdEH<0;^*NBoF0MLP2{8M*%YeBImj_jVNELDkm|sJ{Cles<)23(7es0q8if7%z7y+j z;hLX^HKwDY#1}Fb-B_#K|2iF5^3|E(4WYg%w$(03RX^s#d#~ISg85_n5KFTsq*#o( zb#WN@cZ?HRiQ7om+;O)J_yMo${Zc_ItMBf`=Rt(A-Brho@nr-kdF(BLTiP`LtVkG- z+Do`~9kZS-CUnyYhg$}><|tp44CJnA$U$$U5~JWUi#zl?(g>Qykh>3+?tfP?*g#FNkDaE zb)N;263(ayravCw`QX`Zdf;9f!lHVB=Zl*WT)Vl1vK1t|^D&6dj@<`(Z>qPt3Qd{Y^PER0Nj4$b)B2@WZn@su zc5wt-$s@(!?FTHBZsEO+T-!!4lC(uw*&n@v4O{a3h{IleX3XBTa3LHgS93!r-~bfl zkEw1y!4rGam~x#c0 zusApxw{keqvYnpc)J~*<9q7P+dK$c$Td1+&y{OA1SUIc5KU42xA_EPcVl^S{jlHj` zoaUx{QJmJyMCJr2Hp$GSO+Rbr$=bQabA9w*uOvC_H$hhNu`iQa%fqtfOb z>UEznWJc{-9`dhHOGVH}G z)+5Gj-J0+*_rNI9*5OP3T^_i@1~%m^B;{bmL{1}T7!0c}epcOP~3VfLb0) zs{4cxxO~hMFJsI)LGjv|pWxw6cQQ#sBOo%QS%TC@T;{U-%wxI$GlJsgJu*-!Dmkd@ zAw*&ufFeQ^Q_$QZs=q+hQSl%Qgv?%Bsj(_rl{b*RK*@SMcL!r-uWxFnd;L73*Ue_H zvIU0W+n23#Yc{8*;Y9dkM`ckqn7V05vJzn+Y|Op)M*Xi@?3T{(LB^=`9DDj#sdop`{PP|jxf|X^V+jU;AuEhCqh%oCl=^w$2_-PmD z9Ibj%^7tJdje5EuA3p@4GeAc18zgi&Ft1GpMxea#guh7E098G%>FQ5%kHAx(V@nR| zW>$aOi^0X7Ss%pcL*cA)=d@(zi?vQLhGs0vW0tWgN$LA8`=S{>Q_SsW!eQ2#Sm*bG zq5%fNLsK1I#_H>A!6;Nrv8|_%S`*1nDv2K&L7KPNg1&CHaa966cwE0BsV%I;?&!7# zHC*2!ptgBV3UJEtc~+MTCuy50%nvUQBOtd%$f>N6)tEH$a>BAOG)DdJg>H5$oxZ7f z4DmF)+>3bE++0gb++$A9!em7N%Me5x74b`+xcgSTn~5}H4D->a-%@kH45cl5?~64; zlt2xBXit%EM{=sZXBLJ}M|WDHKw04sG@uC^D*DBxi4<)uCVebvV0V|%9W&9y<-}%0 zMGP1qG3q+cdAZ2;>yv*B(AC36f?0he*-BP^J7=k06BpY{%SEYSw%stb_THpGPHi+q6>npKik9$<^OEc=; z=+bGn4vh$o`YlrpC*k^@cc>U#(D1_a(2-VdUcm;?+2xtPWdm+BPosu><0u?*fvpl~ z7;J=U3ja~Q9l#7g1hdN4;+g@9bU>M6kzIwFguXLL3B@X%5iIzF4=BUyvQtYoioE96Ik;U>l5Ka7 zrEjyX*ZDCS8^R@;Y4$pefJu35!d3)vok4-D9n}^MfqX`8ltdwrT?46$52W((Vdx3m zsE)4C!$?KOFW^OLQi%&M{KVNaY$%FhucrGs*XfK*0^s`P@nJ!&VTY4J(2k~tPn3_3 z5DFa`e-)ya(5dhy-XSH$>O521?C*>^LfskqY|_oS`-U-gROiz2mEGeW#AEqoG^>=` z1sU^rL3K5b0#q78QF0o)mlj8ke)a=3$A6LX+|ZO$hlw<=k=lX(wyU}XWm4z3-4CL= zQK8P2+&*Z^@TjXm%fclQr&@I(Qi3HTl+~l)FBsIf0A25Xfc2pnvgrn*O6yh z)m?eu{ITgdG-8I9;7fjWSRJIAA$Ffci}Nflib`zko+dw+kF$0|uN~aBjinM5#eKYk zfO#ghxPeOl`|D#iU&cu=3Y+?lw<;dEROy<9SL!IT!?wjx0J+n)O6y!-Fy5Hn=O@%V zBX0AkIvw)wajYPd17ykecNVA9$g>0eKP2Fa1T#4l#e+_l#gnDII(iir#$Y*v-N6e- z4ZIj;dI%Re5MGhr@_2VpmZ-Jsxqvhx<-en*i2~yO?k~mst$?x$ z76Y4n)Nu59>SYipc!_Z|PUXD!b={3A)R)G}#%PPGBe{ z40{4dXu(iqYJX^yRa~r3Ir!8>AzaQ#M9yZ7Wx+nfACaQGk8beDw1gm7TUIhwTnK;D znRaME*sfI+rKWlju-b;>I{7KBar%?T|4Eyo=9Bl*#~@r>6kz+`pn9c%Cp2dYZ8FF@ zcWW(09GOz&O0(?n4j6a`fr?p3bKf%{_?CjkUI9$aTrCzp_d~s1pEnW?TY(MHYE+)eZJqH*Fyst`jsN$WssDNj-~dW43gwk zsB^`nKZa4yQ}tIj$i-9;Yb9CW!=@W8%r%zzSnq>r6&V@hGZ%I|BXD<%X%*NKehe^I z=KC69w*v|YqMs;B749_wvKE6DFp5m)poh7w*nP;#*y$&P-mo|JpkG~79Zb}>$C&WJ z4+?|}%kM3BMj-pAz}lOZ;vp7p!q;vj>u?|n>t$#4!}SV+FXlxXS#D~}T99vWbmY;!wTxzO*m=`Sv?pef|11+6?cOO;TntUb+z|vywGrXHj{RaQnF%!q}=5Dyy(q(F~96XdJc4Io&?BJjInm96LtB5h<1uNW^>6%V*|Zxz_J zBiyPEWj%G{3p65B_v&r5zUDnR?XoKtHJ}L@%NbU3V{Mm3l=5Uy>DD)9Y5B-yu?-R4--H{ zKg78p~(q-{>|4GCsbWQX&KXfZNiN^b$h}ba-U=?+yY_N6Z~359v$5^1l1#qS|A7 z0wTMU4q{|Fpx~r<;3vzqe!nRt=?t?&d0t6v_q*v1(S`iGB}>ha8O47#Lvz0a z$STTA)4^G_QlkvzKX#ET#fPlJz_6 zbZ37!%GNd{)(+t_-pqLfu+(FgGrSA5d*M|3mbk5p*C$TWNOngs}{wNQasY*$e}Mtba)Hekva~{ zf`GvZu1~gog@YcKr7hjg?e}z2V;UkcDp~UA0uUhA{&ea!R?KQJkdr-QK^mXZZCTID zw8b-TV$`+ibGRiX`%;%dm{0?XbM}@C_PUZzVt*8MY%koBDas415psv;11R7Z$8-UW zJe3|Y$NS|Q)UE~hJBB=b`^IBGw<_dWGO22+y#UG4h&u-~Q711ZuVZ(IblrTChrq`llVg>{7P5zMOCSca;6ye` z%?t`9vG$Ez%c>dFlA2XP)es#fAI6;iA-XO*@?7yY>~B{4i4oUTa4g~(eas7M#^f3p z&=6f_Piei{THbhW9j=niZ=Zf?Bf9Vbms%o?pz}9v8HuUVVNj`U2f$Xax@Z&UTi!w`uDtNS6xxmUW<7A@A1t2z^x$3gok$uQz_=IY$EaBV;Gx#Ll`BUqvNx^=%7BEKgV?rxOW6Q_* zNE1r6&@#_^bML)gRp^q%t&cdB?Q?4D##CRiN7sx^tf}-?ba~AKB@2-bJv*)lSaAI* zb!GxB7AZR-K&7cSWIC4w|7Rm5nq#jIKX`p#XL8rM>Z_ZLf{1e0$f;ha@Z%9QK!$s{ z-vlH_Xr`D7TP;y^?tkdZ{p4T(|B3dGxiMQ(w7br??X17V6@)~2y`N3H@AC!1Y;lUn z$8BB|O1^Mo`&$`f4k>x#WFfzoqjOB8|Hk1&CY_e(8JA-v5~3%J9SKON71IYi6oeq! z$sIk;o+;8?;FaHr1zJipO`06VnWy5G0g^Y0!1c}1^F`#P~u zLNEyZcMTFW;?Yy`-4-yO!KB%-20l|n?B*k1--!+-} z3T^khLMc^L_jU&k?^)n_|_g#Ut%|B@@Eg& zoQsS0`*!Y29raIP6En;XRD#kqWV?*-CzL-j^}P&Jk&nHCo?eT<{Jw+AdP5>1zoK<@ zT)pkX9d<7TKn-X37ja6YxbRTOohI~79=cpNSKLR}+K)lSgmD8-1E>UqF!V1Z1W)xt z&+9GPMUM^!suga;5cEHh!uKkKi4IEF>isWW$#8J>F3jrL1)HmPkIy%#4WMa7=RanO zf*>ye?N&QYvezcC?I>GRZ`y`Aj|9Oy-fY*$xOvMad_S-MZ!R#Bu90ZI^KN`Oz5OcYX92!q$tuA;CLVF5#{Mwd!ERhx^IYZIcky$NDR$} zaNLWM81`>YgY}sngv(F`_at(_C765@b5>GZ4YZpmi8Ll zPmyf+^@gXFe%QsA+@>VeB;*MBxlFz093-*&!B=gn2z)o%GD@&SpsH1^WPoMY93r== z=h8i87>H3Ed>$^GnqWG`*h(d#$hu(dVg+#M0TMMXq2SFF^@(Xcp4EslqN|ssXpXTM z??Wn(@;X~Lq-|4cMml?JJeyHU%xQ~LvEux~BJeknje&p!**fhgngMzDPJeI^tZxlO zxM$!Wt9x`s+=kfmzhVNCxi4T22Fe2o3UGQuX?`fBb2E(D17dDLqQjQxfv4ip(29->5e)m&P{y>;>5(jabfbav`le_x z9VAYSz%R1#$Ff5pHQ_;lBcG9RU;$W7AF)GXg`1?52J;YKiBjK?w0_U%a5LT1wvq&e z>TjxP77`0*?NonTa-dsW}3jOwr3y^LLV4-szI>)S4<^$57mo?Q3<`@OD1~i zmTHU6wQ}`GK=R{9VI~ti+2FU;Rx_}T$i7s}W37J*rgYeR+dTmT5NJ?HIdoSFRA}S* z*sj^|j*)49xre~d#UJ^G6fK|57sd;7cB;cT(!d_vg73!@1(5+ezqc770f^ET+$GQY-Rxm*28BfLbRn6pveG$BYw)17U4s+vwn>FU-`{E8$b((Ad4NRf2DS*k5(g3(PhWhF$ZL6+6f z=JPnP5?X~M$gdkIO4YBnw|{nGsWzMxQ#4xDCW3aX}7Y*GKvwv>>uj}+4z z!)6B4kA)Y1gsR1v+Z-mQA^u4yT4@QgF_znes&FecC}#y z)jG^ROXgf?l-R98NEBMNgObfpn7zuB)XbxQ`wR`%xBXUqx`WmLebQU^-yvvC-Nfph zs2vWTG`1t8iFdYVN*=Devp%~veBOkNI>L$}LHvT_LjPRbmEdn>B+Z2_S;ND?S>N?BmHf=bkEV3SA?|>EP}i;`=~BX9wV2}0QObG{ zXBR#;zlZFH$<=?<#->r9IS{88CCdl7`X)Rv?2mBR>Zq&{Y@`ZGD~JA-T!BA2Q?BO3 zX41_nJr*ayh&;*2f$a|!YS#l;i|5k(kY{W=FkHo7jG=`{`_l$3*7DA(6XEmOarOyf zbDC8(#*3ERG|H(Hx1lvh!+Ue6QSZ9RQb>Yl48N9BRgc$*D4&w(fCJs+ST%QmPa)mA zYlV=M3T}d9tl8PXQI~Z1^0N)J*_6twF-9MqSN*Y3kTuG`8T{0;KY)fUWJOgsP;|!X z?h!Diy!}#06}un1nJ%g%b|oz~e&t9lb}eLhVa4PXKQPP+%{vMJ7MPm$Ox(iMvL-!* zrw%MhL4%YTmX$Ti8ma5vu)oX{i9yX7)Q=aGPim00X|l&{MOyM*&ix+vL!Zf;s6BiC?xl)l`muwe(F0%wP3~OUG!esYpnBrTiY59=)R9^jKF2l-+yH(t$~cGOT= zufqPTyT-Tk@#2FVV-%|du827CvhMp$;J(fF+ZOf+qj1S3Rp#RErOZ zKNft4R+a=^eSUuDY`TUZaNg@9=}dFyN6%dK$(7snoGv@iM`T4>nEXWmxKr(VM->9= zR$V`FOtRj8IoH)``yfe>d@+5%zbAweU>t)+z7e5TwtB49iw7}*omqb5T%Ca?#CBu# ztUvmkO5bk4*InM~P$r>d{0Ox*q5Zs_(#SiRX1)?SoEdxR1bzAsjsd}fVZKrCE3Cxu z?d68{lAk37GFC0m!r?kUN`mw%UGWT)?#olQXs3f^Rw4slMTU|3jOU$E{SSnra%2GM z>@6KE*ex>HAngA6<*uwq?b(YuerUj&zdp9A(kgzWF$I6fl?$b&yn8kxt{T>^zuXep ze;Jfxrc17ODX@Qe;s4s=Z96Y(z~Ex_Lsy`xR6YO^N1kg@g7=8e;#@&Aq-h(yJ?$)=&AU0}iR$2j!t zOBb2Z7Q_@V9Zp<&frtxHUF#{fns@C*{QZ}}Zp;-BA2g2_yI~=D2WEY&;@T+SvwFWp zDtF_Un0L#ts>>($&KL%?Fe!+vO$>e>=da_&EO_|*YmgU_|EG^M%hETfAjPq|km`zB zQzQ7vjB^zAY<|RbFU80a$hD+*iaER*08{!G$9-X*X&8oxXqG^eEX6yP_MPY-f-Ts; z0S^AR5Kl}4`Ej><%5i+3=qbp2_1wI}FqqGZEYr)KR>YC;Z$Gzc6R zIK;XqCDGPV)I;L)rb^5butJxw+UCW}(VULw(SGhzUWR=q3Fv3Q2YjNVZUF}vS# zmc@z@VG!o_XC6)@-NLUX7Y2AT6D7SELmeft_r@hIa@ZZL&e=+A-Aum<*`!paS(9RR zS`<4&tYS}4&{%E7VL(Os;-tz)Fv^*TfAt7gDwbuSl0Ck&Qy&KWz^0YzUjkM8d^uot zd1FqyU@wdpB2IQK@t{4XAhP*l1=I0pWIU>lg}Idk7Y&+92I)3|pu5K&ls}Rch@$}u z;1bPiYpIqxW74h>WR+XWp&K0n8C>YtTiY5zH9s%}CYaItsbn@ftmp;4(`U=8T>j+t zubV!84)v^ld8W_*CvKPE9f&+o^1*_tq+N~|Hi65e4y8o*E(-cIZS3gU`+Mx*)$uw< zEacGW#`ADup`JKCx^wY(0pKVTH3BK=ZaOzK%}xI~UjbKws!&9)%01F_b}7Glz#M8= zMmtcCiMWHewe1`lYaBRc(Ik^j02sS8 z`t8u)&B<1*X6p2!CBF~4#+3r=z{iJ%8jA5idJVas&E1ZE{d;ezB=eNlgx{S%KQaqs zjbu_17Es{RR-wO^n8s#7OI4hb3Fs=0dsaf$ntIYHiyjivNonlyZ3@=@d|?Yd+K}Ra zdX(XH^R{UcEby-7hl4W;H{ry+o-hJFiErIec|ti|?K<+qJf zhjdcBK<0osFu3~z3I3AHm6ffwPCz&6jsA((iq_>#P@cHm!VR1oqrn7{h1A9jZs=t? z4xsV_*X;B~uM@2^{_T@s?tX*rpU zN-926&W5oM@a|YgAt@Lj?}!*n?e@!>j(6kAOw{Hv*y5y^tZEyM@C4_f3&93~3T=sL zZ$9(#H>MDAiB(wN=G4D0o(%E!d7;R@QgPlF}Ww*|x?=m(E6}!i`LkvN*2e@(|G=8nUCs>T8Yw@i9oqEl$09 zt}P1F+%>whSG0n&w2DJ2K(wGqDGL@QTpApmRXhveQ2b4d4aC|4!(k_Yj;uZiYncW2E` z*wUpdp;)$QOShFe|0VJQ7@y$*rfHkn50kt*-rJT>*f9~{g!>&>+by$>%5@xPI{(w* zgC9s$MH-ti_dA{nM%nq+iExXQrw_`1&DDjLT;l<0waIn=5FrR_HV)R$-L_C5JB^KH!~KXC`cOIozu*=WR%0Zqizq3mTYw-S##NWGDUx;S`iUTB|JWx?CQf&gHP zs$OW-1Xn%aD@3#pxQ}YkLmoJ!s8jtsgac$So>jXOk)T)NryjLFS5WdlU3k53Q)aqe zM6MMHHmJlZP%$e7Y6n#^SJG#;#ag$#7Yjx$I??^SVUp{s6rIi!Vu-E0AD!IVEg^J*)u^YN*_h zQK@`A!hEbA_vy!hsX|S2b%nTXIS$U{l7LpQ>#wJtXtC!~1+MW;U%G!*Mv8I`^CY1! z4$3b2aksrq*~hfc%}ei>ebzFqZAB;@e_3_5@PtssVq&L*vJg}8d5`ub&X8V)(9wok zl7$z7#yUfu_Z@v{DtVI|;$>7~;#EL9RAwbn^hQ z-1nojGl6&ga1b~9ZkS0$(nFE>8qxacICFyhK+h^$+b@xhhH6z*48yt&;+eZV)2B=6 zMw6xkHx1=|7K#M;7xwA!mI%77A;#&)TPazQU_Nnm%u!-h>OP;>t!0toGJy|752)v* z`s=f>6kO>{fI>|e)htbh6LJ1UjNc3LD$0=Lw3I_ERVAago#y#rUR$h z4J#+XXo?UIT0zZGWYaCoRua)kWa^I$4A=n`l>s*ePLpg94L(s|l2%K;QkQIo zt+UvcT$kQlcHbz}0}0!;5M6i$2&|p0Qx-iqa_`i$K%Dvuy4LyOIBE?*0nc$sq(3_x zkcGzzS+ipTAt|HeCisDm#t(OQuhwgT$d%Q^Pf18t8+hUk@mrfuF{cdwlM}N{w8E}F zMO1N-N7a@s2Z;ZfuvK>sU-6FnsM1PXa#xBk_|oz%^oA!GM8z^k^{+n>A0H7n4^M-i@ z9TmZk4>dMQm`|=wu+oBCe?8E%Jx4CxdgfGEn@kCXZp^y_7Yje7#CO0y}8# zj{>?PudC#u{sS}dm_L4DQASLwsv0Da88Y*yRPpyNvLS55ejQ)dhZ&UHt<4C%4J_Wez5{w~mVz^pjJY7uL zd@=6tPi#n4ivNZ|fWhQEH^d}NpM}7f#fq*Qyi4VoTn}p+G|lDstyVw4hVD6L4&i~r z;WBwTqz5dq;=oRx$QE-sAzd8o*Ah%Y8`FWu3fbY&MH{7eEhB1nR6kb4C>lFlz7Z) z9*DWWyE_&ChCEF9oY%gxLTy-uP6HtE}qRY_&mA zZP}o#4*y_Br(9bzIfu(Kj@XZ*t&GgX@N(>9Ys2$OKSpN-_9^X@yE3<>GXF+c^S1uw zI?C#`40p=+;p412Mp|SfsRrV^Llk9f(NSn2g@$u0)mjWup$&|$QByB{!_1ClDEnI$ z=lUTByzB^1N2qjJc827y;QA<5OWYbKT^F}lLC776sXO!Ibs3zuwRKW z?xu|Hw%~EY%5jYQSOZczNTnHLgR`N*Q744*8F2^JmuIJPhQuQbhv53h(TYUCp5yIi zB4;lQA~XOej^%`3b{o+WG;Q`j80>G|C@GATKLm$ z)2`#YnJ$gFhZ|L)Wrc?r;=|$~=*_c?aA7FNBMgmg#9fXPBYK?>Y!fBPwr$%tAdNI0 z(XYts>Siz+QsPDjWRwSiqPesd*Jr{GsC2vNJihM=-TuuU!9TvO&kkww1I-(h(heE!PRyg<<2N z1d40!_W7a4Tm48?CLvvh6LE%_+;Eq<a(J9qwHWQ`}!t-RPZj(zvcy6<9{5)kcI4 zbJ_qJ%pD|7F7Ltg{UI0~7%lf#cUM&Ra!Tl&4ee6!$qHNIFjtU@``l3lOLcB)0N?Uq zf&;=5cpusY23VO^>QgDv#b+?w^a>M1;J4BBg*q{_@@GZ1rc(e+$ ztuAIcz7Dx8t7ec!;Dk+_j2tcOo$VayB%BSbEsO+g&8$uE|CL|J`d|2kzd3t<_=U{BDR=++VFAzr ze_w124EXGWM#x>V`Ro> zXZlSt1TX>t@J9CEbuj_hfXu7_Vj+NH_=jr9hR*?@76MWMIoJTSz&{~?%E!j=`_13v zK)^kKt;hgi+5O#x-wmh#)BL|GWMyRspbj|z5Wc@c*54>bMgX)B@Qe-cIuoG#%m5@J zE1<&P_YCwb08Szxf%Oj~@i)~GfSm-e2?6Xv7C_s7rvO^R!3H2DvH~suZIK0#{`>m? zw2^_~U+96qX@h?cDHlWM-`GB7M;DWSBQZeZehYUF-KmX8pZjb1>@A$s0KS+1>uE){1n>28K>_N_0xjjxI*d zf2BF$GtdbED5-#KPWZoIoi3{|1Meyu%EhG7?~)F2?AbMb~Lbc zvj1JOk;h*<p#TS?~#%dNG%d#c^5tc zQ`>6_-w^N!7z&V4Q(XNJ>WiInY`f=Y3_a;wqVf^+kb4}eHL9ju2O%N>E|b2?P-|_h zypjii8h`Jd7AqWgl$-;7IIB&;=~2EN6>0G0Wf&(&0LDVWZ{+x-7 z$@Ys+;WZ2>Esn;B31VA76A4YrX0|=VB4!cy{V9e*n)M@@I+lqrF#o=k_}?g%|3G>Fm!|;ZKU3f@4dH+1DL^O60?^_9 z-nX*r!IO+{~lR(pYdkzxrmc&>CNiL|8xl{Um?s(K+S4- z-hkYXtfqG@g2cRrCV>xZ#Y)8V8p?5}6m!s~`V$m+Yu?n;G?f9aj=msIK!FiHXCi*! zi@0!Y{rTO4I|k3b#~>Y)btn694UMXrQud@4$BpBo$XPyq@%H;J#I_-!jOBTT`{&x1 z9oM>)K%;$;0dzw;GAHw`PfDH^ItPPzMY9D1FBe_1wuxtL&ro^^s50bb?izsk>|)G9q$?{=&`jhjI7W< z_8^v}>I54$8!6_DfBHDiZ zRh>f1j^Uj}#D*`#LJ`LdMOi!%Iuk}SeH!`|davAk@U`#0fzq7FGZmj;fao+WJUnBF zrPsWvP`Amt$EtHxW!SQ_(LZ+AzD=!ccF>>5HemLF`J_h);kSD86oUw{7q3Xlgawf9O>|2_Q& zO)@c(t_IbU4vMR3cRlP`s0W#wV63LE>Id}N7iI3*g))c}4p(PimhT3jEiXMOgYJ zxOiMCUJqK6dqBN8!onh7B&80(qyw7r&1~&XydOq?Ro6F_{TdLj8A(b|BpF-kfHuSK zs=(v!Si6sL98|AWU z<31$YN_xiV#@LX8zwSz2JuC>Gv(D^_r7{Yxdx|+eHvgmrsj4z`ol~I4g;B*Y3kH2_ zw!j^q4o&gRBtw(liZXTI54cXKOe!dv%dRM_v zwUn6m$|>lrnVb{Kk&iiyn@vj(X%-D9wAx5hJG1eVrxpQL%Dp?}T~q;5!JewL%oiMx zI1MTD!qgV4cP!>^OOTr^7IIStWi)07NQep7Fk5Pl1THN7kCS8J$l#FA{LN$8HZYBP zJ-YLdDCmKDM0hw8Hg4kFO;_a{=y$iB5YOl5lz9kQTgI!YamDGfedR~`{5yv&XNz{b zN4s(oquiU)$w~3?{0{beP)^% z%$B>M1WH2~Pw+v$WdmB%!f4dXdnI^|S#o^u#n?1GUurtHsd>#UhT~d(%6by)_-QEO z??EOJBm~>JxzDw2G@Ny)Z#^l|n8IK4Ejj4kRGS94Ey&4Z?^3_jzkbca&DlW-NCdP+ zaL~(7rDsA9fr!)c<+8*~l#wW0PpE681iyrSKR)JEFg&m}yZWZE=AmY$z5bX?KGp11 zabV7))e5s*LmES-Q-!~R4M&x^m55dK{bMMI?$Py|u1UZK(t*4{en;jWhq4k|mEJ7& z%EKZtc_AsY->^R3B5tjp8m@|~jq-_dBL8MfV^WpIDRD7)XqeW5mIT7(nJSVq79Y6w z6Hn-wyQJb|2L($LbiXOZnCCNW)5p&*SWi%0Rm*voRLnH26XFxYPD_W0DSMEbmwr6s zo=u$gqh(Wa|MS$%f>7X(K>y0V3RMR8LPn7-l!pHN%DvR9=fU zue&HtP1ES)8kXR}iB3k{L6r+e7hokxac0Dbd))!dRg!DE=r*Y&+~ST|+?+m9x+nPJ z0?9?Ya3X3F-FQM)4L&?vcjj_|=Q!$>blM;^sAwm%CMLLn79!z3#Z zgk&Su#LRAMnGDY#VtClr)qdigL*&E!q$|YvXvduOdbt>doCzxe+rWelCx%P9QvUTd zdP|$)@#9CJoI5>S{wkU631Wm{%{KuLaV~MJqfnXyM_@dR{Ks6#(XoPB+RD}wldoG> zuDuz>@-=>!B6=D^+x}?8H2==S1=G9eS_6edDA z8xY>UR@*{BJTDf0a&}y-K21j1zE$3Gv1gbD0ZP>26AJqK zUT_CU^WGcJSpVqJ@?vma_-8+5HPb+zkaa}@50`>Y)_Ey!qf4~9_Urub2KRg5$3O0iH+xl=N2~fG3bYu|GNg=T3%9|ER@( z>iggNWcZI-Oee~U5AbsW=q=z3`2Xm%_`BEt<+RAi$j0l7P-{RI$jI^fL81wQ(Qpjs(-D@jDRblJjrH>@UvVa zgcloQCJtsW20o6AWh(NI_TmmK7>!2X#nR07^>G zmh;`vsw0+ExRJ2|(KdC#gWA_4@05S=aQgFQ>ei@N_S+ubeCLJ(Whk;K2WApvfLr$I z#9J5Whdta#|87?A9A01;NTplW>Cre*VqVpP_cM;J=;Rd}tq7ETsD`jEf`5VwF^K=e z^|Fo)$a{~yMzZYlq@j0rqyL+jMvtgD)76mgCCHaUWYpz(%zBxPqi5k%s32}bOCP+C zZ-lqkknu;CFGyuL_P7Je5Nul>b0F5oW)_tjlSnU9#FTnqa)Mbkxyz881}r{|SKKL*V?5b_1E*$O%iV9%vjA<5_EyAarj#du!2o~efwoKHS9;-jiz z;&$kkoQrxBsh8&$nj##J2=5jW3%w6jXqgKL_r*!Wp0O+ZOZB`(vxZ_GpY})QIZ0wJ zIO`JWo4!`%2PM?nKNE~*pwF2pJqkwQu*oY`k!TUujzUr=L>bpJz%_oO-<|*ZW9i3S ze}iqVNBDQ3hmC2VTt{Zcn%Tu3g9u&nRJrz^h{;zWmqs|MdhzW-kG9awH<`R*gBr^P z76*@AQ;#C+b95+L3Y2l>wzDU8!Uo;bn1qi&v-RG$LtH9WRs2G>R?C<)^nEW12oA)8Ts+=o>#F z`UFZ9#zH}E1v)t@L7(#oO3J(qV-~+-s+hW8mkr{4bu;V`4(!|PBh1Dz*p~CHvH-F?5JR!WydHE?m)+HcswpWoJpzq2Ix;Q*9777^JR9P8Cav}v6*y)|9WeOuS5iNYA_73sw990 zl1#F$#$(_uR8>;R22IYC5%2dwrXF|{2Yyd+DRqXW)?QYfu`n9PAi|+?p8y^^bDRR& zS?yQUyG`|KWc!2qO2@DOy9k5tzGC)JF*&28@T1cLp;G-~raAh+ps)>6n+hydXxhQe z+=zSYhTn?WBmxY}JMQt<6B0{-o}a0NraC z1KH~u|0F3-9U$^YMpLFGI(1Zc;YlYB2n?nt0~*>pAFq8IWxoyW4eHO2cu=0TGg61A zFmL#2mJ2^H=)>F*KtOWDa%DdC&!7kF#L&pI-5@OhFD@)d?$~l{zFgzlf3N;h^fe}S zy^mz!yuo3z0gvGZT6>Zn1s-?>A1f}HfSExiOGbDlL)F@rAaN_hFRGLt*)LVswGnXkJ^#gW%E6yv)h3#YppUt8VP%WhmrXz;FKBlRHY_^l~g+2Y9q znRpMU%e*Bw)^ZTU_p-4~{V-%V@cLKU5qA0G;N038;gsO>gOu+bCRwEs%4$5mbAyHVxZ(^cj+S;8d@@PauV&LM zqsVz_^|$tM2QY~Jy3z65DfZ!9&78w!WR1}g;*9()KX=PUK#069#MX>io_%FDjf<}9 zLA(=7R$?9{LT&s`P)prFsP7hIiO@`&SE|5 zX5(KCFd9C_dZWbT2^^bn(Ovb~Uw%ov4Ym4NZp;#%a5-@N5u5%V#LEdo;UhQXV>j-K<`CQAe?y3(bWhc|BOK;TH?vkHdjnBJy?37N7=0+z#ACul_ zE*gc()y)SM-b}>`z_r( z7_IPVgI717=K4mx(A^jmnxvnV=n2FG*raM#eq9N+%h`Px1_e$$rB6#vE-a0&fk+uf zHDWp)9*%{q~D}u2`P)x>57!=TdalgOymNO2n=Ar| zo27h6jFiYF^WcZXZ=Z+4ik*Wc3NB~ryy_o4`1#ON+TmBqa8rILo|<0{no1r*vKe%( z%y+Qcy;sa=0RK=o^15et)x56KN}+if((uh!+F1E{%hm$xfz6XPHj7bp4s08d(1(%! zan*a|2<`w~9e#ch6FE9@5YM4b`DnSqV<-&xiF z(<>S~BQq=gKUT#67@&F=$hH%IdqytkMllA$udU77M%_61qqhE*jv*r93NpHz@Q!Sf z$;ke?y9f0;_?CT`Ay;LH5T{>w@ER~wnjiDZy4&}FC|aj>-*G;fr=7)LKvlUCVDC#a z=;AKI)lhj{=1UrzfI!_Yn{5(^ZQ+AzHh`ETP^S2;-NB|YWP&-99W@kzV+9=D_8yeX znYVYw!6L5uVd)(1N~t{_U0f$gZ{>#c!x)rn@9jN=hY6By@+IeL+U!P(K@is1QN9(p z>_l{1m3R|k_n2liLMYd_`6lR(fVo=*aHhHsY^|h-b=DI-FTsp;?|w?hX1FurMtbuL z{`Cuo>Z%(IW;Q>=7iQv`y08`Y_@j+VhBW3V>4?ykyJr!NIK$JH*vV;JKJu=qXJ0Z9 z6tz?=gGQaH4-=AB=~(-X+t~1>)gFk2P)izPFYVA3b7=TAwQ`(^|@s9N~Z+khw>>wkB23U_H*>-NJNKv0^IF$Dz0{)SPI>D z;BRfYpFx*z#GFp|(LQ^e*>Lt?WCFXj^;?W5-+VP?%iVp2gJYzE(Ljf6orP}8V;zBb zbXm8G6jpEZ^ZgZWqIQZV8Li0ij<7<<)z22h`hwfPYnaiu({CjD$-u8kx(DCt*Zs0Y z-|?nhP}~vvyHEbyB$=iC^_xPAs9?a`?(=(NMhQ(p${2Z|DVl(TdC*KovT@(fk!X+t z$kv0%mLNp@C$cup)^StBC~USTHc@61AJbCO&_Qq(*k8R`&sTM^AC8MguHNdqh?>!c zH5rzq3zgbOnfQSvoRQLbY1R0u8G9JHNVkR7dT4$`)Uyy@`X11se6m-1$=4&ry;0?H znka=v29xvYVR|hZ4jrXjfJhSRU4s;D;h(DTWxv3V)gF8wW*y`1Nc4k>$^qlO3B4`UTebo_L8J&qa!L@K2?VK6xGz zhg&N|@>q>5rnio)GLq3!@+~c~@+{bL{e36<6pyk*2*%;BrX)@h1#d*YY zfse<4ucUAJ$t*j;-3wixsB1R-!bFBKg zwlqr<$g*-SzPs$pu7%XH*{5_sxu5X*e??8{*ey&G1*k9yl5=*>vENT{yLLkys*93# zV6Y{NvRSYriRd^`1eLyxE59^X?_1+ymaqMyHiHrzPGU7JLh6n>vvz&2cd{xrR0eYG z;ZXM3kA@0L{64H&W$;XhmLL#tU|D4dK@mfe;i|u=&>cw_Id>Jbs*#I>zg7VMsc(ZA z&*~F8T$*1nrAX{;?N>fJvtI+$K9=~BcBH|0RMImK46v{(>m_=iflwzOVR9-=b~&uk zImAzSF@&%w5oMUhM;CIyNZ%HAR%*{je?(4)7@Dy|-r5JzlDjIy;ovAqoO=Q<5Vywu zD#s+m87Y9GySH6Ww6GrA^@Q<~{k{_xgEs{$YXSII9fMgJU3~0_(pj`&&Q9$koKc}wVSf`;b?T*JZ;y`2adQTvUt_1 z#$Q_vv2Nc?9@6WkPj@*)a*#NH@q15x#jT46;+%T2x|=kjO)0CL@TgQ2JD43nW+!dN z?Sqcj?q20<(F|f7NOo;a8yU)2{}PedPe%%flGv1XwCQ{JLC4j_UHpbBF>7qlKBy;p z@nC2B1ItQf@B&=HERBFkqLKwXP-S4~IltP^V@$GrsCQ7Z07QNC*E%EO7fb8aS+!2v zH;5aUjs#y|Y^*$5Xj7ROx#WEj+t!$jF&0r)9i&HXw!R(13cFhBS@~KlKhd&kP*qFP zFB7jkS}#%D8Io5OmyLW8vSAUXYr*B!xDL+hNAb44RK?h6JTq`>%x@R7-=42(y?shp zJx;;7v89B}hf3W%isw{Q+kp$6Ty(1GD#gY&sYxd-#!qk*3<*Ao5TXhusy}Lx)4J%# znkl6OeB`eBQe1descB;iWB$5UJIx!l9mIgeTPB97N2puJerNa{I%L{5-UV`Yx^p>e;W*>VehSfgOGWASHwEk z86w~p5?h0CpL49Z6v65pWt_&nf7&wp?JPF6(PwDoBlPw*u=lQST=?GpjNF5wogn1R zHC_Do%v1d|Je$9Uh0#F~)zUnhhjA)B2im;lkF_|R1k(?4DYIzjhiZ$l;Ic3GAfJRk81|MNMo~dmd;Ctr~ zf6dShJ0;h7_N0hho2~}64Y4?{$dnvg>PjJ}hDr1H%ikNI@?0k{{k}pc{_e50)6TX| zs<^3SL^bARw-P^1*1+eu>Z#?K+L*`EM)Kivvz~kKt0)DfVms<9C(YE8kY$?^>Ba*nxA% zy=LaoiZv1Rh@AVtTLKF;1ZXBdwDJ zsl8Qdc42CT|L#!#P`YqB8bQ zZshw0Q6M?{_yXzKnG{XrR^t~acF&_S?+_%3uv8)y=1gmJAH(VtE_ zJ=wcgB-^QXS5uxqR3Ei=xNptGAJfrb%iDZ~05dt7(i(a^9C$bPt{(Lqnw?-)6o|8> zfNj1>Oij0A((K=y3&EWRdrUXy=pi+V6MU35+D+umO$ViXZ|Bi2Yo{XK+2LPc8d(c; z(kizSzoQN^Tt-?4J6vK`LWc&GmN$p?9~#+ zB_bO-Vv=E)+}!A*RH)p4P2K6oaA!*Ot9%);w3Mq)JUCBT>6>MLb-~fAn@gT~tVR1adnjqkK zK*{KcQ`aN`zz+nUhC(N6E6h z9#ffSE&?ILshgtZ=F{D8wJ4a5vp9EukvTI4w}8$vZ}ft|xqyXu&|I9*Bs&JOg!5!& zaT9<`vWqI?wuN5Tt@ks?pmn8e^7APvZBhTAgNy52*fFX=@M8Zah5aU-6I{AKoohDn zdX=!D^(NtQQ7K-Dq!^L8S3rdbACd*%{i~YnfbSjuqhVLtNe8$D#XNDOoF8%Fx-R?5 z01sTC$HQJaVTxa$-LM{8wjuOw!}?~N0aBr7A0KQ?k_!3Y`x4y>b_FA*(V=C1F%}Iq zS^Uzd%p^0J*<$5*f0QEKqeI)R11oc%9@b0I+>@Y#nN(vRR(06tG!CAjh>bG*=XSkw zfhv3wdP-&jeSY6naT^K<+~X3or%s`4SNK{TC_7{*Fx{dV4?F7r6U z1zkE!$e2%vVE%d?OUjdsH|^T?SJL1XoAqmDCRAY_mJnWNMwaCzIw=!ouc91U%(%_W zEy-)hnA?FL=7-f>s5TQfIGfrhi+R*lw))knX&5{B3yZf3ubTwBD@jSf*p35%Z5KmV zs_9`Z)CE9Kb8bD@Jp_*>*XqczJS4)W|R?@FS z;icCUsc4(>-uM}f4DNFZF~<2#p@gP0d1j6FGflOySrJYUbQrQZ9~U&C?y=#d?K=J} zVln+O7`sI)Yh zv{k*}A4pa~y}+)>Pt0g>4Wy??oZQ?D@`+Ni_|6`mr{eih+5}iEX)}V)8HajCcN@m` z>K>&c)AWW@&`IlVwhh^dm=b&haU-U4koPXv&ks;VlV6}x2`|2VhE#LEtc`6+773t< zimL{GVF%*!?2OcwXF+pUm12uRsc%oLDzo!Ef^$J<0?>YF9yhh4=x zf6(yG9|3RH%Enpex~?UjL0m=smW&zVT&*stb zVJO2(m9pA{!Z^KPv1gZ(KnaO10eG%H@ChATi$dzWDkPWCQ zi^NJ@PQu6Yy8bK)=ZV4}rA80>hjI)e6}AmVVDZ9Uo)|wd$P2)#?zOI-i8offEeZ0F z@QC-U+{rDNojs&L^h1Mp;NZL!V0KPcFJ>MI*!uPMBa6iH(v*|d;WF>>G`K@nBDaa; zZ$`QKNATXv$C7No?s745dh%aN@aVv{qiT;Uh@(O;1FDWY*-7FHXZWWI3?`Qgdh$ z^CZYL|K0)Ow4n>X)g*^ha06F1p>yxrQodR-u?<`bC_LomNHb=#T=0BKDlq!gyu$;M z2%*=lOcy>hRVOUk*Llg0V$B|0P)9%vn|aMDWoXovT2_LPa<{4 znzx^IDoIGB`m8s@OKyDOx!!2}&B<3YWCVRvlk^29Nsn*18r0bw--Y%3)lLB^OnwW=nHdN`EG9wzBm zCB2eDEseb1H7%edj7;n@5mtnBH3Un0n4l)c*MjMS3Ist@c!mUh!(_CIH0hQvADHd7 zn9Ue7$Q%4hmOb<+`1-_Gkcf`VUf@TOjayL!0B)!=2M@8aMst2NI0tXVbWdX^U-0ZH z6Y}-y23P!C#Uf}V+&MW)HK~gw)BQk{MbV-b?d61cl?n{?d>-znt zpxLXUI|k0mL4zy3O8GAx12S5nM`8&?466 zRa%~Zf#(sJ2z5;+Bzx2Spf<<4oIZ$y|1PXBBU-z)QS0Ynw~!q|kYul(M|dIZd7S%h zi@hEE#H*j4*R)3BgPqj<%G6b7tJSI8wfa0`7q~ML1dszrfZU>x zDn>{4ea`Yps0ML!#S;c;*x!yGZJog`#S%k*^21l}`&hs@*c_&?aokg)6akcvZsWAi zg-u)z!Zzk1}(8<#9p}1Sh z5AdnO#p1yAbOpjKM84i{4MK4Q-3Z7IbyT#xKfK^WZ$(jn#wCRci;Y*k`%|GFqY*?q z>u%>CgdLtb?NK%Jk5cT34&i5xx>YJHNbO zO!(zr@=~#iw7gxFLvfisp^%UWe{(ELfM&Ghhu`t7vcDX?CTi`MfohJpgf8L*T*sSW zTh7~iK+%PvGYR!4y=6K{t9+iX<>tcVeiBUg zaaWhh`S>6UJq|kdjWu^;^X1GAQ70dT^9c0dk#OdtvPc{nDxVvbVd<$HZMD~=cb)oM z_NVO;_Br*EY|ErxVB0HZO?;$Tg5AGu1?>$JebU!l_JSTYK{1ERaZbCc#nhA{Y z98GOaIWJ16J0*P)C69OC58y971uDQF9a5?7HsE~@G>9AR?$qJ}zetq&UekCewj;EZ z;Ab(``IXCok{!<9j*5m#Ma0bJZ_eQ9CHogAvd(IIRgajlGO+>k_kD0_Rcr)d^v?E@8Rm1iyIC_2rL!I=UUNH*P-GgZYKPMRC- zhpJCRPv!!h+u5@6vVL|Cg>_3`=y3PsIhE9!-?ER_jAuAx8(C4%uv)hRMO(-n{PynF zW?R72ooa=lxCvZ@J?bPp?3O>>B&QmR{>r)GKcU~Nlf)jkV~)4^+F@8h_GFjv6cohd3@VFu`{GLO@a^PnvyadkZ8EInCWHmYe zHu&w$9ctf%@Am$-4M^1GiorL~?41olEiFBnlRo-$3&eDmQ=f{jpluTmCz)fGOBegy zBf~7O0!U9eSZpjF{2=fZ!#;NQQ5%`e{i0>vxP9Ap1&7LF;3xNW4}HF1-8a(DZ&H^K z{KO@oPRFhcO<>%v_`u9htoz^j#=5u`ve4Okj9=1sL459f%R}8MAXI(G7N;Q2xtH0d=jWEsxq>dc6i@J))=eH)tN zs6oUAkzpe$Btl5*PGWrP<|u~>+}j`0@VVN&)SC_&StB&4%;*lf zO~HYWNi1p8@Y0)=F2WXb___==w=(u|n^qXr_c#@Sb}Fc$&F@O{2M2@X{Kmm^_*p8P zquv>gU9*!+_7)6Of;lKV^IzjN0#NughN@oip8fUQ{H5y}7wk>h?1Y+Q>4Xd^K)iNO z7RhhHUvh-4Abh{jFh^C>>LuyjhyNmiXj?gTlmg@FWxQ=VfIS=;&_(*fqV$58Gi~08 zf5)u zjii4+jHv(zKHeameJ9c<4}CLXhq8B)$aj#g#?@~u`G9uHrGCZ-5z-B;-z#{n#lz{l z9WO^|F@cawqNH1(@aEL%R17A3O)%6wp5jF`n(jH0;S1}stTJIV#IPyp1s{k7&h@%m zT2{Ni$)zC2pr!jUr?o?-*|m|rGqDF&^lKG#nYP#^AXEaA5WK?{aR4YRg46W+X}O+6 ztMWcsKk&JHw!wiZYSuYaV4{BCpoTbppSMw{IbLAoN#bLa zE}IF`ddw=dbZj<0rK(;vpPVcfE{56@+48y|cSu{+OYtW$Ra<#dhnbZ_+G!XAmh5U! zCdG%smHQ%OIlD$hNh+Vt*m`o^oyyA%*9NL>+8s0B zSa(}<;fjMGV#USJa<03Sy=)ln9`Wfc%T=U+dcx=xCm5Ly;#F1PqP2}k)w9p&MvYN%zI3|lr+&RKn z9*eU{d=&k%QJNhixrub-uZ$k4Y7PCUti?8_gCSb9vpYO)o_B+AO~^qs^^CB=L#e>{ zTFv`b1!LoJ#5M^k<^;X(u|)pE3b5kX;1u_4 zHtSG^*J9ML?3R=Z)~J1gF>&{=75TK3v3t1->T++xwKjY=TtZSHGlJ7wd9w zl^PU}j_R2L{F%L&>za9|ibjU%S69~=$fvsIZf)PthaXpyU2ivq!Dv(yr$F?_yiLtf z`tc8>IW2YZo8a(X#vj%@m_d_ia}b4%XWYi&Me8Ld?zrtw`Q{2a&fWwyrwMS9mUR>7 zCtC8Dh;Py+&i*DNHuUD=U!8d z#!RRmo1OYyY$iOo3xKsU4-Bgf6Mde-AZt%Uc@0(asxRs$1|a*3anCskRzAeTKa9Q? zWo4Kb$vnzO12gEnjLCfAw2vQ-w;4&cl8BPj>_I-LC4eyce2H+en}`QpELedDiC7Nl zMUII|7)7F$riHqHy`6rrifwgwsHhm)dQ9+!w@((voM?F-i#JGCxaL#{zFx>r^9X{} zeR|w6h%3i-$v1)``T^Gsepx~fWzq=xozWxggp5Roc`i37g`K}pCC0)vu8^^G^trrw zoTTK8aQz|7IlGLT83iN*Dp?BW+z73!CH4eXwcb5K3M|wD)XmPY0zct1R=>EWhh3q) zFbbBe?kwXuth&ZXKs+~-exlkCXeSWCYL@_pn0pvj<~tKj*i2^@^ggY|rDT*l{AQ+< zKE)8FhePmlxkIiwq4l*>a6O?hY}O5%Mq#VAQOr4y0o`eijJRTj7?@3fL@~p9+pmUz z)8s%LsRZ{0F1f3_jgquE72Z2!m9!r(JP0aop*4L_@o;DsgRMVaILoCn~JYlKP1<+(sf5<4}$F$E|Rb{bNwva^f4yiz>(PQGk4hyS4AyOT>@-tqK z%AqyHK^Mp2x(zxs=GgZRn9=lpN88se5U*2k1Vdt5~C7!DCj z!_5pO-HV)&`)DOQkwdR6pZ)m6fH63xQ&8EuIIjHUiNH03B}}5aufd|?5XHx@i54I0 z9#j)k*UCQ7is^@4U)bG>41@Hrl2Hn?2il4Z)B|h6nP$>>=DbC;6X4&*n^sJ^GC)w< zR_*%f-962?BbB61XIi?rvDL}^>sBMg!Y1(ZswUj9+zCZNizn2`Xo`>aA+wNJy~Bzc z5(HyKl>HbcuGbOK?YS=2N**n+k!6Ey(vzg!3gwV*0zO0aQ~g(L6cRSZvqEV_ z2mxY3AJ483DRDwvam`lQv#7K7Prd^)u+|j!_Itd8?)M2h`7AXe5hC<2Xceyfdd-H7 z{8JSjDOQ9uOK)mF4DZvjB+9281GIz@z<8nzELBWxNy=n{tRX_ zQdAK$E`x<8NcVMSpiEGf$=juluKC=YbGcQ+1p#F^>qV?bfWQwOInblc1WmeB@gQnE zmzt3qeab5&jY`n3`3a)(WJWB=fB8kR*35XTMU;)#_8xqFWQHL4>H``VR^DLc7)Ybi zOglkb>+8)kyCOq;$0qH@DHy;fN6&sFYfg$!_YGZdgz}odDQsZYa8jR9ND6CcMRQ^5 zA$GAqQdvvQs2K11p_Hmb7qp#un**|6=OmR_Cq|weYfjTz3SqY{c_4qZxw1fqH8AXI z&yh*1tx}-L56kA)nUiltJpPh}!&Pyla++VMNw;v2wJ0{f2PfAN63|!|c41bGW(lr3 z#2cJVSCXyCis#M?e+jm{YiP5DVp#b;Wdx!X9}thyk7u*I*spaZrR!0fYA7OTfd!6Z zV$G-3aXJM9AX16i+tHXL%7emW9{P~Zb9vV#h7+`W879KJ;=@3iwD!1jaTU)pag%tYrr1RapGes__0~qz#cozHfm&_HeOn=>w#*kjVwTB!Q z8l{G$l~;T%&<;|s&xjHpZ;ZDH0MA25m(7&Qh$hrAYee6qp87V@PNct02@O163HYQr z1A+6c5CA1Xc8h;H$2DtQB`w4yaWsd0reuB)Yx0v|5EJwOz6;G4=_@r%>jJ zaDbwuWA7KSFt}hb-vwLm?7K#Yp$?7uHLQN3Vy=~a`@~^ zcxm~$rT*p`d7gbUO2>;X%@kflgZN(EP^_dOLYXSA`z3wL(7yd7i}~|-@6)(QQ%}0t z^N;d}W%CwFx(!~5=x~4s-mu0@aOHbx1t_dd)ku=+M>T5#jH%aM{v}V)@uXZ~8sZ5p z^`F^9LoSs|GG63+EApahL1#)i{Z&Rx*?h+6_IY9wTSNP=$$V>J4eB|}#9<3XhOcQQ zEBHk$*!DkP{GTi3^uEoy)hM~SP0V&_mq=dBTJPSUIRAQaj}xG~Ka+aE>R(sn@wEG9 zcuX@?vJ_7)$SJL&GITgry^uXt48H=7@@<$!c?U;g5@Z+U4KV|O&w0@nZJ5bSCcshg zvH6U93-AM$m=xpBYxW~*9mfwu}ra8`bq1n@E8)mdRx9oQNt>wAQ+rW|=x0JL@t%w}TPn9tTY z>iX$Lhs>iDdmQ95Ki7aPh&8492@bB|IBpK({{>M%uD`KPYlj(baPQSRydlB7Z;izU zS|`E*%zOUDw z&wMu7?9MpETl7)|9HeBisbdec8Sjk$DDv_4b3p#A9V9AHYQ}p(ApU6~jzqc~)%@(! z>$2Qc^{iId1rSyTMfZ*N&wM9i`S*&|c2-7?Oaxw@x<~xBKlO*NO9v|bXVwNJ9@8=D z&17)O#k0kEqoVoDb3wDOA5q16U6FXo(;uL>`B{?M`$j#KL)*36OS4a@Z)xEmU&Po% z^0@LsljdtDaw24B%|u1O3XX5X zuz0z)S45it05lE?LkZPkFq%M*#meKW5wSR2(aYWNCn+^piZf^Je=8ld`|oG0A;1=G zzO$Od4XNaN`LwL1J$jRb;`L3x(|IG;%(Lf2RJKbeopNqJ-Kx|i_h|#RXekU{My*aX z5BD-Dnz&$zu4Lu*IgOGgB4xDjW!n@l!tAM$C{P$tv~6LGekub406NqME(MG<8d(^t zDL)f%-GVaxtrv4c`QGP_%d7cS0%&C!YQZF8Ow_pov*FvEMHuee((DvPO|Sez3awt$ z;>B)f;Dqh0imVwE^dkV-Zz2{1!hbgLUK6?LgCptD|GHgQ6oOt>g)y?&Nxt>P+osHw z`}BC55)>aT{<1tP$M(ehERz5mzmjF%4 zZ!ow1?Q8$PyhGb=IBvUmwy_OTNxQ8{w=Z`Ra^AaJQI%k053xy@lZ6+@E)#MzAENoW zFsc?z;O+v_0Y-(H!P_0P-co?3aHo({S|Df^GFF7KTE=W+rebsCxqqM1v{&;Un8cea zu8(CZJn75bqMNgPt}xi9q$Y7v545(=_f_LKWp94iiQi@zN;sNvIt&N5qCEVw?UXkZ zHgBX?YtpanwTiDHOHiG!_^FUTlMhhh+18vE1bF(T7Bf83q?v(z15ggYS+=Igr%_V_ z)ub8_bOW6rZqZN5RX5l+VM{{ly6PK-cNR zKPBa`d>1726KCYD$MsFMFeOLXVn!|)Qt!8~iLsz}3tHT2xKTiw_Y9_@{7`_R88y*Z!vGj41ilGBa18uxlyPcnz|iwk&%xm`1O%>&3iY*2?>A4s;Z`XFmQHRNp8xioD48pWudcp*>uk zs2Rv+Cb6P|2KAG=7i;tZC~3&lbPj-Cj#d923jbWvez#<8lyK?1=>-ZD7+?f2Y;;Y?;--0K5V8a3Yyx*hRPU; zLH9e3Y@w@*N2x5t6zjm+>&`ZBSnLUF``PAhagfA)j}@3uGYsZhkJn_{;*9rrJ7j>x zr7tZtmoPh&58LvO5)6}(MuWX3_Cd@!{{iPh&KBSTX5wP@rf`5g<(_ueeh3ZMvmZbH zgx%t;=8S}Y3lQQsvTnWMYQlzXD;$fQ=#y4Ol-n#U5YnvP%%W6~@5aN7V@*KYF{%&3 zVTxL??|OIf;22U=I&{odUST#%n$6`?%0|%(!+Yz~T+M;zE!}UCq7g}S#fBFWO@;AO z>vpOkXHfvQOcOv%Eftimw_I%C|22#t&rVD3C_-4Z4(wMQuV}jW1n9U7Hm-guyC5#Pqt2@>(qYS}kDx*sA7^LrP%pV}s{f zkCZRuV;-bp%$qh01kMJt_TL3K)X9pe#GdXk+4_W*^05wVVgv;Fci+WNxAK&gg&V6- zHOKx5AH9ON1&>%W!b#i9_(ilyhJ?!I{Vh!TZTy!I+>3Oo<;=~gIaeNqao4K~4lMsZ zPXeT^8Z*l|X>el(wSIy2qU*`FVN-;B=KmC9b4)6|Rh`BBjasV~KWGA?Kb39c1F8TN za2$ByL~5&Ow*)oS*cKCw{-h~;kKs22x~d@p`3J%1I63*Fy+XMg=+7JCbrhseb`>GFO)YN?G3k!{{nxHhp5t}S{*_+k800<6G3A2GeVJE6 zV;9ngYbb*@R^L>bd0;OgSwfl8M8`6c8ScEwr^3m$VeQ4-=(@cz(6upH)@{Sh38kU^UH^KZE;E(*zOAS~~@Tt#YB;h-7# zcAOO$T50C3y}s^bOxpa2W?Hd?mW9q)GcVk#is$Rl=%{7->7Ic@czgCz#bTmt7$(?) zj6?{=h|7eEf|Y)t6vcV3-%Zwf*)7Y}cR5$>8QI`APHt}`!?@0p39ONOkRzi59NWs0 zpBva`ee~Eibn^gFJ$8mZ97pJ!R)RxDS@?TaJ1)P zeFQ64mHIwVfxVH`XKz(BK1LIVj-Zg;tfY(_*~(F!t(SM`}|qLGPqFG;Fop8JJ=WMx^s|(EDq1dL;yzsDF#DB zRAhYJ%yCgGUOX^bmSt!WY!$zP8Za%Yehn70GyE>tdqoBpOBQx1^(GevMR32Co9$2# z;4QtPs2+32PkknQWAcQ|k%mk9jVHXL;IBImiYG@-6YL@xQ>nMgy5|Z@>2($#z=*`! zfU}8^iNy14X9-h#>849*lU4As%T<(*U!ie`WuzqtF4@37u>);&Hm`_la3Cj1J-_X^ z(Ht``o0k%C#s${!VzT)fIBnMJzx_2|Sp<7U&WX4w1GAzn!Y~^7PW)8>nAG2Na`{T8 zQdpn}N(qwEFk;cf4DI@Em>`wzSNU3E#hcgqG)~wyiC{1kyjg`Z>HRlGzjikmKYC5Q zqRtApmtOYcmgG`^>SnsnVAF+&rX&~~XkWs1BaQ~CS07E=;;>d#kYdvYtNDVg@^E~_ zwH1LaD7-w-ZEtu!12zdZcjQ`!IiG6Zmb-l;ahv%0KY91 z_7j!xM;tHbD-y*QQ2*Uzqw%MC5CViy>1R(hoq}bHHMrt>`9LOVFkt*kLY|A0UYggE zeigeA`Y6w{oqpMpMI7g${+Aiq7oy&re`0uZCkEk1#_C4-#A^}T=Ywz1HUR(E4;W$~ zD7h3RTcwxEv9wf+lf4Kt?5r8aQdSf;z?zOCz6HE$PL)4#yvXPI$?fJNL0(t;>kQ{; zEbcO=;?Z1AYJUWxB?!ixLw?<`jxHaV*ygfMi$;>0vs=A?H0~eoN!}0lwAA?kudB%# zcyP4-HdZmGJ@qvH=FEgxRciCHr@uqMst3hr*nU*Wm!{+Il@2AyI0$}t~D(mj&U`AKJ z@Gh~HKic(LXj2&lAjsJo1=ABc~RDh&%|73}IxhtU${3hlc~lP7v} z`W@&f1?^bRo%6T`iMX6Q$~r#rUTDFuXGx{I5{u*$00ws6Wz1M538!7;W2!R81{jgc z0iB%~4w=$wps!7iA|fDQo;7w9<7ynUpG!bOUS!mVsS2FCn<9PmGNXPTS3gl^(RhvA z%fd_YheMMc(tz3pi8wWTTFU`!6~Y^F$>cWCqEEmqrUri|wpxIjGsQwbV`+`-P4 z#M{{D6+EJ>J>MD=zWmrtgv=0kH4YG`3X)$Xd%KMb{L=+rbs-5xvbYt}vUMGYI;kK( znO4si73&);4~%HPEZ!OeH1N@C- z>$iYl(6#Bfa82+SFf6}3!WMCABhpw$ZPyFy14Y637M7ooRyqC14Kvk!w#q&xcMsif zUa0SK{Kw(eALxXr4Jjs*qA=xcR*LUbfPw@hXQPk$K!1MakR{>?> zkYcA%_fL(DHRP9!f4qUeG02-45NEJbmxRzOda75~BN*s8;p_9w zQqWrg2#u#HHEuXZ3r-90(pDoxHdJqMsK&f9;*G#fMw@81#kkVSx4?TnK}C7wp1LX0 z*dH>Nl0H)2`UPaKQys5#oB+e$`ek=x=k%A%`a(JM$c3EdIj4%*I?x;OMzK+?d*YdV z_B9ahRp&M~FK-m%NpyuF?Sy%FUg~;H(hL3uGC~WXZ(nu;fERCdqMui8wqAlt&|(o& zHs)!O(1w3sM#l`JdasW$j6hNUE*0ArYlFOkiB>E~lmYCZbgZY45=F$ve&4av!mi*` zz)3h@OGkQJTT&@KJZi!{1T%+Ce6bJ>X-1pw7T^7>?{eSXa9hpu`1=lTgcK319UC)h z?1S(_J;_W?*K|pI27(bpuff_6Tq|zIJVGDAbXMcsBLtbKf^b*T`^5g9pp>f)XX@oJ zsq9e@xoC)C>_!_stTvd4I_mJ1*uX>&cbKyO^jMvD%Gs|MPv>U(Ci=Dk9anZjnR4*~YkGTgq+$kYst2~V$sb?cZkO1nxl$^avWKrpQOC6)=Yd!2?qWAJ% zbuvLb+-V_^ei|K$qT+AQ$6aMENxjY_yu!UWtUH5ufP{HL{dsOpZ@QyXC~Tj1R&A{jL( zR91xbL-MRC5XmTO*CsbfT}occ<^a2%HI5J9cH}!VVDg!g3{lhwigU`7H+gPFBs`y+ z`;v$RE878W7Xmkunb~}AJFONiLAyO!A0<3G^k8=4L8`=kTS`h%>=t4aJ$-RP9x zi?eerTO0Dx|4i(fuKm}7bO5!KJDMgjXHycuuS}#52&*^tI?n9_XCUus3?mO5_d`1t z7$SmtGEg5~gl-bydltKi*6(8&DPc7>(UBSg>2dTWb2u)i-Tx#XHA;-YmNK4kQ*lS} zC-MQAmI&H*(6v|FE0f&!&?xLs*;RPB`K`n}L6QGL$n@farmCE^94h(R7Ql|qv<&Fo z!KMs15_bA+CnP5&S`wE3eNCUt{L|Fl%Hv5hp0hjT?gcK3&m}!B^{J&%;IJjLym(nI z`>x(Q0;iwT=C@RW49;6!(*i{rMtY%$K%n97$PC|3UH?l%DcL){Qe*(V^-912Tzc21 zvS-ovUKjr63du(|0I>O$w0H6!rE)mNczsZvd#S1n7#D+!UhGJcMBwBud6ie>`M?b{ z&LDa+UPH<`(Wlrt4AAg1HBGHS3`0CJpP`|@TO2aC+L>eRC)B6@@+n|z>b5y*4PZ7j z7`ZJI#rO_#mSx}A=3NmVGl2Y@B6t%qzI`pq99ur}LBm#!J995;XHw7iRabegB;w*u zk4Jxd2RtbE)J2}v--oi`u%7ymw->eec>wX+r%R#Q1Lf$ zzs)dFJmY?Gjp6SuN(;A4OnH|1Nu^6Ga=ft21)PYSQc6C>;+ERA-B!TXqw(2$)7+Q; zdA~byu+Us1&+{qgkNF0v#qo*d!CF(ePR9ZxOq>M*9 z`4!w<5T&v<+KK7DS|{?|6`is;i28Jm3f1&|M-C)y2t8avke5hUOQZ;<`&ADFIPyER z@F?(cT{z&A0hny*MM;)gG@dauh*zAnYa_=90~Hy}t+tYtpYaXwDR0o=IdYrrp`w$B zPDmm}p%}3%MU#5uKy0B+GzRjKbZ73zcQ5gU!#I{~fcq10H~celOqrRBFbKT3By~*a zYimkQ_l5f+MHVzPBngK5+H`&2&PG3dm(q$- zu-C7i*Ty~FPOvJ-bSM<;kP6}~aY(vB$OEMTkBpoCnJf4&w2uQi1U2V>3;_hpH_Q7u z1DUPe2XN@`#G-|Qd~&whf;=MaiZ2$|52;VQ?dPF0EM^q}&1u87*zzq`v3bmT9ec za}3jn=sXE)xUA7=WUJLZZQHSq+`PI-A^p_Y(1cK<(|*-~rGRwD%m*qQDBe@1n+u12 zL8GF)GB4e0p3V|X`hkXnBV!ARJ2fz!Fd}&J8qQ#dDR#gGqbm*3ZBQM9uY$C6(Edc! z-$YQ^%<+u^kTrwo#ug)GTVPn!L|>T*dDKwwUN_j?@w@*#!5HT^<`2hT?{5r8&6_Zw zD)t?OpUZ+qLN#itgLD~Pk8u-#Xv&=_y%7h*W0j+Wf9w<>|F+8$e_rN_%MjS@$~;#X z0x>hn1jpyKwxaE6_e)X}bAx`iBQ-{W!L_Z%mMT#mU^Sx1lk1r5YsV)}bbJ*jb5W)K zN;C^fO3b*flpMFIimB9o{|1w>i4Hpky3D+x2$I&Gc7d zLc3h_T#M)iS(I`EjKAjJP-%zu^3n_<_iWp)QiGoWcaVG;cP@GKL*GL+E5fJU2 zEVH6K#*jH}tO(?E0eda(b2{-{8A#Yb&OuYt(-$HhHR3e}DUYv)CvCkUri?gm2$2*a z!EPqeq}{&MnupY(CG<6K$K!w023AK8c3%Kf_!2$GdB~p_eqWA|t`ve&dH(Vl%KMcV z;wsJrGqOs`XsHFN&c-Jh*Q%U3Ld= zQR4!Z^8+DRU&+I{#!g4SzclG~aOQLg_4RSHxaji)Ny%Y8Ucs(%I%c)ii%mIKxyj-| zQ2@Q5)|p@VDCl2U_GKkrJ4`VM8oVOb1D_Ebo;ZFh6OeD@-kX=N5_NP$T{v1>k7~sD z^B*esXclc{H})Dtp)0jmr~vk918Kid8`pnV%pjw=;{3_H`c<&Qa@2#>gZ=dD_Ao8;4PX_4(AUgH}4LxJyxku4Vj8Smv$k2N>2G zMt=!L21`IaE|KXQ4~sa=@jeIr9-tfyE2LF`7T&@z+he|_gPoP(LO|)dK{gb1zRzIp zx&kI8Gk@h&rW0gk=P<$Gwq{z$Y;_$Z{=H1hJTfylm7HFk?Yambkx*@A93u0fppHhi z6xHI!zp=M#{E4g_BH)kpr9|lj5CMh2=A4!(c+8ri=!V!diTF;$-g}l5!kvEjxFM7! z8aKkB@0Mlo|G2MtMZo?U%datl4=#b>SXY$om$5;A!WKne+Mo(uIbt9m8(DVGIrXZ5 zL4{TGx%Na%(9nUkYTaGR)uk9xxz;W!=v(|kNl}>obnkOj$?H;ShSA#B{XC=_!J{Xy zLm{Rzk|Bw8i;282{+nkWgw8|j{(_#R%OiPiuul{{!&XNK94V_F`t(cAkH8!`d_#$} zwfUAXVwB+x7rd64sWCAE5EBO#$|D62ep55iz3=17S=piUoGrS?hKx>ew2ihy=iyDa zJ-s9Ad3B&0;8)^X^RHHz^E)no_B#I%#s0D!n$-VyfmlIbKoDT>afc3I{!8EJXv@G! zra21u$-Vj~=J0t{S+9^)#}c-Lme13CYV|Yc;*Np&`Bh>Lqg=F_YxzdV`<44^)wv#6K zOnJ)!Lk$C?v=gLTl+)Zx6Ii!bfFoTv+Qpt4Hq4PKncMCHItSA&+<@x0jBB3h<^R6# zh_3BD0^Mf`$U$+)KAtJ7e#^ zmk$^p3Ckuumc7?!f%ns2cH=sXwy|}$F?jvemFuwnQ_@;5Hv+>@>5s3!<)J6tBN~HloA|`)^^J19jw`+oHsePgNMWIr||4Wo%H`Rv{)8 zmn9q*Ju zz(rw(yT26~`XOdUfhNM_l{GNEjqT`?3?S#rqFC|yeqc*Pj1wx`BeufhZVTH3f+H?C zTVy7IYQ zGdRsv5K+QeSPxLS*GOfL_A88_nqt%@y8ZC8w)kh!bxZLCwp#lW0n?azq_7g ziz!0xp5g5-s_fNa$*`oW{WCwtU(FM0OkA+vk8`lRcXlY%%f}-7k`I5z16z|tlsW5? zSjPa*-4O@7SZblR{HUM}C!a3LC1GwwlvvjVw`p~yhUZwg`zdfOWbGH`)xj!F zDN0t$E(MHVzid;PP_OAWiqR@^4`b&o#{qrW~1Vt3U-A9;9 zH%%XH^RNvLV{&kL*}dg!D$#as^^-{OxKej+_+2Wa-Cz(l+o;q(=#5beQw1TU7UsdU zv&_#!$RBgRGv-*^P6^uGpfgt9kv3lT{F|y;39=Yx{EZ%%^QAyMP~69?ojAhiNLai@ zdBb+Hdan+l^ZxypT6?xgv+Z%>bb4PVq`;zPl%dY(A5n#*AvNQD@tEC6v=^JCztwmW zK(1wZ9^HPn8{H~#n#O0_w%d-7E(W|}*(FBIM&M&oRItrv&?#$e0$c8eY$nOVoLO-* zf>v`HH@6y+G z9PDaNy8KCi7JhV~m?Si9a_NACb8OFwm@6neSHX~zBvC~&~43o`J zVHzj7%pbqo)x8$U0*guiCm93hcPK|lK|{Aoe_p#Slw}95l<+O&Af-HPEXlAXvme|^ zz|=>QV?@A6PALQ+hr1h7@)@tt`~%?u=!NLFSAy~gf=CTwlu5a&#w)ZmbW%v$U)1Cx zy=|>L4W2Vtut!t%T?qOJ;>(S~;Jrc3mA`Tfd~wEYal3wk^=Ns(Pa|a1HblKssWoSl z2>-&gsWu>aiI4=EyU+qV{_mm5Binu9KZ-=E`v4tp-P9m$B>cQF!k$L&dNmE?zq1?1 z**VQVQ37+-kp;v!m3cOF(bzKqAXO=okfZ_=jVe}yL$Af5gC%86xLFgxr8}E!>-)?hRuY zR&%2md9EnC+dw7nYQBSJ{woQjzX0x5W~?0pJ9b=|vqaM3O7qt7nBDB@dpMvjIH8}@ zs{DJqLm$cCmUJ}P(XpEGm_qb!&<=y%PW9M!NkBM=cq+a!hljNIiysyqI3A$j9{-%= zV@NAqc;_9Rsxh;%ue+9Vy2F#!KL!J)1H;}T7Y%AUC8om{3G4@;v@3hOc)pP*gw8xGySu1rSl$YvCD zQ1`1I=%k|_e2Kb@Ox-_K8T$Bum@bU4`v7&6h9B^o(nk7hp*$u)U=g@zqwel-w|QIh zZDg8vx->z#nFy#=3Z38e>#i=b`i-2EeJaA6>U>12jOjU9OW-0scWF|$V1X-|kVji- z6E37K+WF?zA|IdZzPvJ`DJNy$8tHSE-X+tOjx`$@(_nznS@Zpl3nt|Uf|ot$^()#j z?D)MDtkj%n{PHI$UiU*S{1c-tDvix1{w-m%vZAe8?QR94tNi{!iWhhnqir|{m7i^A z@%Jxo_KK3rtV&!s-P(bphgHk-srOSCHtZo0uOm>~y(1?%R&$|vv8Qr)DoT*O;#BSH zkv#{BE_G;aI1c=;w3Bg`tG+^-yNb06A(G)BXimdgNn>!Ixctd zO7?(zk?RwWH$n8|;l|L9p4FZXy?FURv)Da~3$Ch=&FU|g;jGrP!tPRX6jQs}kUDh} zmOKkhG4p)TT0cOAhB}+Z7bgzcJgjkv;P?WvU0H{6kwv-#$nWYh6CzMnBdWN-O>KHM zcD^KQei*B9UDA7U(w?)PWlaBV@1P2pv1o1RS4sHN=eG;T5}22VHUE$0Sy0aa@xT3h z)`oxm#q5;6bEt&6Oz-Y@lM)qm&iGz^nRss|xDp@O!z=56?K=(t!ZyHe2_kL1lUYek zLv8n5Dt!f5>~1-6JfpO)8|V*1R3w66)vVZRm+bqEs=%*DZTFEM8!%H2yBF-Q_Dz`X zSWHqL15hC`$yb~qv6IA8;wX%)AWvV4>_*s5jah+{jG`1) zf03{MYKdVa%z~+kwJ66kV0)!Mn?{Tew^bU5KVwT^126<~?7N1q&Qzgk3B_}xptr4| zl!B#|q&^8@wpj>VOGBp{9?eiDd?0a$@gaGDVAPD|(z$22ybz;9fbXJpr!r{Desa(= zlBP!c>M=8XA#sRd7ZZJX-LgW=wvY=8A|xFQX2ZzYaiCFynP?uiak=0t-W3 zbpUXcz_YGut$P<+(bozoH>7M(`R18hY}{i_*4v@&e3Np^XlcRC0@6KdE$P6q2GlzW z6B|*pmy-iv0Si`I@AKgQy>u_*Zi!D3FzOB$g?`1y&Z&Qk$Zs#1NH6tS)4r_MQ?eXl zj{xLSR+bp!kcj9^=o|DjkcxZ`MXuk?`=La$l-#^UB759SFT-S$-vt>JeuWfxxi-_F zL>9#wm_2nag5cbS2UY^A_LfNvwf|7ch9_T}6I)pC^SoM%zAkUc)};*#e21{fkQ|*x z^4jD0X+1)j+~{q0upCTRQl2_yhpIaSW@`QfnR+t`S>vE1PDg&=gWB{$Lx}iHNf@ zfESMV&Bc?C$*FyB&aYwMp+5xcYLO3h)}goGjB(D@E`WDvqiUoGv{sL`ka96k)RZ0PM(xxr>PD! z6`DpE7rGjMZ^NfHBgxXfhm}RTELr&zwVVb@AkF{ZJEus%;+Ay%uXPe#%YF@D%x2W_ z4@xr{xIV-40ola5^CZ{O33wxOjc4|I_k&`0Q)8@l?>nSRg3WqMQ6FJsKJu~|WTQrU0D za9O7+D*cJ#iB>&V!QZ+B(N7mFK1w5^TbiNLZ>~dW_v8+HhsStE(zaD}<+QQEwo@@v zC{}LE!KuSlA{N{aXEtO>8S|q^_=oo>|{N3BXgT1sWIn z-QYxvKi?-|UR1gbo+_85%A%lZN^uZv;gt>=S>I}hibAUaTp;-4AbcHeP03ru)9yW1 zm{Xe;c4O*c0zHUC@KHiwd7)I}pr$ zdyQll*S%|v2nopOra6X;xS`Ipr%jwbQl^jhmJ58EF)1^LxXI9vf2OP26ro~4=qe4u z2?J!=SlN#`3riM9_rhc)Du}j>=>N{5>+rHr~-)>sQNL0n0c|y;!CHd0~Ov%$ewOb-Api!=}Q2Nd% zcD6n7c!vwKmcNLM43P>m`*^?CX^?RBI_H!GwP7tz6>OX@tIvTg|9d{}lSn^exa+FN z$?Se|G=n%gq*?LipaZjQX9pZH%59=prJeN;;w^`lr0Mj|56EKk&Jr}=s9zUul7~Vg zmp;@K%H)R*qrMCI8wtAxAt%s~PcgmpOvsq@^X*3Ga*oJe>_^5j4Fupn#MHD^}Zy{7N;q(CoOW?L7ApUKwe{~*md&+`3n2srbr;w zryoe_N52;x(Xvagt_0tdty;slq8&%@ECllK7E9k^oV0R->adjb*+U*nMjqSLWMqh1 z$;4AL7`7Qnvc)3rLmaysXL4@xMe_F=-Xi*|i5RCeSn!D8x#+ z4QWds_^xr&0x35(eYfARUjdD3%+2B_4ao}gb6}sAwlGwN>O4f#o|{g6?6J*Z{9&ve z&IM4ikri(x(XMTOU6zt)ZF6ka2Cmg5OEQgNgp6&$x)42L27ybaid?d6Bf0yc+`~dc zz+fd*=Da4e(CK9gQ1yQ3xc;=!7{kJ^_(9HuQ0=2YlvRaHjxiZ68(70}B5+muw~x$g zFw!zfq`VlnUi0SI;ii0k75B`%rcHl_DHoWf=aq=$L+v_1?-CC2I{#>7dX-(4%o&?~ zAPKKX0raQCeQkrr5YaO^J3crNo+y*73m2;gC$^5jkQ?n%51!Wdg2jFh!_{mOa6Kwh zCCMBmAtR;cr+l$xXSfD;RH1n-zJoV+NeuvHK}FB;=GV4IV5duxev+)(B>;> z7o1U^*t?jUS=9o)-T8Lm52<4+dT%pCRaYgxUty`jl;TG!-9wQp&L}jIzN|?Djqm4^ z^zWn*>(OuJ^lCAYo<(X-8@kuwi%GU9$~9Si24QB;3+PJLlLPa-j}4k`7cObd$bG8u zYB?AGEc5_k>j@+P)t0`?YCXi(2Rww4813r2HZKy9y}<99f#Vn4RO~Syh2Y+HZZ;d@aP& z0ML9mQfWpH5RG8$*vfQBYXQTt0nXF?oK1|^C=isLolyHOHsWYnL{;onU7!0P{(e5- z-o4Ooke^m|t`G`5nH4RAn9zX_hHKz%5N4)v!xe(B(S8Q6q>gleBhmA?pm;u7#Mjb6 zUV~%QU=)0ZvteX8H=BUUjPi9aT8JjBS&Zhayelmiqrr;=Pzx~0>cPXN5E!Ldzm0z0 zH_`*n~Kok<`b&i1ZBAhmGgTt2U;r!$V_-T^y z3t$p2&0zNQRz}Tt5qu^KXQZg*o(}{u?qYc861?U-F@Fs%Rda=5*iOLzumWq*3W+9> z^J447ymsxf-&-3z$A}UyIqI3Utcq}IeX8(sum@yN)tqpx@TQr%hhEwmnzqZN( z%LkuJr>9aH*7t{eYyPQ$ZJfgNY;+iPJKlpILxST&xqYrlcdMwZ@o9dQ=1RA{(ma@^ zbB_`o-5c}X0f51jz2nBTiUN1>njU=rmsWm*uE-vl8XgR)ZzBW&XHa^IM!OIke=Ra6 zgfmO@X@W#3WHh)lxUaGk=N>Pz-kQqY0rF#Gg1xh{>`fu1f{I`s$OFlpHi4YpnwFt* zEVby3a>D6f#y&_{P1h%0Hl(7fPBR+kp9yMMj~kihBqk+Sk#&Kc1c?N%(g>O zb;Q+QEL&nX6|Z-yT({*7%CGeDW{rptiwD%p9x{V>$DFYKYR?hE?xvTNQP$v&t8;8bhGnEOtmrjF9IF;ssWP|76`?I}nde=G#8*1LJgkpU{`w zsDOCo-$9}&=iY-tm>T5P@jU0JnRg!Tu*kd%(zq{Mgds?7j%rqgfKM$m`lYx|Htios7 zX?}G8uhrDkX@dIEtaRBCICxyeZb2aqyZ6VY;u%L^bvP{D!Jv{OtnR{orFo_z#oOk3 zk6E2=Asm}0*8hers3)BRAFI&u$7GpQX;vn2mE-YGsQ=&`O16#vl{Gn_T`H{uEl^LS z+@X~1QSQYAOJxAjm^|VQcBNn|Q9j0A6D0Z2G!g9*gb#4~z-V5!8s?Z(nyV5+E?Rhd zN_svYP)f98o$weQ@nm=?)@K-}DQH?Z;`~9ZXJApu0&rBth?>kh0!mq6x_Vj=IKbT| z9!0d$HgEz$e-w?*6_gp4idc^R1Cw6gbzD-N8x! zl%MjIdA{!9nn7!Y$8w~tICWBs_<85*jid(*-=os|M7x$=!i}y=k`Zdi@p}w3K=)Zt z)Feo`;i-<_^MuM$!9Fg14dr+eu8>Iz;2H>>vAnKX?Y#!p!krQp*%ZKTDljVDSVGVB zo-b=uUe@cWj(PPFd-{a3Bz+wdSd@O~WeIxC{!P=mhM=7Io~W*cq)y zi}Q^!2~MV{?g+ckt`X?~>9s3fbdhoqYKf23!jUJz9`k?!8|3}j6AtW3VZViZX05Fl zPNZdQ(*Mzl7|=xx&Anvmc6kvYLA>MF=blifcg}*O?S+dPnjYM?YlA6+13H>1hng zuh~ksZ+RRBO}Jy7liyFYb1}5_56j{E4~{6g>npPAYMt2>*aWibUTn)Sg0u8V5FucM zKn=3Ze@D3s6?>U7RjwB+vr?O$~v7q}ym@xz9I!BW5d7fr-vm0XGLQ3xCo(|5AZ69SM&QAZbOG17g zd~x-Iw9H45PJgkOz?2gJG_!8sEW61zT`gmwyKv8T^_h;)cU?&?Be*c~eTcEhP=OfL z{VCz=+Wud1&2Wmqn12#I+kdAi^Y@);#bWPNIoLMjbn9H~z@Zu4&lcEn$;fH!$nuFU zaz%!XXr>*8R6{OtVX#+XF3APO+yq)8LTsW<}8tTeBAp0UC}g(7NbJPF$2L zD2KLn;nNqs{`MVlM$CwdRM>wtKMX9EGa&>x7vsiU(&H^CTIpebt<^s zDOJSZW5Q6FmvC%}iX3Jj>Zm?~0#!TD;3jZ};v*!8q>a{E-#|-n6QY`3X=axLv(1*# zn^c$`omlM4lXq6>_rbfDzH)3bE1}d-!%Nn_=FG)}Fw4gvTJevRDSHMc_c<_q=xalg z2yj+#rlCeY_F+9>=}2XMwoSrmT%)?DCeG$nq_Fi7@@5%zVimU8NuMmEeW;hM(BMRWS=9OPZ3A4f0a6`dm~&V!&mg(O802W z%JoyV>{)6l$YS^(eT2t`p*fO|l*GJGW+B&1;AV}G^tznsaI?(PS==3J?XoHoYGh6+ zzCk8Q;77XaqI}0l8);5(sw1|nc8Ts-X7+=bC#R?VbazH6DA~rfgCbVr@&#!8^O2!J z3*}Lm@={KX(}yn@5RQ-q4QFG_jrJUe=x=3=`N^`38hl$&s(|Ym9Fl*~j4yK$Rdr6^ zjXECpp=?8JxS(4|w|H21?&F;C)$QCpdxFx5@YT3&E`Rr%9B;ZikX^?hWU_Y6+NLj( z_^QpwmY5a`qtC!QgxxRK8M6Kr&QL9kOPP zBGq~B{XM?pJ9-0ONtSQ>*V0$nypj4P@CYoUk4KznTcf{`;%ilz7%gargXwB+3kCz_ zF$F>+&Yz*$&shAvongCxH(ANg@5@m*YasU$#Q2_rY1O|aHBq~~)cN+e5A)Y^lJU

GCN-Q4GfslZY#Tis9+>i73L*%(|Ead&T%I&GM*C+^_0&+X?k; z9Ge6Ruzf$bB!OFxL#>GuPMh0+G7rfIv_adM0VWl>)%d^1N-*5d0;q^s5LTgx!`|dx z4up-;HilyUkPH%8bC=I#y;GQN!459kwtKZ!+qP}nwr$(CZF9A4+qP}<_TKxPdmrx8 z$jC^gl2mzhGlFg&1eRy9+os!-EL9d&&oen5I62*hw z0#_ow3+9|eHL-Phy#V(H*5KxhS8`=+hN;K0vDOf95;^RA$b<#vBB94~$F;_9`cimI zg2BKqLZbtWKALd$Z_HX3+aDTx#FcT#<8SK(dq~+btsyb)5Imz!F$$##_Oj1ycVnJS6jJv zE{+Uu2V)^kj?d9G{0KC6l*CNShCWlxdGl#-q1g7RB~*Y~A@Z(QZxS}6^g&>#RpZQ0 z{}jBd&gQh4)S=hERYm@kY(p{+sKjx~gzUDnmp=#>y|pc0e@yFyd}aT=je`1XxcI06 zlbxYv=bXpf(P*blErNq%3i3VOML>AwI)d%&;|hW6lT`$HX5dm$Cl%WC#;0ht+w*

l_c=K!*^0PxpHk&&;5wSRj_RD%G}3A>98W~RyPlUhuqyb7?1+ne7m1)N4- zh^shUMgkwKZ$ndL)q`Mt;%y(5`PB;%`?1OyG#DrCuJ7$+9-pXLa<})$L36YvZCEjH zWwypjUo}Hm#Mz@QA4%#|s3H9eg_A5PH-tkJ!0HD+0mh9a;2Ab30LbbCVw5?6o zgJD1NgbPBEN|hgG*dpz(&6`=1xg$8et}u*%N~ef}<6SWJyJ5svxpO`eG#o}$V!Adag_J0+W0Z2R%)=JrAN zRl#k^Y4Dh+g#E&Mpfr7BU#1h%`|}DoNIraXa;{Of#=hLKTm1ktfHbQ|n_|lUmm<GgSwo@rt(ifmOZ*5GI50 zj<8{qF6fk17Q>P7RANxwvJeG4em)CYeFTO&q@v)7Pp%2EVe0vAZ0P}pOit#CdLjJ4 z-u3Ynq7eLH)RW|r0;w0xy!>{`wG&gMm@CIpw!{4GN}=<|aOA|nup$=%RHD}kaMyZ` zA4_(0%`ZZSbRjHNi@Q%$SU#v#PU#_CPu`#9wue~|UkTK9iM4*%tzC7ez$dqGbXW~> zu}%!XW0!q;i6JGeV;e*~k`QzoCC+x)2vi>+)}!D+UdX3pn6i&{b25)kvlFT-c=*(U z9hhZLvT0!jvft>Su9NW{d#$SuLzBmN!X=mIdONZkyXCuoCr2;0h|Zo%ag4;#^z*w{;dtbzK1c_1nI38Ug{CF=IFV znAuOvMtJbxSm%s_PwQGIEe=K4yGeUU(7aEgM0gc`U_VJd`9PcOLTjY_8Tp8K5={Mh zAsH8y9Q>&sb#{4=VeXa~)Tp=40-{|m^xM9mfdOzy4Js7zx-?wzBs6*;!~73%WbFPT zWM_qM@jSyB8X=rie+YG=eoq7+J?mHT0ZW<1?S~Hw>hwHmqV0rclT0$Hj14mW^w%i9 zDC#1o)!_5ju?JGS1#D0J*f;6Y#~e1nbpKhfVwxDq@DKzfrFIa35w(@}kS7vJI7^#9 zPS6d{9Ue2%t?nvK4A+CksIuEcj}d&XL{6#K+>1<2NOFeCrWfTb9{`LMrK97DBorQB zYdj)YM*#W?>&hSFYb{Ucn9E>(cOY-|S{xW2i@1yf%bi#=P`lHMTxNfVyo_&A`wUZP3zV2Z5M>bXET16AjGIV^cRNH>VQ>P!u>2m=R@N`FLH zJ{1@{7;M1$@8bR0U?n?4fEP|B`n#eR#;in1z&(!=(WRzlYcw(!C4eA6zJ&5)l(={5 z3|w7^hJ7s*kD4i7A_yljS%aU8<;szF1Q^Y8S$u<|h6(Y6zr(w%M=ZOfE7xsKyK3 z7rIHi`+Ph3=aKxe2+-J>vP|7GwAmANOcty4tAKz_OCN-Na=or`P_X4OyR1c8r?bda;3* zZr_;!DZpq0HEO?SU-V1;c`=p0DAr*0CbvlbD{O_eNq!#^D?4#VH0+nvp_A(pP6s!W zSDPlzY)@rvaJ{r^YQGl@H#k z^V8cGD^|2*++uYQrfLq#>NJMt_180JFZsp;bV|K!25;iSFhK9lZ<>`L1s8{^+FGa) zCHmoLP*%_1o$z)UFxL+{8P^Ys%F~lMAWPJ_cWW`U@B^MSY=IGSoZi<3*zL6mRv${? znit2{96|i}Nnv?PdDqi?+a0%_bj`$g&Ezdq%7->L{2#p7eHsUEw#ji3`C~OW!?fmc zwU)HvBqa2ndHUqF$tmNorl7M_(R&O`4RePygUeqagAwr`cbKFL;#f$6) zECS_>l5twvD8e-_O~I!aojaT+#@8w((>9SSDb#A)ANRRlXj`U_ydb5IB zX+J9*&L{sL>?dp+*M0Tr2$W3tu|nB0(#f%9vAgbIU)zc-Ng+9>&rDaEtD&Eh^wu&( zHc)dIt1^}L&Z-6QVotL&g0`9B1WU?cRi%G& z?Hyb9!t}dr)FYq6yhqfd*fn*Ztvv9ESUo`Aw8)p{@4Qtx9j zVHz|-03(5$41A4~a#{18j<`%?i*yt`IfIalMpZ2JwMl+Fh_riZcusb*%2?J!dXEWaMA>4{MmKS85U73{gd*S(zr{sy5L%H7{d!T~vZ8uHc)o(88P^EKiEs2s}czOVaOCM(QBWQ>%F) z)TZGM$bBK+d!K^kZ}OH~{VLGcLSLfxGL)!5r@4sPlnRenIixTxqCe3uXn7+i31o)n z@wg2uTb+#fsX2>)GRsHr7`UBH6VmHZ-y4CiHAE|0+~`KVksHQTBl$SZ`;nYqXZ%va z#Q)wb*U^|Hm&{h+#&|nBStKWN))w^BvvI9abB!uGu;{{=_{dA+a}-?LJc2JhNz9Q# z16o0Rk*-6ftlB)_&!K&`Nkc$vXPbQvJIl)9Te~F3f(YyA&@5OncQXm!C&}?8A2M`q zfidu!YwZLI2biWHy~3{Vm$#e!Dj(71lpTH{MDwlLw>lKpq>jhO>;>0W*8G$&O$MRu z{lY3q6(8UQpFDOU&+Sn%NWl8(J`IlG&l$mGFvT6f0Unsdht4)uNhq*_%u@H5(h?2& z2NQTh$@2#sZWbH?h>o?V@H)MHis@L3Vmwf@!>zvNFmcyRSmhr$ma!gFlj{9-P`(Dt zv$guwnO;hai%*mzK!d6Og35x7*MUgRP*o>8B+qbd-Z>yFpAVQ^P?V9>)s}SGDDpyx;$Q6s8Ib1^8y55$l8D8-H$n_t+njM(Me5ww z1unGMIvS{j$KCm$L+q9seR043@SYwss5G~6g2tjfixj^g@o;mBmHEkSwC~0Zn0=bp zofzBQ9GQ8!ccc&q$)j*2R8pIliu;tvvgh^u zd#UiW{evwASMko`&B1Pg_X_6N?sPN00w3*7Lcwogl_dW-^A}z0cWrHcnI}G?-Qxu2 z*jUqJjwb>ei|^lh7F()i1HErDRp1wt1t&A0`)@UzrX6OEXn(tF0D|B&u=nJ^N4+d^-PFBP`1U|ao`@ub6%#jN$7<&uCNEh z%}dew)6@leoWY`yk8Md@g}zGvItLko)`hWuxYN943iPxa3=asRVu4h(?3~VN1Vanh zyNb?gL2owTL1ap7s8)}=!0 z{~rDU1+anbTv8X%!D-nxUtdojx8J#Lhr_bMAiSTwuZ2ZyOGzz4LTGek6sU!)SOufp z5M`9z2ORlMkr)EzzE7gVOv!60{&6{5p#T=-V#}bMh=@cXYs>eK)mlDy+j-1%oSv9Q zMgbriY0yC?cEGAVx~J@f)u3RiLrRTLuwV(iYVe+iDz!bXb|-Fd)c`C$){On9;7oxJ|)-x8l-v$o+1~>!# zmT}g|hvp;-d*J(^>0=idz*|vq+vx0v#sY&zsZ(FZ#S6m#><$S8DNsZnqFPK5d&h0o}vKef<;OQ7567v*dyy#D&T1mIpUBPP9AQPwrW`% z_wd8bh}ajh2;A@A5B%BINz2iMQELA*4mRu4(dncYwFArr3ct(5ka;WXq~FeD+6NexE*p*JSDc;O`x;%<7-T+L_y@XkKhoK~?$i4X>VNIVe|)rMGZY(X14U zW9Dye3i$Vqlc^c;g}e4x65BqcO^;y%m9%Bk8*pX}`$P@)I`EypJ@3)<8=7oZ0Qpa#nh_8yuXOhfGM7y(l z9O4R1Wt$4%a10GYI45a?n;SObCxO1p@P2w?vwkIl3s1d$q66{}kBfS=5T5MN=p-g- z;6^3iCYk&}*nM>@yy;(c-B-3xzYKGoN6;{}|Aolpp2p&BT_Ptg=}vL3by)};@ie*2 zi6SIs^L6Qw9P4jIhBT3u;!b9wOz0JLu+10QrMtkWp;3i8yVA%ni=NrE|4ie%_0^*s z%N`otAW2#jZD-H4nJG5SF`(KSmRb?>vZrlvVPNL8GrwEKt-jHQr`i5PclZDVYt>@T zUF!f*DhDbopTKQX6*wire76Zz6_2s~BwZ-vkf7bF4w$1rsH#?&F%6&}&cEVfEj&3h zC@!w-@6GXx1V_R8%tkJ8n9Z(pLuufS=^3W zGW}Y9s6HzL@1swL6{|J@7!UEj=7wi&#)#EHYS)#YJzDQ8fapLIKBWlo1dl~6@q}*# zETo^0id^eYigR96*1vJf~E(rlca+I*=6{5%h#g4imsfbwhspcIoM2e6_oZ)O%K7OD;h}N%leW z6T5ZV;tIRhu8-+kB!O!iCIM;|b55F|cea+tGk1Cyb|*>-nhW-w0|=78Z@1kyts$oq z0J9B6^Kt1L1(7$Oa|gVog1XdFaRJY97UU|i6xiY1chuA0NM@aw>(z@5cT5WvtB5+ z5l5Waa%jiG$!OxP=p5AR&Jr*iz~n_n*?s1S(xUocXUfXmV-UO+4R<&x%=)UFSL{GU zd#s^St~G4_sCwV*@jTM>4uC`$JeswMWB7WvyiTV+4kL9#rseOH%bvaCHz?fSXM5=! zOoEmsv?u_#PX;SO8t+l|i=35<1l@_%xL2`(&WDpZ%2@K(_` zYn3nH#}%y3Mr*qLu61O&6S_n3m+W4mzB*oBM|$r5Cu`>(oFCP)8S5Q;9ZdH9_z4=W z`sN_7`D)}uUpq&qV04?kY4@?p-u7duAcADcYG!83l%$R39?mUIIhetMl~lKoc}SfK z04d_^k4~$Qm7W2R9f>an{VilrCn%KOrXj^PgEIGuM?0=eyS{rjXF$1|UQQ#Ou?toG zBno*Cg18ALng4K^{f-77{j&tv!px-t-s4}bYjgMq(7ao7GP~#Xx5@2@Q1)?8l{ioH zE8m$`wB_uakqEANahPSzm7tzldsya{H^}E;E;?m^HRiW3OhU$q3K0yXbD2wWJc>Np z{Wz#~ylxFOe9z~&!%2N;RJBKs3kK$S3m{hM$uPbn@jmj$l9 zn3j(it3k@^w}Ok41Xj-nUtdAlR8C1FFlPypLirT0m1DnVOhRxDctRc5Q$3)**g@NU zPe_j6V2?LiL)}Lo;E9XqcwpyIx#C=g2XI|6aT}0gzi@UoAa2h` zT(7v*EKcQ4S-$2i+eUy%$uUR2tJ4}gl7pvqP>t`yDT{vTQ*MuSWpOO2h8>0{OkP>c zhk&OJv?BpKP-P2#4)>bQH|KEjERLE^otH&9<^Qqs(EZ5nuyFwK89eT~)Ymli7ww#0 zRY6D>Xq(9|u8ydw8rm4v2aEHx(GzVEQZsje&;^GR`zp~TJEoV1#THfwC~`;s#qKNv@-?>>kxU{Wp0iPrvS4u4;q<;_bLB zVwjUCB`G>f@B=yKm1Lm<=A$NFr580hdaazt{w~GEAzdU=p+?DDUj>oaw=IS$G*u0R zbGaSee*AWgf+jNE!J1@xRH+}xkl?ms>Cbv;s!gPpN_4V=sGsZTnI)D^InA zjEWhWdiMz>HMZ*$M!7~u0j_@+Lx=YUg{d*Sp6EDC%am?E9Wl7J{okbXj4M+saVzew z76(=kr~(7hy9Bk&f*WN(g-FWt5y;=6b%umOX99bpm}T^B*21`8?oo7;agIn71gN2f zNcv%{iP|!>9);q;E);<*R&r7c-CN{gO|^N78VC~|9u(H_ffW^?awR2ZITf3X3-rX8 z5O~+CF_wDLn0h;uJpJ_6O^@A1cB(BWAh5zS{R2clPW}4WW=o0GwPAYf3)IuAG&V_A z(E62?ia@=xC3-XcjemZN^v;EzKK?D2WI$n^X?&_5ZSszp&GK{ZD>67F5hmhbZHC#R zC zCCXtzrp!EtGEsVd>Re=1I>ryDk2yF7Q!TjqLE3nQ6ZAI}#OMd$G71~)yDf?@$M1Dr z7|K;yezp6QT;TNT>Gr8632HD5k+2wtv*53ewK~x2_alV#w_EH*aCTW0rWNc52+ukg z0AX@OeJS8zF3!UsF_8g;aXcHsgI9gMg+p(ZpNxRLZE36bNvyV5Z$&h>v8oMz2E7R~R2mxj%+#+!RL_B1z%V<^vO!8s2OcaEi2|C2v2NI-&9h zhkD3nt)^D+XGxv8ZacW zQzalNcH&}jY`x9HWmlPjWVgwDYfm&zB20*JA5X=Oc)9xDs>e-SA6!`>iWX}-Mrz~X z7Aj()pvMn!N!pczIr9Py$W7l^mz-mc%5z9h2Q9Va&J%TUV{||#_dH1X-cq48Uqwg@ zTy+|w4?z;wdpM#sBnLjUa2S`IvAplks()PzII+_@+jsW{DZ23&6>_#)ien4L>-NVO z+F}!LLm2?i$~$XdK$ROjC4@C}YJvBQnZXIlc-sRCwA1E-&^MWkv2~?Tn_*P*Pe3!- zIsn76bnw?Tfj(|!G)B!(`C;If$1V87&jHl$5<=4Ei32&d1Hm(b%`Z`-$j3S*%Ewk( zr50XQvMu)U5tArTJ&=8Ldod*K)8o-Ed48&>XaeKK5;KtsnMOFmlQcXPC>rCD0LU}R zrTov@*disTik^*g)Vq4U<=GuAF3Lnn@Sg?z9YjdF1T1wYbbn=`LcX+b1Llz9)&N@j zQ>gc-FU$~@4;uN*YHG?ymV6H_mx7}w@KG1U@*2^BJl%)lpugd39tQ?s&33VbpFnx2 zN(jeioIp!Y++^#!T_^}!qc)5$A+3JX$pbk_rum(;i0w^7{p>|{Lf}%1Y^zw@&+ceV z?6ghg$TJSng@>w#x8rQpN4;z&{hg|3?H1t{=DlXZL{&zpPrAwf%pIug8KWlGrqNzc?47l(IF<1NtUW+;;@z8M6k(IN+rGO)N{`dfoxtdi^q`Y;d*5 z?P1RbB#y%~tA$&39(;2bKH^&&UX#ZlF}q8`~fwu&Ig>RjdXV4>=akfUI;` zCW~fYPDY2`dm`$L={QOq;a#mumvj%Rd=Y(m*dFo?to>(TEGT(dZ2X}UO;FU0v_=&) z_l+(y`_p1rq+!2t1{t@iA&F`$CP$NL{}yJ&=8vv$&9(?U z!_;qoiL~^hn>gHXdqZY3DN5K4nw_jdA?J72#CRcwiMFL4OQ=6odFtMNgKTuWhK25ZrPN5UGjZsaVx zgwtSJn=HcmY4NmmsM063%4n{7E|a1FMKosvi5E<4K13oCU;ehG^uwx0opWt?T_8zZ zdf52wHN!M-VUPse0l5d$VdiCl{SWpH6TOM!oyGa)_Tne-nBd%V%hqXqd+@tXhp>Yi z&nXYhUoJI%I{c!5LSXn&$eDb%@Jq>UtUKNb5Ue-iq#SYqF)EiM+))qQ2jj%Bvh~?X<+>;Yee~iULbq*OhB0 zzJ`8vfFZa8u$DvMOrC$7(>oGBfHJoSe-o$E-$miW57y5r3KK+WqKdHFlxS6>raDNj zQZct%r~5~(9!Q^fYpK{K9R$A~kPi6)yW!suA4yx^amc9w!m>Ze{?w)#)p*_ry_Jbb zHC1b(fZ0&wOKJc94Oy31o-vNBL@*ERnEF<5F_=cl^O;8`dQG&B4H0}emGj=viPZiD z>$OQGzPygU;V$yFHj@5T?jtO>%aDCl1?w)nq+IOpIY(*$6=S5Y0j?p_5 zCnDS$^8T@KTg8{h@=pWW1t;(#-X?)!vSC=asKZpUZpA+(&o9wBwXlMqG=4tO!hqDa z@?Fvg=j@=ilW=T|TFkG%{WKN!*d5T5~x=6T!lMkCj+Q80Fh*YT#Yb5n_-jqoG=^o_BwFcZ| zn4QeSNx3FB18*n4Ue}YjjCp)C6imT34$4TZUVF@^nt-AJ8Z;Ctw&`OK4{;5VDf3BF z>DURkvj$+}9H<5`=@R}S)3W9{u{?$SW;H*!e^=~!i!#+?ZB$bzENckqr|hDe_bdXT zIA{WR!cMYALR*b2S{DqXX_<~C!?P_ z_W5wXUUowORNn^~Bw(=q3{piXW-7LP%;2Gkjv**!;-W*N99Q6oE_UL02b1N_mSE^h z{~7lMjdnh*u$1LAh#>Xd^9q;INdHEHG^r|!avg~2jdl}K56w2X00_c=R=QhxL&+TR z^s5DpQ&_Q4%B3NdR_c63`OLoTSav#jC;tR~pMfFy_rNdzyxu$Kk7^Z;ZBA`>I_<3l z63sfa0JK>j6V{c4NS2%oP(E*N^+Du722!QezBsB@l^U_m|9cHG@cd41?JU)-lv_iWet(aNiG$j$Rv{D zp4qM=;Mw7eE8!`Dd3W@FGmcUY${^oOyk8l{O7#MB!k3dWD4MJ0(_l|x^$Jx^pWd)~)FaiAA>rmynb z2slbWOl}CiClvL*41c3eM%&d(UZ#EBOJ;oNyLKN@jul5*u;v$@RV#_7tkz2arr>(g zgE}xeRa5PkKb0H_NeX1Tf>$6S6lko}pb37yPJrPABj1XC(auuWzA9-_kh6x`fLQ$M z*6&zssnLPbG%9UzkdpOA&urT+BE|;6te$q#6ON>q0xan{l_L4?VTYOOj>}dj&jVEG zM3JnU{2g|4M04sxQ*(Oy%HN(l-*Oi1(xJ?UdCL4Lx)Vou^!;>Gf~K1QQe|@BwIr3M z9n&%8$(%SF$isArZxaYXDvR-1N%+YU0oK1(nLWLz<>16jVH)9EJWva{q|DG;q?ivs z)y-TN=_C-&`2&Hwsg%0L24<&qkU&2FRf6r-9A}|EXx9DfN#GGsLpIstb(u>#8CY!7{g9yP46*Z23`s8 zn#DAPS3!D9P=CJ89j$xu&qr<-;i7q-`@IB`Y2VHScoZ10u1hsTRKN2K3nv(f4CUpI zRk@tV%%Y}BkprSWPgNS6=v8fnHHES@uoI@dZ_II<&4g%YSD}#-UlSfjP6BvAOCz?Ue@!oL%FI5lUpuVp9RkNo0fTx)O}^Zd zcpR`^=E#f~A|q+;OzpTRc;Gjt!U}fPy@kUT)f_$Mp zDX%v3*VeFBi1p1*U2qVwtM$3{{BHnFTRNQ5@q7MOVNNTi{%2=DpfYspwcnpt;`qZsuEE}58{xvbEuII(jdA?l z5y9c$*MGaj&?Gjid_-rrSK?TJC^0r|{PkW(U}gKJ8?PdBTE8u&gcK~-6yiV*cEMPp zMFy>qfvMSnH&{)>I7wgPqg-1pa_TfrMwADwvR(Wb*)jrU(hLA7$A#>3V{8^{|LQS? z+i<*v9tdfh1uMCE+$jzd!xpBfD~EttGEzgXCSYf~58}xk7M-MLs~vuh;cQ-KCLG<9 z%Ir(|K&}U*TcP5Hs!~=xrXmFwk^=X;8C1%d8jQ;YqnyNePb>GDXsOk9?YB2#N?>>{#o;IC{~*+X)C%8yTfR=XM7zAirJ& z*8v*R3{m|WmcJHYRl;9!L&`YnUT3Cp@MwsdA*;fj9M|2aaZmpEzx zl_e$28r|q+lZ^A#H>*Q5u;@D5))jYQJ5R4$Q|=q2`6(wAQeTr9F4V^A^nDyTCTGmS zO{3dJd+~1kt=;+txJSE(p(o0n{l;(m50Dx}?Gr+ahK;|mDDzb6 zjxuO!(b}{?&vz5jTEEJq0E2%9X#m3^uXI{CdjZ+1NqSY)3D*#jYX+`(@{=Ec>kTEE zys7^cK0kRu@_B!xZ-OC&#%2&v>}6_*@>U|-W%NhPS!i4V%VU}HVn#0A?E3fHt9d{% zMZh^d@YyNm!^l}X&tI_I6RIQlt|{-chhz>>uoeXl&<9S)pP>)o6>`Ppal93103<#` zM1*jiFB*64QeXn>92fkDDGc4kzMXKum$`wMcj(P1 z3&&03&1)Aqp6zLP zD$@}*IiJFYZpRXYC?zK=Jp0+DTVs8Pdx}wC`mVJhOxc4A@Yd}2;l9jtK1`H*n@qTizV~g~yd|fk6 zTVb)9>se+PG_~VXB6rRV^P@icQ^c?`!nnBihv_LCF-&@ThTJUpnX%u{wdnaK@?%E3 z^00|_wK>;-xtNV`o~NR}o~nQ7%V`%idmNWXrYq+g&;i98>e3hGqANKyqV7E$2)G;l z{F*p->{eHXCzdJ0^yKmQHqIHVlkKe0HtYDFCan@-%w0DB+4opo{&fgrOxuPmQJs%` zWhQ~eW0W2$97>&Q5ZjOK4>oLDXC-*tPwG77CUvl={xb|#(g+BDi8vmt`j5VC7G2Ys zkP{u<4sMxPbwUiD;dO@!3GBCrF;yUYf6YJSMlMS0cvS({sD8nh1-KhJG_;LsBoC%F zHNd(m7&^oES&M1hhD^A=s7DNQt9VK;wFJ*WR7;1?k4z0Q67+%!Kn47)tRh0^`E618 zDTZm}@2(0*{Q=S*bC&c0Y!*4}2`KKv85iaEHzR=@jCg7o3QyJO#SDbi^+udgl! zFfslXCrV0Rw11{aIpRO^XeJPQOx!q0CAp)-=$Lp6^oq^s=eX_EyEO0D@Vg+01`nCc zW1EOTkLKFmB9R@~b%4hxT>gYlnhy3xR(8IpvoID)4HCFsc%O;Z7g!B9mGo`LqBLVW zkmO+Zj?#dGqaMycq$tutv>|I&21&*>D;!4{-n@5NpH{^B`fAoUa@-S=8CPKy@xhp~ zP9jRiD9%}bFi`bCX-LS24*P1$H7-iY9SH5GeT}e0+9(w{$@4^S-%-2~SEsV;W?=uR zh}hAOohom5w=Uo5n5x%`wIv3Y;7j!wv5u!ji3ry}Z(bSBuvtwibIvjQ!F>AXMr!J@ zU{sBt--3kC=l!us$zRw7@8-&Fmy$ger(O(%I0k|eRf8KoAlO;?T%0;9l-{1dIC1-t z++;NpTT+n-!C?Z44^FI_nn~AR?tg{=o>{vy0!vg;4@@m5WUC%#E5R$HWp{m1xv<$c z-gWf0wNB8C7Ccwz;6pyu85@mP*7?n%!m)qh%zK}w+N69?-4?8mOF5EV1$Negwv1@B z8FoW=!9;8&zD+%Ek_Q9fr9h6}3bR14`v5e>Kg;y#1X#fnZPnPELMw!0_)O+vmDGDn z`6gSN2A_!gcTP(BbGU7}U#;u!Ot@Q8jBa_eEIT3>(2aKAw>Zrzf!j(jC z)c|a2V-W)MzZF1LxehzJ!IhiPPGWP_)b0?i_x6$fb5?hVl+;Ojs)7EZUGxQYR+!ZC zRWrcP>zw*2$>3i=wmMo#jw6}6HEhDSfDi|irFl=(OgE4a0SK_P=Djz8M1)ipGW)_k z3_23q*o*Goy!7KHiwO|k_H<_!rhv8d;s>YORQNaUr&_AF9JL5j69>I4M|Pz)Z7y_P zsL}g!HBujPzg5b?av5vWy5S5x?!)a5H3M9yf9Hd<@{#{hy9vKoC1I5B7yW&qXU3jj~~u z%0}6yw`<|(08=?{Ez*&J=vi5si+G2I(FPpLYyq3(&9yu<4)InY8JKRt*&v-Eutnca|UdN}6TW9+FCU+N$A68Am<0IL%jC9&TyFwD4Q06U!gsBmCQ)Ql52NykQ^2Q4$?VO*c%sVJQBX8s>dfMOc)SFLe}7mAK`XVq;Wup^7#JvmKEx0d-V!p zv_%YY?`8@7=}}|wgm52i1qy{n7?BNa}hx~iYTSxK%EFuImOFdggLR# z$ts(h(bxZAxs%-NlwcD|Y<5pKmyfV(-HYs`l8zynjIbk!1k=$2EPpFfPu1D zelg*S0ysQD%~3Ln3CVe4L1Fc=@d}-6J8A}-spCE{zL&{gs#Y|Yd5|-$cyEbq?-;d1OW;B z#d}`S*{tfaORbjV>yo?x_Ew46O`CSfzP%M?z(rgXSvuAMKgyW>!^clrjo|!|+u651 zfu(4#(O4PA?7>%?X}StVp!$x~sZ|RDdIr{?gqUB!Q7Ep$BQ0Ggv(*?2P*q}#Ij447 z=VI>{beNOKV6$7@pVPIm8NR6{^hXa2HP=a}AQpUivqt^)rFBkLsw>cgx!~0~{iCcLk)+=%S9rm*C7*Q#a6Y z5LOdfm)5QsdhzucN;|JW0!ZqT%3ey4(Nzf5SzVXp3p$JN_=q7G(|Pj|yT01nf%JVi z!ep#tqX0d2;UDj+1Z@u``Fl%1y>|N*di9I8aSz=bAU?FpQIfdQnNnZDdGNH!?I)(J zHv*8Q;z%PeDrIz}D~Cw&7CHW%%KV_)JhlD@l|07&Ma;VPP`o2HpulbdwEC{Sk~bug z{O!7$sTf~)w?$s((&&mHs_MhHv)n{^;Z6lr*u=Dnk+rGF50w`xdQ$2FXRg!d^A?#I zcna+XbBZ~kCXv_xpP*xks_Q3}ltinID>N zJPtN`pO2h_mxg8W#|Z{uDQ}jBg)+7=a&&Sq*0+ZJrECo>VA=5K@P4mcT(pW##?~r$ z%yhIOwl+>O`qsv@`~reP!ork-`c~!!4(9*miC~|D#$!z}8KZnu(R=zbrg@26`qu zR%SYFTK@kD{?fF9`gUUf)BK-1wf{r^M}v~Po$-HX{*PVBbUkeTSZA`6< z@#tvzT}=NsJu@9656}Pgll^~wYBDgeX#ZaxJ>CE7yr6@v-GA)*4~K>R*F$y&ZCW{f zhyPek&&2p&f0gtN9BCDQBzSDm!5p}S2 zw)>5&pyF>7T+9uP6+{Jo6(~9A+c?_&N4KH-|NQx{AP*0%w6T%7{{PPm1!G5BX9q)L z$6r-yvIZ8$hEBhfw6T*uGafVRf9L!i`=3?&WsA`N@)-VWhX}(j`9IS|nDN;DOZ^JU zIoKL18arvy$_a_kDjB;u(TZE^n;HxJ?;`lWi@5f$@SiQ(AaaWPUc!* z^l3Knci>^`N#5v)RlV6VMNO;Lqt<*6ykmRdT*2Q`JebclWr&_40Of_fDYBq$Wn}8Hl-eU_?3zDbezqC?RT+aMMYr6Y*P%X4Q--B z#FcoUb^jYr5mCqHjt$^ zXjAnSPBnZy5j*cE0N$ zV=Vde2D@D9b=8Q|e@^45kBe`m$Pm{JoxLow!E1*_9qL|=7TzWWBnub6g2PRkbB=0# zTWl4AQHunK-%-I%OWdL!ak;Xxi8>R(^1X&XR!5XQ6|i=wzl9jOOhy?H%EIaD3U zeZ_ISm5qjV(+Ku=XEh#1D>`%Mhx82GPpu}svPfKi@2sreppn!489k8-fDJ}Ed!dn- zWY4Ml{K=i{alE#?fb<44NR*^|WQAd~l;@Fvcv%0&=d6Z-&ac(pV=`wS@di>{y8mIf ziS$HPLpaIe9bud8zqspJE*&_AZ3)kr;~M?If*neUjQ1#&Ls%gVH|`9$80S!Mzs?J`3y>h79I@katq%qsa8$1V#>rE5kwDM1IzgjoS0H$gua^>J` zseD(?`^O;v&$L9q2g$!UvSsr*(pIw$fGQe4|C z0K*3gN_GR{sT+pj5N4GLB)@o^GKsVGV?y|V1zCT=a45FT+z6-6K#?Af1-bdeLwY~W z?IO{orV)v+AIejw5P?Bm&mqW{ACt1r1b@t*OE@wu9C)x$ zVGIzdmmSGHjIvu#sw>)!2M`4s2hgfVNwCuCttl$23_N>lQ~h2+Cy2ZG!D#!Guhsfw zQj#ZZbi8GsOfEs%m+S57iy-(aZK_|_l9!lQLN{(TRhNqSD#i)(+1cyr{(^P*%WAe!!J$Jv6@ zZej88pA=z3{dM#B=kM*2j3m<{vgoicKr~Z|TzQ(zsRpH;kCbf-PryJk&_om}JHHM~eIesK)h4HjPcuHG(Vt<7)zx=j^AK<<5q*5~&v zczAd`F^4RM;+1Rx2LvuiGS>W>y~{Jf34T*#8#iE|#+{IW9*!*`{yRLoL-YYL!^xPs zK~xN(WozS}t~dJ6SFy|#%>4%)lN?zb8c9>f3ed?V!&y~Q%IzSe6dW~OCH{JfE(6Jr z&R97a>x4gdLF*HC_Gb7{om8CTxG8WAd^d7j1?S+QES6*5Np8HD$+Z zHz%FUT&mGYf&!qIZge@k7JLMMMehhrsSw2gkGw7yjT@!K4B6idtey^DsK<9yp;WZx z)yZzNMUuKubVtttNL0=)^`N$?+&|xyTw^H2~@v@yNhSSZFq(&Wrd0Hxn6qiot@Gc z#f5=DaJBPC*~ouj5_ElcdSCyxPqhv|!!~bn%8fBf)V_|NGh~KFdkZ~sI(8+~J}ixUz|9G0r#h6}y4>x0MN|6R3XbN!B&QN>Zu9zl9Qj{J?)FRu1 zAbbJoHii%TCsYX3>&@GVEHDELv!vBfcDJCG_N}I95U+t)@U~7o48mIr&f zqmyGZ)XS z;3!lt5+dEWLEj`lb#{nzRWw?oOAkY0Vrqu;QR_7(mWFJ}9w=BP6d7{D1q<{-sJC~Q zg0B`v>d(RS$;GVnA1t+>jSD!u&^pYIUn8liio~WK`(I{s%ADE_v}ZsK641}ejcWpQ zYg6iaGg?%9cD-Rn`{oKr&IJMBssPRN8-?2-f_Z4KWsOvD3YlDplDg;^9pHuhP)*zf zi+CM`yWTAj%KH24M7bb=c}}vI(V_*f%q-HmIMZVAk*_93`wq^e2gzjQA38*4wxyWM z&~`z`KilWI*Ko%OEJHRcDzr;!MS zGHcV}0^6S3N>+9_Ts0kNNLx{%c1tCiem^B3fDel-*KwzY0VcDZ7}+CsB?paY6@rA@ z|2+prr1}e8stxmJhGk?s>8uoRUDRJq;#Vi;faLtHnIUVpi{c1eqM6WDcF?oFBVbG%34a!B>fOiheVyb8z2 zsP1*+RVwcEdqN(VrqF|Onz`e>hq5!g8_+SdU(FS{nT`wpkjqAr#L*f%HYaywM22Em zJcL~vJHJSg`c6Y$#`_zRg#fFg(1-hgMHNw1C+E<+20RtIEIENeh6oNZU=4_GnlHW zhTH@U@`Cf{DFJ7Y5U$RK-;j)2oRQY;2`daUgvM^)C24jDe>1XtiE6iDVHb;yU%4!1 zL{o~TXpIs$wNPc`8nVIW<1}V*ngb(a%|+iHjLv-l%+LUN znZEuud7jg#Eh3jaNURRR|PahsR3N$<=kHF6We0-tuqv*PxD3Z40(nF@{*KK{#q#7 z@4NGsE?$qdirPfU3L$tDld~3}N;GUaE_$z@=!i$55dTXPFp*z>3pNvWs&+B0tDpr& z<4=z9_i>~Z4ZPMsNuWqk?gOQ{kq!E742LkqAIm1rR z(PC|d&icXi82Pa+lY}wAZ}%2g@Fai$(UuCBvJ6I@VuNYwY03w>A}=<{R2 Cetk@ zKN>75V_FL zvL5~YzeUc@$^E!zC=ds&xO6C5ou(_MJ&{DP+YDq#xsXV1yB;CpnsO#+qKZ{C zs}MRvcF#?%WuWLsJ2`kAp_-t_no$x}lDp5B8LFRRn=VjE>??3PVpy&N%sID@Z??@b zm8ZohG4rY#Q3=F6x&*BfTHi?nH1P&vUC10sB20iYG#wU*U068b>M>$N>=kR>&?cQz zQ*;#zLsRp+8@!GxeP1fvK6Siqg8ZTOSa^NUds?kfQ>J|-KzY(w?a^b8E2Oy{%u#Un zw=`VIUioT6E5`W0B&%KW*+<4?Wndbm8h)eMfDs`JqjU5U>j=Te9_N>OwT~9pSb>Q! z>HX|vQ*1pOr|6sVu|9MQ5hXI~5Xa}E<1QuKd{K2npUB+{={?0VTawRF6HL6jOTLND z<4nzM^L*2hM<h-*2uf@iNGysPy1F;9QUR3}&!t zG*hU_OH0&ITEqwZP0POEZ?LiNWDxMs?(-}M zi0^?|d^0k|U5=A+`Ofg()}m-Yrmz^E%&Wyy?w!dh6!{d^FzG&zQ=B%gu8CwwYy;W% zRrzrM9xAaOcC2e`8V#_>?^Txy-0cPrLP(YbJWY&S15whF`wM z6Rbct^U0v`QLN!#Y6>d+;_QY_NPi|$zOqiY(hmR&^s6iBx-OaBg#t*Wcw@@*YN|C; zDP8p%l{#4$3Q#O1-R~#CoFwI+nG0(?`s-gM6u_g_j~#+_xREt_C>%=XpB5!`SI zB$eM)Vit7(u}DNTh74jcJYxwt6+lF!MCD-8H&3-2PK<(oVMiu`WCGl(HKfQ#+-J$2 zJfl)TMfFm4?pfOKBaiF4;!`;bLtC89Ek1^rpTz6M^3x?4w|ouxt8 z>N=n>a+%vAnmWDqgEy9hhb2xHg4=LEeP_V&)SBzfHu-~y(2)J4lt1y zbn!hX8;u}w$B3;XyKgm!!NDxsCy~6p);;Hc$1t0kP^ezVjvx!xe{rx>hVf1w>x(cdu{&_Z$g*Kp+yKuI&P0^Kq{4wlxNQ zJ$?We9S+Ki%c%8zKk|NHA{f8SW^G)d<(*a?QE%Iy?$$dOW6=tR5rjeiwbFa$0$fp> zGaD1oPjXeE?<8kduJp5}=lg`7ro+>RIQMIP-)Jn#v+7R09zkjS2<1#O(eAfd9sL#P zPjtZxCQ^P5;7`DYVI{}c{LzXVy52OR=^#hOD?`E6%>*>{dM!%q??w9tF!#3(xHO}ljEZa-k4G1xG%knGq1w8o`x&0$CsCG+;i4+dPmmf~y{it-M@{i7L{TQrL~~viRKXW{vNdi$YY?bt(qq z(JflNMY$d72a>q~>+cc@`&T0Qsb=fl|-4rEp}))m)9TsE0luw`wCeat;4VU;m>q|AXzj7&`wuICr$6`%iGo z&c^sJWZ@6KcXqV+A>p(PjI94?$)7hZ6C(r1KhXb&(*IW){h!R4jevpv-()QB&+Ff@ z@qd77x__hn|9lAx8$B&OI{_mj6D=#_4_*FGJZy__BZN(41r*O81zWRYYSA+uWbwU) zq1ikhBkYw#0G3Kc#2Po!Bd}Ggch;8x0fOVOlp|6xG(LkNI$;y7W7I;i3uFr~lAQvt zMWh(C?ZzzI!ve`tX%h8N?m}dhEFLUpL?|u|KF10|!r;#(7bj%!Mq-jk#W@`0X9=Lp z<)<7w2}SOCA+tTE>OBZNq4R8UzSC$zP^Cs@o3u&B!x`%kNE0&DVDF7Q@XI-Yp+?;3 z_QRNxmM>Jo74)H+=Is$B6IKrg{tTNob3o>dC?crf8-x-WqzI4v^~-)H4b|r{?T9bf zh+-Hf&Z4}+iy#P&D2c`|t}`cX)}u|!4t)Y-U+(+J4HBn$PbqiqG6l1AftVIp#&YmH z9yPLmGBsO$t#;;=CxGv^4`9!d#ne$zH+$ozV&H1AB};*s4B*S#I4-5GJFkMyu$WlA zrVP|D9oA|R&s%}7TnS>7 zF3+>FLo0hMnlgu|$C%nPQ9SVS4R-+P3mAaB=I*W);?pVX!sP=TWGH2(yfU304kZ?y0RwW<-a z3qsxpQ2Sj1%et$yG#7L;I){=Is|90^?<1QC*E`NTmKDDuY*uoP4)|dmZbbJ242^72 z6Ki;sw)eVH?mj!SycrAE57ZSC^`&KQ`tYA2foFaS-Ahhm)O$L~8T6zf$#FQ4QMGpP zD;H3gCpdHF5@JoTUW!8(m=*!Lno}5Ojds~`qI1OFhjQMW*2K@xY4!Nx-#oTYBcKo9 zvev4uoX;9kK>tV<4g@5YcaK{b@^P-bEtz|=MNwg&X0+1IFt*|zR~Bb!y%s>?!C-C44^n(7*Bem|?H~%VTuhh( z(EH10>lK8R$W5^YyLHu=>x>QBt+A{}NaM^p(MnpLL{e+j+*Q>Cn&x`Zb&N1ZZS<4L zYjx2SAwC%vDq|*Er8=S3?L>8P!ai5K2csEiv8+^v03qWxE`nM29<$anmMV!~__bJK z!kXZX`E|u35iMpM(W5em!LM0K@;3(Sg7`d&^royuuuQI)yY}@bm_MsY}cEMfAQ7Cm@}4PAfMg=PQVV;124COd&() z^6m~L-^qk!PPG!Pg5QG3^@tCdoQ0s8j4MXOvvopiXX@g-kHJXx|cVmCgj&;!S3X z@5v6S6|hELOfbT1b+_pruh~#pH3v<{FvGxKDi(iJv}z;*FipoE;$F!>pL z?p#B|O8|VxgPw~+F#nzlI}M`stI3`wFC_`z(*}zB`$Y_8c5~|S7k>j9vvs6IOPZ>@ zo#b}0fK%LT-IPip5&RL&weKxq8ISHR1O0RY@OH4Y*C7Nm02@j>UAG;!Mynb~h2sAE zbwvSqaK!c>%m_P$(a>&29oeW0g=9MB#4U5fW^=#*SlwGex7D5-qy`8e;Cj4H@%!mG zgslJq3rfBe%J`R3Vjo_K$&Q=9TS1O!==PJlBZ;@4%!RztlswcYMi@pz0DX5O`N-f; zQ{4}>2)|A1I9WJ5w|v65jpuI`bZZvi-(T-c=y;@THD?$0-pYga(ujOF|eFpa2j4Bs1C}42B@@3eiT#Uei-+6N#eKz zr$0F5msR6H546)z5U&~Jll9gc`5SI;8v3xErhRte`de~0_@k*Spz^-Ta1G(?wk}W6 z(nMgG=G9r7TPTI!+B$=d$j?0psfb?Ab3gU#;y!_Sxn=j9CdL%j{0vVZ*9;Qzibn}!4 zL9YAaFIM~WN7MaBa-`M(Xw3GO36jYXdc%i$)?a4S?Dcs3OD0d(pEHy5H}CQanRSkm z1klI>@8gl)0kEy1=loGQ?s*U9uY{z$m(MSag(gh@gg<7Kh6IYAk3@_VRNF3=P1=fg z_n)A8$d0v5e-k9#sbqE`FnmC9txM`t8t%QbN9>4q3w}x;D56N!;OKu*+ zII-bLW~r@O+kZUJQVvys$NumdnBh(@N@MKBlgeP5?!aX&?(ZRh$lOlK#h*bU6KehV zY527i`3oGb#Aa5P4QXbiOiPy1MtbKa2Opoy*kcVBE?~v<=my6^!ibU&WROF7!o=?j z#;p-qCZg%dHn@mLhzI9R-}XY)4#>_CteZx6?O8pRq%}2-yY++LqUprIla$FG^Sn_` zxTDyA3jad6#(t!f_qNPs)kTTrW(0f|e{pZsYgBK6tAygc3ecguF-q(OXzZB19cTOZ zwlF)WEyat*5wg5Jl&2Yz1si-*=`%uP$k2(bEX{a~!y#6d`?lQS7&S*YL7|R}=c-(G zG-x^Wn|H?)#$D(kEf1gGU-zz5AhbT)K3Qg@4*CqVzTn0}-v!?RjUdE=cs#ARSae!1 zBsOX@`DU9;4_!PAFfqm08gW$spQQyo>IQk2%-i9oz2<|%DEXNXWMDY^1|=)gCIo6_ z@YGKtDBy14w~4uOTsSulZZncX<75PcgB?w#r5P_1pMYK+1NY>CWl-NVv9^9KCp&{3 zVm`(%oHI+(BipHFzbVvzIRE7 zy=bDo#;vRN7y|t08bPt7S2gjt#J5u88E*Feg2i;XZg|D z|1S9d&w)D2e*xBj*53$OG)T?`F=|E&y2?OVfYhnO8~ zB?awPy7(Wm-@M6&2Qn?A!&Yhrm1d~a>(T1yZDFvCNxEuqmByQ~H6I*r9h1rZu~eIX zFg-hPwH22RJ3EdvB-SWigMgBUg)lSQ721_jVW~WXhOyVUKDI#~MW>84$3bRDe{Bpt zwduTlK5e)YIeaVnmYF=g+lOQMpwU`OCsaC;>$y8}dC|lS{8fsD)LY=sHDhB?0ts8RhlLt0tbrtX zQpH!h2WzubUfLzxG0yuEU;l7cs*@s?F){#gok_v^hZ`l=`zx=^5&^48QI*{!E^9{s zq*JIx@j^`1np{{AM)#AFr;;>ehuZ)LXx(&-2nfy_WPV=-n|^`hJF&m!S5tHC@JT!M8NLdkQ_z%-1c5*af0+{^Q{t)dFhv}vF`Y3a7ayUBm{MW z_U7fgH9H9fZcEZ^2F9j|l_D5CwlFBlDceG-zdm@5y^!IfN$G!>Ef?yxS;iHu<{ip4 zF{JN@DLMnhb^ym+;85*RaCuh)#dQSQA3Lsv9}QpSl!Ves79gw>V*B&JQ$8ld?(}!y zT(+r}m(8*t0)z2FmmwRQfW4|s0)U{Lr?eeRl63PuDKUaKdkr(-P9E@3YI;WzGF!$m z^wdfzr%3b#=k47nodBQXnOBV3k)B}UmID)#;DX=>Wn?cbwrEx-x{=^P^6~C*Z2(|j z`@}C;edgyAd>$1=aV5;`rkuQ^G)cfuL~g}Dq=O2&-Emmu5k=vD)AY-fU$&vm*nKMX z;c(?A3p{Su$x+M^b{{*5!&6^#CqZausfDtD`rz=I=n}Jh9po;NFq}hBEhGA>g~MZG z`0*vg^yFhvtc;}75o2`encM+LqN$BxsD#|Bg4qc-9dV9{D{YQLclQzBk3{k`=qjMq zK$O(RZWNQ|zKv>?Zi#s);2RD>c<0(z%14yLNhe<`%;v^t^-o(!n=r(UcUqCE#U|9` z9w1G$OC}evE+xqcAV16slZOJnr_RZyo&P4~4cKUpey9L6h;K!g7P4f8-66~0oVdYh zPnw6DvZo>>j@6$;$2o-K`@+`XOpVSnCoMP=fEb8oqhl#Cxiwfa|KlbngwRl8BGq?A zNLceR4z-40@}2e0J+|ewd~8a;p%&y1!S?%lZ6(ec7T_x4vMD}`7m}Q2drCKf+U64d zVFYn_(y~Y?l*<0<^TR$oequ>(XXXXkpLpL1g5?`F&3N|mQF)}^$zDqA7 zqM$?}$GdO~nT%gsGo>gtq@atZa!|MsxO-d^Sh@%faICV)a~o#MI_hvifLA*p(8=kQLUE@es?2LV|B7TzPRpmD?1=_wn^X!sDe9Qj zJ1!z@;V;)k_1vs;g}4d*L|_ih1wU^O(F)mOx)^)&=mzSI)$mskdSQ|njh$iT1_PuE zU2ZqUelG2_p@ms-&gXnI)$CjCokXY_j^+d;H`0%n?H;&w`w8*SdA=5wq}a9#AJn%R zK!Nh@vF|=+Z&@Yl(Qu83!|J1NVQoYEE<~Os7W12|ENsJ55q6$C>4S&SPBtK7->?v8 zKEQi6fs=^x>!)?v%}yrCrA*^H0-KE>XpXPqm0X^5cOVl&OD4(`F%swJxL-xLLfhk5 zbf94|WYnpBn~t}CSRk0~h06IBG0B=3w@KTgOvc9XF-wnVm|tq9`GugBx;?QFdB`5Z zo7};sRIbh{QA*x>K}X4T8dY&1MU9^t!x$Hi!uGMecjemjeRhnZ3x3YBVSRC=jZB{EOM%HpHbd+krgRRs_75Bdr8-+d zaxeiS7^FF%jmUK{eIguvtWB@RDHd;7!{JJ9_da|vCG53OP@&a)d^0OFD)YzgU+GSba|^KK|1^#T_=Um0s(BS9R$(#GIh~w3!vJF&_ITd7FBG2;q!9a z5*nT8JX$|#+J$mHt+|_Px=VckP!RE#9?l1O*?olN{V&l+$w%yjwG}0K;xJMDgD|`APK>5+mAls3_96m1nhI!pzNYpmbCw<_Z0$2~OCXmGb_~Xz4tTaRq#Z z^moOi&dT`u9Bs6QDTs?kG>_l@zb5UQ7t6EF2o|kZr=etAv~ojNjYNBD7C0i1y8~}&- zhC5cR>>bH&7_Y_&UG`&SC3Nv7la@|I6u5ts5K<{&F#O`Lkjg_yk7_F}mt}K^o(CQ= zA^%>ilYL6C8=wKftThKens70^sBiPJ?b4DK`{V>gGM}>}j-wp{`9&EasIBff#o7gq3?61RMX<|*6ox1KI1joHLfNZRnZZL-h zXb!NMiYb)h#w3NO+uoh^1rB_`40zGnomw$juUWlJ%LP|15U z!tr@a$M>PQ)L%?Z`!0N_V!`Bz6NKh+MXA2okMxH-78MLUto(FFX*-?&Epmf?fI&M% z2FeH`s!_NfZBHfusjgxdpJBh?CtiE*kYF5%--&NTyja*A@`a8Y9fSQ`T;RKY)(Y*Y z1XY17Ot^*~Xk1L$<;AX~_Cgr^0f^HIgw*VLgjC7td95Ls?93YNIj8kR+SdsCn?g9J z!zDJX!IF5`S+t0#AbX5=b5B%N1iwQw{)NDd%l&|-|0J95;;+QkitX@~Awjg{mk_3E zpowU+*x$}oiUK0t1|088%cP=(@KPCFj!VK>7zf=Il%u>=LnFnB^7?B>w$_sX2xvxU zxcAfkoBN_W{hrz5##WyN@bJv@BuifigMejB08xK3d6k6mqS)GFCUQV zL2Bm;a~N}g%M6(NA23UZ9-P1Zn?rd_3ZA(2>&66YNtF4WrWVonoZb}fUuA3`S$ByL z{5g!6Dwy7$*N`EvD?WE$KCxXVj^6GV=15TiuMcf63`>S^Dfk&h&af4viUr z3ht6G+DE9t{VEC+dy)vD-pAIuDrlA``_w>}n!_-CkiDK-NnD_wc8Cb zcjaUwLs&r-tH|wDdf&YA*AJgJdPPQQ;-X;Jxq2-4*@&M0jip=I|117nFt};U^RQo; ze@|98-7}jTm~1|kXNR275}SkT)#kQSGjiar)&t%Sx`YVHW0AO7icQ z_NDGdXN_kcPD>?AiHE)Ao5!hzP71nPDZ+0HPcVzH%Cbc>_8|_Sn^q@0cTFBCj<-JQ z8F=770Z$?}?32uYp?U^C>r_@L25#$tx$hxygMN-q2RUG5_OX2?f}cByJi)hIf6~~1 z3H2F&l3dvFnc$yf?*}vMA(s|mWd;t(rubQ}i`J)>@PX`R1-l~>co}O}@SDz*sR2^@ zfC9+THVSsViD{yrf^1!)fT8ufN~MVZbQnNV(wmg>dm;QBtm&)tIL|NzSZC<9Wr?@mP%2Ox;+Z9KaQOiq$j^$dbexgOyZjjjqf) zxEv%54Bj~;j%}uZ`pal70Qa8OcvzSb_N zrIr?sdBtYL=5Io2>oCc6Y5jKYXl7YZZZ1wLL92B3tTrBCX( z_2iQiF%`q?dNlv}4veUz0QPUgUDpta9u#LELU@z=0uv*E6N&yNCBk?+*b5!k$+yG= zD_YCQ82;p2XD+nGXzppddUzQh=v=y2L=1j5ttK<_BNU0~vRnUj1zzvRusRNQqcH{H z`u10F#ubexEAuoNYr#;})evsof3b+4t%=_(RQTKWjt=?=#kiu#zH= z3c+(WDKc`Sa$Dmr_aeowkflzNCpG|tJcc(<;+w+!9I_~$M6wgfL$~m=-!%mVCgMh7 zu#E4D=WAI2!=D!|b`d0NngvQ=7DySRvnx3da#|Lx(~-+$ub6F?$Hp)_S})bTbTAmR zUf==nZem4(e4&-0j@Yk_CS)bt541knwO`wMO|uzz#JuwtmuuaXl8}nbP&cGXMlSa} zfP?q8ekoWjm#q`pxtA_(Z`%c)b73eToGz;7hzuap-Z!& z_ba?8ysZ_;Alx_5zSFOnuw2a`$2oDW*d2X{WIfm|WNm#303!R*Qzn26b{0|E_g)A0 z17LW%%uX%Rf{n$-;Iv2o*M(b@9d7zZAo)x-qU4|Y@;Gg2hN(TJAS`ubbgA(T2a~Rf~m4H~z4mG)$GXp(OMyODviB+b4iE9o7?6{6S6A zPF(x3M$EwksgiRET5>8$4YgK4$=9GY7Pr}$3Wm{Q);k#LcjNjyIVDZ2YXUe>u80&e zfiG_cZaetNj)2c(Rx=#q_;D;EMn~|EvJ_kXH$kt}%C~Zox#pZnpjnGFqlYnt@K=V{ ztMIyMh(~L!BP!Ad<`4U z5^e%RC@-nsGU>ff7;X4c<>jva;WIs3iT*Brli#?9kK1NemiV}^c%l?CmVOl zdDK7x;pU65;*3Zp>bxpu$I1u%jo1~eA|Rn>{>Yk{hhT#V+?aGUA4SwsI7}@h`S$i3 zP{nyJ*#97d(CzcBlj-9p^IhGXybfgka2JKo#siw9Ahk~^)LAf@vI2s|m3>xau0GMs|^g2N`fnS|XQ+h?;V}U`xJrW7- z`mEMKXat`K@vnsl1?Gs)M`@SRL%skh%>ivOBx^$D`VHb2>{UnqSkz1)H}g6ZC)~6z z4o9wy7lK~j*(WEH-r>Powuj78<(D;Q0JCG{kd8k!3LkL_L-8np&WSMYM{S;2I_UZ) z26^!@-@s?KW>F)ioC*gqRya|#!EjUNQ&ry>G|hyshd&wbv7uLbMSjctL?#$uUq9rp zG&*=GK%^chLlAmrwLroP#GsdW7dberjysE)6q=8Ab}HDI-?xFaXsFF9u_Tw!)?|SE z0`KLjo+Z+M=cFC402$`e-RfHbr6^9-#ho7pfymi@+>Ex9EFPV-+-^}_%^LpEbCtAkzw+2T zZ)!QG0fL(!?2ik{UrBJ)klik}z0-pOHE9RqEpn6=Y$#NNxe)fGx@;nYpJN^4(;klj zq|?~yZUOzn5NeJfKLlcW-e!SaNA#W~8-i$xsg%EdDT$~axkluW4;6Qze$PUAZNp}{ z#Vn-r4m#x zuv_=a`YUtENVE?MJ{qfjEW44rHu1Y>H9ogGZcx*8jzbRcam&k zj8kbD<=*nlW=J3su=&*Tl`w6YPPBEPZYGkD%OJsEKHYvk;N@VmY|dw$*v6OS(ZI+H z^idcn8K(3L@O}ZnQ;|fMb(b^_8+8+lSFkLnisCqysoPEj7sqBuA9HX1S??#mCULN0 zkH~98e+L03)*^%<{R`=HEP=x-o)p#=1-6|B5n0#r54YlPdlt;wYSMpYH2+W#N*`Tu3Uk(q;m_9r9B z$j(H|%=%yQjTUtT2U0ggdBq-lx^Z$wA?5FN3R-gs*IyATp(YBzi(k=6u~4Az;M)U2 z3+QOyX|8pZVxLf= zjfds~;{m)yGCc-hwITMs=;=>8<8Xnl5%9yeY5lxcZbg{hFei@X?GnP zEJ(Z}dYdJ}aIoMfRuqkAn0?KMD4dEiUZ5IT2uGT8EKqH6fBmd|3b!@VdEUa*0){fPs)S2Pog>bN1w9I6g zi&eR|$5%>AWS}yGnt^&M>?H%u6Xx&HxpNu2qH-`i+aeoe`*Q(uj;FK=K9R$ocMWQ2 zp?7?cVB-Zz|Eu8IM^laCNc)cg0 zwl9>T5l}4{@+NdkYMEg1*{G~xwtt-fXPY@lSwLn0RZWB0tE6gOQw@e~lEEj;o+LCt z@QERwH7%=g1V!|pgfxr$_`$w@wL)Dm|EFDblhG>s>{^%FF%|&wNzqL{w&e5lD25qi zS2bdfoOzK6FmHNc7l;}%6?R?{+pdds0b37mVfZ{vf=?XAJO7T)ycF(TJOUgB8L3QK z1Z~a3EM7Ivb8BLJeeG$O(7CQWRV_7k=HhoUA@630>(ph!;xX=s$gAb_&_u@uLHolD5Tm;jDx3N=FXD@MC2*T9d&_x$L4h?s`v-fb)gd?3rm~8@JN@>2)*mF!WuvL%Lzy%yZ%&# z1y!3U)M{>w$x2=7MIw*fBvyiBIbPHF(( zsaLd_-mVe_`64iA2&i%4--B)7SWsT;%pq%;-cdJM;nqUscXqttjl`xz>&J;*p)u1+ zc$_B6BF8$nkv=~`*}40b^WuOF^N8j*)_i5mh`}vL-@YK!7OY+}yYV28+xM7gz7U}= z6FeapN`XVDaT&A;uh$EGb$*VX9+}o!j2?V6zmD>u{H*}Kd}~ILH$+eUIjccAKDTP?k}ZM<73ptIF7j<`)dd@m@*FUtF1UNy zrXo5MVqXv ze%tCR#Db#xRZ-ar1UEX@k(nf4T_g)(k$Q5js!|ozkwI_7oqj{y-h$=~P|}U@faq&G zA!KgJV{E?Z&jAlsfV4iCiI&DTtea*v0%I+e^Og0~10`^|r>VPiJ%R@Njc8e3a-Gq7 z*M`rC#gv@&f-6_X(`vs))5%CX=~Kxg2!*8;=1 z8LE7ivx=m8$>6VSpOLuP<2i}4ct)ah@b})=C{W(*Ydk>gc6<-${FRQmv=}@L%zAwf zXn-CLf#V7>SVx!I)IG?WuM>oKiAJ60MkVFG^xx2Qw9W0xq?w2ie8IX33Hwi(wh+@wuEcs== zK-nv~SRwkYbY5Ew^!Ewq*+zuDx!h&PU(%1`K@vq0ruG!bn)Pfj4=q9%N&AI7v8tLj zLp4Gf{aI2qlmfzrvuFx>4&OX$=V`CFg!PgBoniokb+*zuss5B@xMDmQYZR@oE4#@( z8rq~SmgvhkW-0YG?;@DR$S#TU3=Mc%U3NsQ=_LK*gSaI9z_@_Gr)sZsR#sbYmuczH z+RnX!TlEHOd*mq@8=pRXOyX7z6B!W= zti7k-BJog_*eFfW$nmtol}i+8<{pjO=mR|hV75U#?nXe$fRj=)RyAVk@^G*%GGO}C z0nv3NkSmERGMm)?nDBFmh`;?*m!eh1BN~fO{Q*n;4oWu$QpJuRXFt}Ro zO+#YHQ}>vCu4vh>bnTHw4rA+yQC)n~Ry$J8`$p*UGe+t833$`O#Iy)cX86W zP`?BdkSvFE;-+89+cy3R)G>|?W?-n>o#DyrBA0L~n&vS|Etx*=F}A2dNrN>tdyPuY zLUFQV6SNRPnj>>93mF;SMxK1)ncKqME3UbDX%`yA7fvv_Cj7|;?4n{{MeBd%}BHMWk38vlX?@`&Ts%qyzAE)CK8-p=) ze8sG@jVG&|f0S_Cn(wP3C!?-uCQRyC7HISpeT zm{6vMnQWY_Mo>1>fkepDRIQrO#DH*nfhb;HVtO!q`?i2*JSWDn-ln^L*UfvMwI=&? zHzgV8E(SdNEB>w4Cro|dc(9Ba^X;Se=>;yZ^7TKMd#51X+D1FO&DFMT+qP}nw!PYR z_iEd=ZQHi(?tks?Px9?ly{S}XA0%h<^qB|Gyzf!hxQ67*@rT}#uS>p^xC`)6-)~Xf zQYVNbD9fJn^b3$gc6nCl1<2-PZ-AGw8NC5C%rLd+i;E=VGZN_$wUvm&J^N_5Efx@4N)RKjF5)t# zDL(dB6ZakAO;0B?YTG@xv*cB(5!qw_p`flc9!ULAA@q^mi(tyPAA@#|O&^FVR0pO2xHh3_*1gw5WXUbTDg=nIF zi@yqh=3T}`QM*3N-u(ik1oEH%ATo1WbXzvn3p5Hf<#D8^)_hcb{C#z8+AJh9t~d*T z*pJgv;o+&a$acoe4<5=@;=2m5iou9dnh0vGQ_am^cY+x=9PIftEjeO*fif)pe+e z(6-3lpx|t!V8hu{akYa>fLLlzsx*W0dTQAQGZDS{&gHLl+3I6a&(284H5;#)sE6i{ z%ll`o8kvP+NjJ5-o5@^cg<>f=Iq(43S^X_%EO6gUHOFyOF(qDHY7Gecmp7@?!N6)Q zEr@|g0@OO;%8r~SNdxhqYUR3SzohvV`L7L9hyl&w)ATDI0TX~V0K}B2$N_#bFe6(@ z9j56@_9F1My+Bn}bG5CE{j(-r=5iDjN=`QHV@2&;jvob4=c6Cd^lBM0w=6!MuytP) zMl$>+-<8O0+c|ZWvU3&R3G}uyqQhz>$1JW$&nf|yo*O^P%Y|Z&BQJByQ=1+PrkGII zJ1ysR*cclCfzQ`WIeisn4_KAn7vnRn$@c>*&0sXen>fb9)A3S1X z@B55lX%&6dI!D4VAL@aPW>6wS{caJEmFn&C?;o7 zsDkKtLX5TP$7_|B)Af$HRCjjFX*r4cc?_yF`HyEEC&L8&`uqC)OC7q0g94BX2V+MR zE9xhAUF&IR#2Z*mucNChZ2B9nC=T@Ih)!ta5XJCoxhj~rWh_k8%+@lzVe5};T{E7> zI=kTsq}bXh6>(9^Zs357;900nTN&`zw?voiIZ6w)kw!+ZnZ`udo?%8p$MKFt%It;@ z?M3vQO}rH7sZN{IOhX??{BON{Q~)NCQ3O67tbibU{!UK>Um8dZ16CQBK@Wa?ZakTL z(%FCQIfh94Cg^F@5R51G-d})f~EUjx}Uvvd#%r1p6TOt7TD6vPV)xqyzOWBYc z@d^vMxN8?i9{|gLPc}^LVGxgXuYP-62=q?E+pKkflCcgsk*p#dKDZgu7sO$+u1j0O zy23)8wO`6@oqxVE9$FDHlg6(U+DFjMQOTQ&jp%LjD*kj;bQ%CPn!a!$VG_xLMi{q z1lFo{hpOC?j3RpBWAG#oN@Ul>Q|&3dr-TcEK(Q<>ATL$gzy7h3BY8v|oM@>?R^d4Y zAUUEtN>GoMBlZ}983Vm5l);_%Ef<2)MPS|p=(vWsc8N$r>PIr)-jKV2Gh_xz{pD5B zHR`cVX!BA&|H4AXoFBu~ul!M7t zO>$1Cp?@A7jc_o|*UQsMY9g-vM!^4FzSwx@3c&LBqQf{Y-kWrLet$Dt?N;GPJLVN{ z@+=1TE`ORNBTlfQwP3GbjKxvF$eebEg^Db94KiNjH?=(8L-4)7On7GgeG?8i_Kz3=>#2#4?}v@lnYdzZ%z z--BvR5ml}QHs4Ir7=e|ni#Y!F=VroEYWCi4M+rWk+$1KivP{0ViW*{x2`u|!sTx5C zJ;ovcfUV0g+i~0L$QNvZ85>05`cH`vQc?TfK#pbake7~4QVTkqZL;tHrlrcKE@}$ln0t_2^?XbF>%#}D%l2OwPC#HlLlN6D z>Jr?>^_TTW*}`K^KhOH_gkB%2CwzGwKBgyr|R{g&OM99>-DhsNxU zx&`H+^BQz+-UD_lXeI`EtfM=;&(?#EDG!fs#60a0x}$C@u_WHXZlEN zx7y_L^7{K;T>34QR5~ZiwHbM_Bdv>Wk7F!Kp75yUQIyTEPnmpYxZ2mvh(t-~^n$kxPAN(lXYyP0FrXYYbacsVn$; z3iNR%Vv>iQ6u}G!K46XQ(}2tK_|uqy1Mm6ch^+}AD7o4IfTD5>@6^wsFkLK& z4+V9Y{V3kG;@tO#h)!FAaT_R$SQh^DjE)c^aM*ouP4j9p43h|U6vd1t8)eu(21^rH zetEzK((=ppzSD-f*N~;8l!G2Ow%8*L>v@xW;^lD;im|*H=~5ltH2X6WZMM~dYx6l1 zs@igS=6Ty@>6nT$wp_{|;GlJ@2Pb9ML7gS)ob$Ki9xTV(bkdXVx5 zv10w*VsauoWN(9S|M$ZO&(cuRXpW6D>R^o+O{{%vo}EQ??^hU0SE~Vd*XDy{&jB}41+}g`8FBYsVoVX?OViLeQn-D`)Bq8^Z>H_W}WYOm>C?&1l@-4v- zuI*!aoKiR?$UaVSSB)!fQ84dJy5LNmG<`iO)BWHP6L2p~@~uwhuz; z8A``*B@`%>0PiCpRi!yEnRs{Fw!x6J)4pE!#!p+cS_un$1JAHz6C~h$g zW+%KrRHa~BZ(Xg!MZb^0s0H$k#W0@w8FV4LI;Bg>iD3RA8D{*CQ1`!zAhG=$L1O&B zW_JA-g2Yb$w>SUy7yZA3ApPrw{7)4bMkXeXe@NT^U6JvcOpR~l-5xkjbqMq}>3VA7 z;kNw7&Bktb+=tp3r5IUP$HMQcD_6UGH9pK9xw(0M2GVnzzaiJ1&g!-^Ayz`W(|EWS z%xtngnG1tzNsY|u6;%G{nE_6wnqllnBVvhhQVr`xF0Ox8tC@t2GI5@k?V^d)zr-IM zMbKpYd5rFt^cldsqhiRJDoluY7K6!6p4cmiM=8ZmvjNzxxmpw?kGBm45}ao3wLKir zcw2SiN)%0XJ$7Zq)98Nn?$An7;PjO5O&$p*C>lz;FFtAoL1%j+9ELwVFUmI`Q*0F6 zTW#x8l@X2#v9LkZKbwjAZKXNx>`Y-ApB>)8Sb2<>Zd9{qV!AQwtug)ZgcejEWkqRj zjiwzWqk{d@N*3%4_E^nun1l5r%FS~CLdc-wsq5iJ_FQ08U8Q*{he3`zTA?#zmGNug&enz)7D;k$K|hq^jkn-Srm;Hn z^MqP+fZe(KUs=z~0HR+ij0~@-;I9h>qLIp7pMAgVG2F>xq}enkqFq~)gTKmc$5SN> z6f~RnZYeo`UUag)$TkDRB(sNR>^|8&d1d+v&?KV7J9_}H8Yza@_;bc`+awBy+U59DjA zX}dH~*5wfU0@qsV)|}HcqR)u_s=Ta+VqmHu#1E7@W(qbOCiShBz1p<}=Th6P_bE@> zUW)>RyB#73x#aUtj!nq)#-g)4H{jo`;LgxCF$P5Bc)QgGPz0vvT7=$B1N6cA>lYJx zqvxIhZLj})2f}DebO^b#e+*zyB}Q8Hga}h)=x(B$vQLLzvuW6f_8iFWaf?N)`?94nFdT zdvGx^iA42ri%K%Uyr zc-6?LwLyc%5$2^ud*?_56B!XNbSN_S#%yQ&d4E3k!_1C{>ZOH0a1}dV$yKLLQv4a< zk!)tmiO8?5NDlOMEaA$Lu;AhhPLj{0@4Z?mP`FQBht#dRakhWH5~w!W3c%!c5v;sA z6MKN>kc`U+t1Tb)_xQ|P)WoBg@h?(ozlFNJV10m5Lt1h*Z%q)mp`@$TQJRn;&{I@s z%yG{9P*m!qD4I(;PQ^d|JNTz=Nend9!8?T8Br~n22+3v$eJnpl*;+jkYal?-4-FqrNcZv+=L5C3|RnSavE(;~9?O6rlTKe4`>K z<@gnn!{FmheNU4qno@~wAzb{E07fE&J5Un#nlWb>PySMfYoq*(L$4c1jZ(f_39|mg zsnyEGYoppI$rp|V!i&emxg6JWzhh5`)va15?lU0sQEHaXd6a|WjUp7-$mr$Ng zQ}>o&u93m#!Ba%fC>M1PGgNyKc&LM*c-_6wkwBIo%WFp7fMb7t3=PsXt(sh%>#&-E zUe`-=Q6H}Y{~oqVBqC&CgrjkmztmBbw=XKCD7HVkDR1{HQE>!SWt1)~p+Sx+nQ4jB`YrZqW%ce>=)kdQ;w=rT`9iaBPweG!5J zF$ix_#anI4y^+b`j@1CmHQ5cW%}F~IXT>-Z@I1TW#8sG~8$yM-^m?TO#X)u7nb2C= z(nVI{+LJfe2dHkR)kiF3ZL_S%mp=v?Kq78q&zk~~Uvm8fc!>o{2(zdqWZa@4kIC== z!j@m%9r<3}I^8!{XM~s++QLX^Gn}V%R&e)@5Q-IMyvk=X?{ZlE=ELHjoWho7k5hG* zXGtx8Avi)bb z6EEWD=u=?5?jcrKj3r=`e_P5hPAubDV5kY$x8@{QserY<7IBZ)81Qxq*=*SLrd`(+ z6ItAA#U{>5De}qT85Gx~N&()G2}Se#BXndoX)%$;b+wVajwKw3_?FF?{;IKV038fO z(_%Wn;#~!IJE(cj37Y1u9KmW6KY4j{q18vI2#MSj;_r21FVm6G#xCO8-iy0SXT!JL z&%qGRT&i*mJn7h@2%Xmr?GQ9kUV*LvubRDQ$n3kL+sREI*;9c_X>d1C?>^#Sm>l3P zCE*0Sol)x`D^^nnS5^zhJMSsu2EZX{WwrZMVxGo4o3!-QQHQy2>ssT1DFffM4}J6K zk55UUc{2+>)pvHhs74HNBZDZ`!$>(KQ!eUrj;F`zAC$y1#>r1w0?%0%v5ZYsBECMx zC=kCnK)hDf?I!_*Mi~?@rQhU2acRbBl*(+wPUbyCB+BVUr}l*_gbd>?`#t>7=Apc) zXOlFOP>D0s@@195Eg4O;r3>m5ihmVI@}4KFG7;_4t?b0D{+nwlUtZ`kU(4;z`3oTS ze<#6*?Ycb{TlaBIEl%4As^uoP=T;I0Z2{nK!H8a;%%Lgprm;0JAn=P)xATy5SM>Bc zLw#J}KSOai25;wlP|OQz4MM6RIrW);X#-#T{W(am{QtR?XU5oU?au=zUk9=;RgN3CjWwFeEddQtF z)!z%c#emX_CSjup|4jZye!^}oYN$kgtgQZ?mv{sJ(^e#Qz3J9~9oPzT8hm6yRZ$Ac zO5Ae5g1T>Kubvuq08I7JFUN9tU@fUA@WQB%tMdoJTI_>^81IY>gwE9c3@D2EjCtJ} zN2Fv8Z_v&!jtFpRB7abY#9(}_m6%mTgt1FQ&-f^Ei)OH!NoE3?VKI$nEI$J(ptWJ+ z7y%e-kN$SoAr6={*LGNsc4qlf)f1TPa`Mot;__i{b0-KV^6Z z#*U_?X)iI|)RHUvsB_wstyZ*)+nBTcW2E?zo0i(az3cnOMN~h04pb`7dY`|G&Zhd| zUXwBlTQrnsHKmbkGmrvw`N@(LVJzOvMtO3?d5l;n(|xeTj8B|jCx_r%S$3#pwW`L# zqZW7-ACkM~pjF7yl#x5Y=TtrY2BbL_lT`Gz>;+8IAX%E%au@Yc13rgU0~{A0k|H-t z0GRIEzRl>Zi(Tu!bmRguMji=NzZ+O?@;K`+GsG=j8H9#`y0;LCo?gfpLrOLS(Igvs zOI=LuZr7(#J-F_POBZ@HW^w`Qocx%7`a}M=U-|!BvcdkJqJ{t81pR-Z-Sl6RZ2YG$ z!{5;v`oDzSze-Ynpa1ry{*}M{M_Tb;>Nzp~TVVL#droZh?Emn&`*+BYU$yz=<-hw5 zhnTklU&TZT1KY^P*`0x`wj3$8jgWKIIt>Eah}8$q0IRU}b@RIq(DD;ajX^pP8ILsG z+zWn9OfHkOJah)addXNA+C4gixi=H2dDP1nv~OnX!<&Ubsj_37L30L)4k!fUJl_=O zU62u(Kx{-I-{%&zz#67kWW13<`0s8T=AI@VVhjlS7XTTK6V_87jy)K~MFBPUDe5+} z3a#MGdIxxlTUgB3w;;D~VS3Q??+wq0>n?AAN|HB%3-zfNN;U4_9Q{X~AVJ?MV`*S?HIpmHZ7Pqn}d; zQMrqB;LiaS!Kemz8HN!Wjy9`d!%6IW>V3wQ7Rs2inQwMXgRB~XD|>7NE#t2@R!UZb zcZ_Z*HaW32Gp{bMkg!Hez^wPuD)~zhQqM>I)6-*gl3;Z0d%DNe5R{YLgyO>aHm$XA0A7B zW8uP;j9Co*iVUixUa}y7El;ol^vh0KuwE%YkrO{DYp@Mdt$j%L~LzW?;T0M-jBoi>*9VF8vJ(?5v>xe!-^)(fILX}s1gVvCZpyjC2y znBJ-r1ZPxq-QuUQ1bpDAbdT-t1ea)*ZiT-%V@Zyd^0Yr!=?~tqO2c^?0o8B59Vw^8X zpR<~!sQ9C8%8{~AhcMu0jXl3M%c_&bsw97qy{*VgTZ%I=lDc(>^}74Z2>xt(mFIki z0;M0XHRPL%x*bN`ZA1J*x&_&8+aVrMH@2<0>2N7UOmDAPomZ9Imw-wuh#@U0iV|&v z@(`WbPXxt|_HIVxvipbkn$g_d~DqxXK}9<`N#RcgFf|a6VYQ*aWD%#$ z@;G&@Q@t%{=6$`ZCF=yPqP;dzjM2V6s+qD$^rLb%nRE7K$ozgj7dEmWmL+>BGU7u! zeh$oq8Cv$6rsH@SImwfkIaYRprm)>^DmEMdMBO%#6vtqDT`6g`jJijb&NGZr;LE3X zWJ%EGz}!J5{)*Q5*9?S;4FkA=u%DKjaRWA8H@iCWPO{wnUGR`dSC>4DTwRv$k||Fo z0{4Sx#A!4?kBRfqJgh3D5QTM~mY6hq2UbT)L>;9HUr0SC+b%#WjR)iqwE@=^6pr|_ zgWhHrYdFh#OBumQQ7QG7otoF4VcD$O`NEDg$I7?a+36o0LmuMx0f@BIhe|C49&-^Q z7nS97;BxQON|y9rv^xk<`w>44Z$~IJuE4@V4wqZ6xuZO~O{ zn)5FcjU`=Arlz$jCZncF8aKEWLx8TKl@BW8AEzomaR%-Xx$@ZirmrEei&DogYw);m z%(Vkxw)d9p8w_zy594e0h@dAYQLjsfYutgY&rn-DUTM39XPquAOd;%;X;sXjA(S)2 z?Gp-5l9Qy{Dr+Y-#b+*^Q-i`(>Kkc!*lYuVQ8~&F#_`ttuvtGNpURTiE6u}&=iD{^B!u)gUih&<9`~q3St}jtZqJU# zNS8JKNi{@tR17Qh?6I`k$BqcS-+t>qf;+>Ls(4VGBenVQ-~7_TFU`95>%ujQR?8W} z3cC+-S_N(NK~Cc#K1?^Kh_eCPowa#V)4FlX!~FsWf6=yoLTHX`7$Gud3xVZqNK7*Y zxNKhdT|ls3Q#3%w(n*DJd{SUi)_)ZfW{cz7Z=x-`GvWQ|=T&wpSR7-Sn_t6&gp}#} z5+;qE^2x8slWZlrIC85;Ojt1A&srLucu|nxV0oL$e1@`=tsbN@CQrVB=$WOr>$B5U z_dy=(H}@cV-f%9UfbhquzX?}6S$R|NT|{}!P7JP{AVMTr6?TscJk0trXAsw*0Aw-t zyrGba=6=ngZ4?`vqRt+#Z>nbKy0IjlxC|0&*YzE<$^P4nIK8n+i19{5hv5v=fe$0rxP zoIFP46PW^TqMO`*QnrZr##D-Z6g1J`Ft8vXF8;3)iqQ63jY4MkH19p-YMV-M{_U|e z)Vm90o7J^ChNz&4VD4(sLZN=WUPbo#BRT~J7D~d{5VR?TwddYbp<&W3#7wMmp5P8F%_HM~|GoMw8 zL8ysiHu4$2QUQz$M3<_IeX*sr@`%pVC&NjR(sA8z><2H6slwfGX`yLmN!f*0l zw71S*Di;W}p5SE)2J$1r6OBC0Y1iaZ8HLbAIHRgt7t#EJS>zmeSfts_w3q#$8HfX@Ili1?wg+!>?_TO=Q=p1KCUDp+tdb?!e|NK7rqQ5#-* ziB@HPL*s(eU?VSED>+gU7;r9~K_5YeAy|r72MeRnU@MQ90QZj!<>%ZaK(ZuNMr-D3DlsLI6r))5 zfV@6;rUaq2J<0+u>+Zq#f>{b(TZw5*;Qe@tbdPRgron(jfR7u3K%$J>Ln9@P2f<0l zY@CIaN{2{Raxwto<~#VtQw4-ji}_+Qj>Cb+l(xSC@LD-mEK5R?hm{CrDY@|rVD)-F ztZR;cz4}`%+iA1}B;MX5)GjD1zE#Hdew(P{Yo7Hhg(AS(LDkU4u1zFS;CIGDyc)2~ z%e{7-#9)W0k31mcuk#o1ltM~2K3oGpaky3%4G?Z7Yu_5QzFpxC95-qiwFmp8Wo-c* zx*27Yc}NVyD>{Xk^P%w7UNrMz@acX%01QTk&yU%quHg_AjmxU~ zgH;dcU)+Hy>e+=UlTFkWmP#yt_O=EWHIOXbrZ=kXRHyad#p1e^Gz+HuVI3!WDVI+W zdo|%Kqa-bHVqEjU>od}Ch$!}}xkh8FD2BGCXw#{kSUwqfwJjQez+*4xsarhXZn#nRS2XpJpA(g?p?u z`I{~Qb2oKt4Ifu0%Q46a+9sIPmo&7_3Uv>x&ygKK^C>)HmWwgI~9(aFU5|dp7OfWOH=Cz z!kt2_mEhL`R8}aQb&z~`(sDv^c^(Lb-LtzJq(q0gIKkC~v<#<4vvFIE;5!7ff;pDl zI@w=qCUmrEGbeL?wtBgZ73b{`r6MCOAdoG zPHQH(*at+CJU+GSDHJngMCInG=1W>-YlU_Ft;R@zdNR`7DH`!2bvimp{2;*SPG}2^ z549F)B4Kc9ML8`K6}8d@idmbFHUaeJcKAG}K~2Dx=bZCnRwQ49A_EwRj%}a1tVs8I zNAmK(Cd4JA1YPv-9@0SA)3fla=4e)7*3^22k#dqzVEb~6XWh3VoL-sB9hW!BUNmLV zwKaKATXzo8+lraezQ1A=yEYe9&}TZwV%Qg8Qten!T;^G&<*W%;!(X0BCAr-b(3^4# zWfd8i09TKX-9YL2pTdHF8#({`4VHz0<)5yw|INzJfX~Xr%+CJr3#}UMH-@mdtmY|< zJ8oX5!Ocvxv$l~_oWe2D((y(5jZw+hu%J{2cy9KKMs5iY7tNS&7B^vP!Kg0u>*hPv z(R;JB1zcgQChPoTp*Mwsxyo2)Bs4e_O1p`H==Ga^xZR3^`~%-oN;+Ov{oBc9Z>_r! zy)CK$yUw|uT23RZ+-u8H`AZTeI2iA3yyhu|9wEUxZXBMsKff-b-2P9sh&eEL;d}R8 zD>xUgl=xj{hN+_DadQvKaKi;d z@{s##o=U^5CrM^O=|No&in6O9?8jMsXnnIL8Wf8t?*&AQnXxA{U*THZH)5~0ct}v8 zcwI~fjiOG){#+l|=LGul>NVWbYTtG{X{P=ip)iYTld)xTA4SU)viJ&Mp4?@7E#b*S zYOQ{KOM#-zUqSh!T$gKATx^7)E{`ge;{;ZX>ISoKmB~;0Js$6ow@?Ko)+Q`jeIO-h zO!w_H2S2`?*2t>9WloSis5B?I;wRSQt`Y2$qN|KfteI;*!l2FNwHHL}5xw|Q!m}{R4IQ{$^g+OwceiM1?2_@9nnQerqlDD?3E4-@D<56brWABk&XecE zO7D}bq=pw`{SsKAkRT8hKCf%n!FyGtQ)>7sHe4_V+ZIK7c8#kZ!3GP$`Qx9zDJf~*C*e+>_4bC?nO zUG~(|;K~P)FUtg}4F4YNY5(nfF=l0Vb}%Gu*D1Ew0X%;PcxpmRBRLP0LOWX8nVw$q z=rD7jO)N$ruVwt8H%8R^s}`!0~SL~2aUF;r$Qsn$hij=XMsbAi>Oq|-GyCG zM~!(*tn{k1=W-O@t(Hh^C+F6Z2OBE5N6*$6p2^tJ_TE45wz|?Li={*9aeN%1Vl+A_ zacrQRg3&i%!e6tH5!*A)H1rrMz`ZM$!7F`(`k)d!G1%j8d;-4gT~si%Zhz#1LPg{z z!~}>qgLZwySux{<*Wgnb4yeq5?I`S~Lx(kovJhTO#_lh7kP>nn^L*sZ&<4G05tKK~ z>V9J!JOwC?wtnc;U%fM24Tc`{!GviKUM^<_mJj0(VjjCX8DXgLt?Mp(5EaZy!}kR}H&23U%nO$c<4RD+`9(Sex>LLNjv=+;yw9h8f$3taFBuW$t6g;59B~8KuI<|UPcP4O(1&bZ5&^5HwVLQA&t}oK zAZ9dw^O~2u$nHk#wzj=i)an7n3Q1CA`5wfDpb*D?e;-pnqG7+La_kOn5}s-kTYDEW zjFWhJuBd0I5l^CL!;>;?NXL*ifxkl_6(j%|*C}pF2cblg>P*=LA4ok&09U~ZyjCF_ zP5FArHp;3G}hJZV5v2&$zS+yAZt$_Pjy}b6|Y_q}Q(Wv*w9w%ay6r zEqCH6`v{#GY0+t*W;rCic4iFEeOe@iW1qMl4OYnc{1lr#0V*Cv!El>gA(ldWgwFg# zf<_pYSipYs?v37{)GuJU|>mDzYHVz<;eFtyEVm-SOcMmwNqG4np&a7$x4ttu`7 z)z&~8zP{-9^)YLhKeWt$fcEd&8;BWP@%%V)d476ds%Q^T`d$LU-h*G$0)I?86Ve6x zbIIGKG36dfjHUPXBZPz1`>SXB-PfH5*#xoc{M!XoC12z~2obl$3sh@UO0_~fh-6VL%*7cKKQDd{QVOe7A z4|-ljjLpOVi6%KTu9j{z>z1q5&6xP$E089qQOb^*f&Yvg)^}y|zU9#+OX#9S1?r~{N_%qmHlmPOKinTaatG|$Xg4HmPO6bp-8sG8+u8vc2fLI?6cEVq>O4&k z+ZRtF&d%oI?Tu(C`{V<%GI!|P~ zPa-jk?rN`oF=luSe>4>{I#ITVwThars)qCNjyKUnKJ+98Heliq>^}R)|;R9`r!d zfx|o^`D==)x0qg}x2x$KM%dKxZzQI0wNI;%+XI7;cN_>DJmb`qBNzmCW`Hn}qxg@V z-{VZ`+|`~as@`ThDN&oBa1cy;<)wjD7qP=6FS)J$;gce;h=ZEpR6Y~SGOQ+2FHH9R zFFjul5?#*KoCCHpLVGg8tiDJ;F^slEPWDM~Oa|are?;IoXDT20z*n`T9DiJ4%eCBN z>_{^S>x{++96c(OFE-)d{1r)8(d+TJ*$-Xwd^^Ykfl%ZvUWe4!`weS*uu|2AK|>Pr z*oGa-3z@9Y=NY`LL<5im)B1ltss#cq6iTxYONFoaZ+tuD`ex{P9h|T6p+m;TfkJAN zs92felwku8-=6s*Gu_LpA8rHTLL!aFZWEk4iFi1N_P}j3U^J+j{gS6kiTQu_9Uwjn zn47(c37=}=TzGM~?@#Y%IgNLyn)Pl!SpUrD@l05L+&yfT&<^yWU?u_72NjeJdq%pZ z-_jK#eEZt57|F|8Xi<)i{dtQZv*jUuJN3{8<94?#zE?GD|BRBooON*vM)%LkEH<>s z$FE7hJ>3Au=SZDS=X1X1%CAHc)0DzQS}Ow8Z>@y5uyMB`p&4axwvgGCKYZS2Zm_`t zcdbcb4@>|u{qSDFA8V(@LQ?jpN-?!Dmx-~cs1u~K&jxak)?6Z z0&=EOIQx9DU9SJIk}}GCl}nYSL8FC7fg@7~Z>IFyMG%wDa%kfMKO;%+$3$Pu9^G8K|Tai1*+Tw#NT}d$wZ{F}viW})4F6_P6RZh!} zJAXy#*u1PP+d2Y4R=?Gkzte)aj+^MB*Cl-0uceEpx6wOHaN|{jcwKqy-I*~hQ~G+a zIVt!%8iUZ=F7Y}LEL$(&@54b~1$qHG2S0*x)>+fikiJ@_r>RjL^gDh#(u~s zs2%n5fW5t=&62iRZw$G26ibK7g4DLi;93Z?&07*x&TrTUq{k#r)#sVJ2Q|isn$dLT z#x})C;nQIUOsKf2R>p+1rOUhDqv=!ZWyUtkBP9yGi5T941F&>hcm*wX@Idgo;0tpO6 zXB0w~bj}G-i)M3CLWk?_g8PP(`v{QxBt#^CSxTVLm4|FE$~^(gK*4)exB>;1^A1M) zugNv<{f~Ay`Em2)J(gb-X0vNMZolkpmKEJy8pV`eu!QGVXtJ*BNG16=TXa-8(qCcE zCzlj4a1$XbiLn;)L1K`mp9ug+%}|{Lr7rP*Gl1e=ISC0GPiDm6?)VjCXSPJ|r+!9F z@Q|Iwje`s4uM&eO^;6$H#gBF&%deU@UmcA>lPK^fantHZCNn{gIj9Mvp@V}xlRm7$ zcl_oa<4p>2T38V3xb##>w8KSDhOD2Y44gcijt28 ze9<^|ye8e1_MLP{u|D?S?9>|KEI(V@{e^z6-8e{E`(hXna$-2xF@Q6doH08wM3sd7 z6AWlgu*8lLePX%V`Ur2p_}MLC>+#3@8yK&U;;{A1p@5e%WS{HIrqzS;u?Ga|G(|6x zY877p4~&`=8`g|)6)rKLD2=!%NoT(XJ*H2dn0e><;c;Jqm2(1#bNCr_E;)4?Sx^Ma za91hY8ZbpNUz^dk!8585hRu_b ziHd^ed{-4qMZX70o$52KTeIfbEnBniz_~bnX!dp*{rM#|>J!ni1`(gs;{x8~ThKnmK(>P5T>f@*W9HIBQ&x^iaSy1qGwCk=gY750H)2#LgSu>A# zw=P2;$Y;1Oy0z_?m`DJS1z783fz>u#D0?yF_ewD%^s{Bpm=myvI$G(5>vuTV6u5<* z6l(7?kOIW>UtR$$rB zoWMDZfJo=n2|#mm031y86peBngS2W=v_ry_^7Cj4p0MUo_Nt4Ra=dEcdSL6r&kL5S z`E0ML7kkKePX0h9dNUR<*w6csnS@n>T72><<_P5_92SxodL-2T099c{igvTVmlMSP zxKAI@=!NB#^O_zx;fWEh@~rGk&yHKw`0eCMs9&fZatZo-PN^gg*h$Y+;W+iLcoJR+ z03=qRiEy8qRJ3wd_L|2!C4>io{GuI;!vMVyg} zE6k#$eQYWyNf>B{pc5ONIf10+vgCd~199N~bE0HuAWLJKW&inbzWl?boz;7H9ppx$ z0<55~j2Lw!#+xg!BVf%`SUz)L!_137?j%%ad#f8CiC1M8yuP`V4^JRQq8!iGX}rZR zzEWF$lV$J;;r#Y6o==I_6d9&Vc3fpSR`ec9Q>6G2t94s!h%~mn8niqh7$yO|fno@cioJ}9vey$HDV|0o=piED5rIk~hWn^?GIB7PQbPj38>STKZiefM- zxV0;p>E(TNgH#k;`7rRHibM8l%#sd}yZbx1F-8+(=iC78-%&c52 ze(g{qaGTZ@-r=}EiZQ+ht4=8$zxj8H6PQ5RX@pQ~i;nEexZ*+qV;`EaX0x3#2}GE| z7oCrBENX-j2Z{x-&&o2bIaPMmecyOy%de38oRQMBU17QKq~sW8#LhL^0rZ^xsbj>h zkvo)HXJuUk;-Ed5$mg*FK$(&>UJG2cZcu8;#dOd8$-1Bbp!q}0I^igG+_^Q2Felc( zV&xh!5umiPh7<#e@a$KtB^okPK=6^mBW+6a)l4AlpPh1*Cb3_tq>lpeM&iCD39@N` zR^<6qz#&ZvL^}x=I8WA(zS;GXVNPpnR^oC>3I-Ew9eIxu6t5pWvc#rrI? zFVl3tb;8|JvIqLkc3ObS#r13lQI6kFI(O?&{e$b#ip+r4QI3Z(L#)0xwy$tY5FM6VEq>L-T7dc~ zxHOC)f+_FmHSC6eg{9^-o@J}xy$3Tdmm9qgkAq6F)b{xCmH#0>+VC{O+^+=FfxI;j zKncfV1LJoVYj$x^ZZwmVbYpYAMBWxqe0pMbsJEgbZs3d5R4m?jtCv4$^)3snke4fb zmT21YNq<69A7m26XS}*dxqj1|>_Bkjp+{GcTiO4~mS&*zCu(sL(9_r3aZLOTeGG?? zF3xG&w?G%%UeogqG-vo~S;c_w)d~UQ``v@%U99eksE+73<;M(ieR#j*aUg)7$ZBmVQIv`( zZQ|u&2YJ<^SoW+qu7S;d5j9k2zF1a%Z2qXrt)s$A56H)x(o7fdBpWsoy7$zK(VoSC z8=IkQ8qBi7f6uuiMQ-2EPpVmuZo4+&o;6Hu_GgcQ%tM}z{>Z_7+~iy}E>_eu$dV@Z z)SJ}!qDr0qJ-UP#9As4OjpsyU(SY}UZ$aKfjxjQQ1JG6Y_=!jTC};!DBrjM{hDY7O zH^H6VYF1~%Cw+yA7^-LiomgM6prPvF^y_HCD#p?yXp7Ep$%Ro*`@>Yh7t?c&=lWXDC%PVrr zXK`v!ZEO|v1S^5Vzn$fQmBFD8ZFP=|aMtH7UbLt2@jBclE)YjgDm^pE?^RTjS;=L3 zm|N7rkgb=l8Kmx#C@Ar#=ub zU-)%#OgMQLxlYTWlb zAN5b?WnRZWR@qU|qFqk-#g(Y@5Tv~Eb-*=p(xkjZ+D!hR<3g9WLDx$0 z!m>rvBLVIfi<{0x-foV7RYQJu5?Adw_tCa%VZ_Vif*bf1`y_xip;Ebx`IYZI!%+UZ zEI}DYK?$7l$U({}FBO$hIV*0)OKaDT;F*J}F3$l1g~5HX09S}%1uCLc|V6XF^@wM=PXEt~~Ja`kA)V3>dH zGb~WG|aJbO66J=G23l`3vAZPT{R{Z>=Y);N zBO+t5kzWqIxrutcM_u@#n=Ao?C*@cypCV}x{x^7r#u`7M7b7 zQ!1Ij%bFr@ng)k9hSxn2O%GIDx@IQ-CR{oTl&wO!Y2rNFP}=~-Ui*BSbQa6E@p-!Y z%N<`_h(KQ9I_5@QGohNiOy3jnhcWb{0gws_o%Ve7B{T)mu-M{(n2rv^kDPAd!*p%l zV^s37PfKvZG(!(9s|tP!KUPTzU87V{L+qvvR$JkT)=^+@j|bD+OrEeczsGN@mK+k? z7dL|EAE3je-;lqlW9 z^_%maHZyq+fPEZ1a16umQwTYs4^^S?UhZQq35W7KIQoW&wV5yDDFp0{DL3ukrHbqM zAU%yhT#6ed=ysXQRgX+kWRJ0O_(F`fmk_)hBt?gxP3%p&hUe9cw--RZv%OBUO+co$ zu1hnT<^B|zB5xI=ZNE=TNaw`4JDti@mxCfRaLT;`2mRMbEHqN&0S;lN&>Vu}_eZHU zMVe>rEuaY8Is~e zTvn4*)|G0%Kj!6J(M=J}Fh_pm+E4NRnwl=kHlmEmdUe~qBmsGEf&Aa(E)3kee^`cZa1|E>2aD@+4 zachNJzA`kqc33o$=cK2_zGhp@h4k|jMn_Ob&9)*6)jiR~*=t;NDfz{Dp_pfva4(V~ z&BD!hEda~lhITU48t8aOR|juY*FU#9?4YG!UYj5WkeS2V2#0DWQstl}d-f7o^h4?P z>-Aom))-tPI)}+noyWL^`sZXiE!zo-J?Obj4*l+AvxBATq^R*jJqBq#R=#?7c$(cZ z=g`>8XC%Fj7j3!22ke-J6fetW>L%1J$E#BTK31!lZ$z6EGA=FEZ4vMI>PPc>3f940 z(N#|)3fY3F^{?w)OFkS=Aj%pOGSCdUPe8!xmjm2$O@vt1d%X2JHlt7u>>50djZFO^ zHDKBzMFFuA-NZ9dzTGh9dYu{v{oIG8$uEVIK3a`a;ZUG8;p*Z|A=}oS6=uc`w?&gb zJcWGK29$8=hmO8m=SZgnRODO;ts3|q$ygQy1oi&HvCFkqjE4-xw`vXYgq=k!sP z6ll0hN0OeUdtE&;ks7x}dwm<52d?fzkG`vT|IoA*PmJMzW}8cfsc zzPrMTC(EC*M?7xk_UlAQpzpsfi(|b2U4i1O_Gy9 z|NqWi^Wd^^b1Y|o7AC~&?csv{b$>L>z3?1otJ_nHW2V$B__K!R6NbCEl3*@@tzqjM zK}ocm>Z+a2Noj3V!2IrO&rL^y1qpyYCBC?|Xh8Yb9K}oF!2atl$pYbIr~yuX;sSqa z39`r#Sxp=~{o?eZYcGoLnCHz&o|{A$#Ls`U&tnfF>5CI)=;w*^qgjPZi0()W7-g15 zQO32rAvf;xw87rNv--7QApHb${>m0+sr^%Mq zpMqskr&z_XsYE0`c22F-%%1?T-82V>fTF@fXo0_a%61zsP7ESFGJ68C3pw*i;R$MD z**+7tXnBZWAbViUSqVs*B#5Tw?qVT?JI!2_m%q}tZTJiIb8jup+kB$1$+S{EXZ?c1 zcw$C7CtVoF1TXA8@_^%(&xHyA9h*|cLO}h)@^i93&0%AzzHgRr%NQVdPj$Lk z&4jD>;g3IABZ^kwY(S)KPgt7{)+jS2=ZRAOJAnLJ;R%T)0DEIxg*|%b=;#GEOcs_2 zcAy(I_gXb;AKn0U>3_QIhTQZaSje9(_I!Kne| zHeVw!=Q1kBoN8!`-=o6Esh6<4BPQT<*XS?2hM=$Ue9A$mxznjx*gRJRDN{}Jm}ot@ zm65;>e82k%!)SzV7Ul;a`0T^ zMh}jAQ7FLc5fWNhYF@`;ukc9egvyqS)1^uofpz>$=&NYy?qO*Pe^oETPI|0uTxIA1 zZQ0U%84i&7T35F(lY&ciRExm7saDA2 zy||V^qN{Hb7ScmoAlm({M>Hgi_rDQcbXBzay$yB-9SL_F1JCQHZq3!fULG~nhnupk0gvQnXXRw>j~|q^bt&@;-T(ILUyP=!C&)pM0GOb&WFns||7$<5N+b*W!5!`ACQ znAL!SmH%Qpm)`T)*UcEb++m+FFzIhC{5}w!$P!jy`V8$6qc}5&Apn?2KMHPuN>U*H zsF(s1EfXS~Jk8_*^Q>o=?3WE@Cjc|N-P}^TsbH{%SByG+Dj&v-v^9lABbyR6&Ry4( zr85FU8P_)j@|hrH>93RC!O)xd7*M$#)1t>hc-)Y5S#f^+50T1K4u(+u;$q@OuYB*2 zR^)^m_vQynfbf3#fg3gCPU9;=XMyQZWbZzxVndEqN>`YL7?+opKHC9W86(pC`|hSA z%8yHu(&Y%w0W^hT%@Lfl<21aGP7*TjVaz}*x{7WHucuM|2Vc+*51SPKSM*WuM9n(e z*4Xr=|G|3JrxVNfQK1&e17&!f5qLYu}KTF9Q-@@ z+gMXN`w|=*M$gFdtpdoglYJ*|mObv2LrL#z`+Oj%;&W#9Svcst*BwvS{=7d8$wMs_ zG_F?%li{dM+_fn_p7 zAk^FXv9)EGxfUYz8Ge9-9wW3AKHC}|LTh=ivkN8VvfptiH5Aq;@s(i#F@uI**F@@W zvxGFi4QloZcG<@ABEyO|qLaP0}eAg3`ik;gj6_8WR5D0kDh;@Tx>;d8HkBcEu!Hxh>@m z3_DpS9HBCiW zkIIOZ&Xw9yLz4-6oqAk^(a^9;B_Bs79*$&z)Uq*TECS0inJI3cPNLHTLI^gl1w;OM ztOoI}r2HB+c1W_0TMzv%n{$4^W|$SKiUp54z{x2l0@1NMrAKb3DH%G6Aj|P*mvUJJ z@AJ0VU1VT5%?l(L%H0LmZV$P3QZ#fF481Ry8>w@AZH)#MJpe}=Zre4NF^_FU(N!0z z(!UK&M#OhtDw~jw+fs#&p!G*mUF$XS&5^pVgk#V1qosTl#r?Z=5=8=n+6%6UdN~Q(D^R^t0w}tP%7O@r{ZE6YzbTc2OV#(&p?kOv z(%YvGL{`^%-~iw^ZI>M9@Lwufef(8pQu@*h89Y)VU@TplH?E0U557TESn!<#xJ)cI zP}r8Onvg;ICH3S(qL;AAC%o$E<*N55+Z$)}0OLc}hoOTV+zyWH;e$k&J)t_Su)uti zOE3XV63c2}^7g_Z2%n~`3b967fAy2vjDfIke+c;lL59rP*=UrJh081DTwqB*+74jJ zaY(N{p*aA`zX&99xQgXu$lm+4$xBgK8g!;F7PX^M{8=3p6Sl5-CI|DaQN*2dm`NHf zsKR~JsPp^dT%5xTfw2+SOr;vTg?Rmt=mc2c7Vz+b4f#JU z;3Q?gye+XHgGx3PCMQ+0D+pl* zIw}N^*N)32GqnK@+2v^Ws6VQd;7ltc7S^Rf5y#kM`5T5>?M*9yHP?fe>A`@3DNocyP;Xy=d7?8tf^4xovlMq%DdIz!s&Yi_epwm8w)0Cx`;m%n6*p<2=*~Xtctvg zI+12(y+fvtS+Iaj`LyaFS#sC^cbdZ@bNRn>GLwgx?`jh9P!ECKC^|*wUoZiH5(Bsl zhu{9;cq)2jc3awY!1O4`6a_7{jaDq^HHrAuKSa@yV3q8$+SZG+j)$L5VJ44@6e z4i{qWO>*~ifC{&LNF@V6m@$msZN=t)tZ192dP zzk~KzzDw>M`!PZmlhf0=I*yTe-nQdLbFV9MleM&^IjF5 zKACdASG-mDO}PnJPRVy5`JV>QC{^mCgI)GfdwhcF$Tx4`6Mg(2Fr{jew6=0dp4qE# znIr5aL5TyH6>Vl_JwY9_XGoh}cMx8_?sausw8v(s*2X8vsEKtQMdnOb&2M-AJGLK! zLbrSfpnhV+cYG@)Ah+$TLP#;^PQ9fg;h+xDUJ+Szp4tFoK;9F&d+3XzO`*RWr4xLP zcm`zR`H~=lub

  • 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 z. + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1951.txt b/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1951.txt new file mode 100644 index 000000000..403c8c722 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1952.txt b/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1952.txt new file mode 100644 index 000000000..14c0c72eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See https://www.iso.org/ for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/doc/txtvsbin.txt b/internal-complibs/zlib-ng-2.1.0-beta1/doc/txtvsbin.txt new file mode 100644 index 000000000..3d0f0634f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The white list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The black list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the white list and +no byte that belongs to the black list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more black-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of black-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.0-beta1/fallback_builtins.h new file mode 100644 index 000000000..447f9ac19 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/fallback_builtins.h @@ -0,0 +1,133 @@ +#ifndef FALLBACK_BUILTINS_H +#define FALLBACK_BUILTINS_H + +#if defined(_MSC_VER) && !defined(__clang__) +#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM64) + +#include +#ifdef X86_FEATURES +# include "arch/x86/x86_features.h" +#endif + +/* This is not a general purpose replacement for __builtin_ctz. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + * Tzcnt and bsf give identical results except when input value is 0, therefore this can not be allowed. + * If tzcnt instruction is not supported, the cpu will itself execute bsf instead. + * Performance tzcnt/bsf is identical on Intel cpu, tzcnt is faster than bsf on AMD cpu. + */ +static __forceinline int __builtin_ctz(unsigned int value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u32(value); +# else + unsigned long trailing_zero; + _BitScanForward(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZ + +#ifdef _M_AMD64 +/* This is not a general purpose replacement for __builtin_ctzll. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + */ +static __forceinline int __builtin_ctzll(unsigned long long value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u64(value); +# else + unsigned long trailing_zero; + _BitScanForward64(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZLL +#endif // Microsoft AMD64 + +#endif // Microsoft AMD64/IA64/x86/ARM/ARM64 test +#endif // _MSC_VER & !clang + +/* Unfortunately GCC didn't support these things until version 10. + * Similarly, AppleClang didn't support them in Xcode 9.2 but did in 9.3. + */ +#ifdef __AVX2__ +#include + +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 10) \ + || (defined(__apple_build_version__) && __apple_build_version__ < 9020039) +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm256_castsi128_si256(r); +} + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm512_castsi128_si512(r); +} +#endif // __AVX512F__ +#endif // gcc/AppleClang version test + +#endif // __AVX2__ + +/* GCC <9 is missing some AVX512 intrinsics. + */ +#ifdef __AVX512F__ +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 9) +#include + +#define PACK(c0, c1, c2, c3) (((int)(unsigned char)(c0) << 24) | ((int)(unsigned char)(c1) << 16) | \ + ((int)(unsigned char)(c2) << 8) | ((int)(unsigned char)(c3))) + +static inline __m512i _mm512_set_epi8(char __q63, char __q62, char __q61, char __q60, + char __q59, char __q58, char __q57, char __q56, + char __q55, char __q54, char __q53, char __q52, + char __q51, char __q50, char __q49, char __q48, + char __q47, char __q46, char __q45, char __q44, + char __q43, char __q42, char __q41, char __q40, + char __q39, char __q38, char __q37, char __q36, + char __q35, char __q34, char __q33, char __q32, + char __q31, char __q30, char __q29, char __q28, + char __q27, char __q26, char __q25, char __q24, + char __q23, char __q22, char __q21, char __q20, + char __q19, char __q18, char __q17, char __q16, + char __q15, char __q14, char __q13, char __q12, + char __q11, char __q10, char __q09, char __q08, + char __q07, char __q06, char __q05, char __q04, + char __q03, char __q02, char __q01, char __q00) { + return _mm512_set_epi32(PACK(__q63, __q62, __q61, __q60), PACK(__q59, __q58, __q57, __q56), + PACK(__q55, __q54, __q53, __q52), PACK(__q51, __q50, __q49, __q48), + PACK(__q47, __q46, __q45, __q44), PACK(__q43, __q42, __q41, __q40), + PACK(__q39, __q38, __q37, __q36), PACK(__q35, __q34, __q33, __q32), + PACK(__q31, __q30, __q29, __q28), PACK(__q27, __q26, __q25, __q24), + PACK(__q23, __q22, __q21, __q20), PACK(__q19, __q18, __q17, __q16), + PACK(__q15, __q14, __q13, __q12), PACK(__q11, __q10, __q09, __q08), + PACK(__q07, __q06, __q05, __q04), PACK(__q03, __q02, __q01, __q00)); +} + +#undef PACK + +#endif // gcc version test +#endif // __AVX512F__ + +/* Missing zero-extension AVX and AVX512 intrinsics. + * Fixed in Microsoft Visual Studio 2017 version 15.7 + * https://developercommunity.visualstudio.com/t/missing-zero-extension-avx-and-avx512-intrinsics/175737 + */ +#if defined(_MSC_VER) && _MSC_VER < 1914 +#ifdef __AVX2__ +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + return _mm256_inserti128_si256(_mm256_setzero_si256(), a, 0); +} +#endif // __AVX2__ + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + return _mm512_inserti32x4(_mm512_setzero_si512(), a, 0); +} +#endif // __AVX512F__ +#endif // defined(_MSC_VER) && _MSC_VER < 1914 + +#endif // include guard FALLBACK_BUILTINS_H diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/functable.c b/internal-complibs/zlib-ng-2.1.0-beta1/functable.c new file mode 100644 index 000000000..d20098292 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/functable.c @@ -0,0 +1,336 @@ +/* functable.c -- Choose relevant optimized functions at runtime + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "crc32_braid_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "cpu_features.h" + +static void init_functable(void) { + struct functable_s ft; + struct cpu_features cf; + + cpu_check_features(&cf); + + // Generic code + ft.adler32 = &adler32_c; + ft.adler32_fold_copy = &adler32_fold_copy_c; + ft.chunkmemset_safe = &chunkmemset_safe_c; + ft.chunksize = &chunksize_c; + ft.crc32 = &PREFIX(crc32_braid); + ft.crc32_fold = &crc32_fold_c; + ft.crc32_fold_copy = &crc32_fold_copy_c; + ft.crc32_fold_final = &crc32_fold_final_c; + ft.crc32_fold_reset = &crc32_fold_reset_c; + ft.inflate_fast = &inflate_fast_c; + ft.insert_string = &insert_string_c; + ft.quick_insert_string = &quick_insert_string_c; + ft.slide_hash = &slide_hash_c; + ft.update_hash = &update_hash_c; + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +# if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) + ft.longest_match = &longest_match_unaligned_64; + ft.longest_match_slow = &longest_match_slow_unaligned_64; + ft.compare256 = &compare256_unaligned_64; +# elif defined(HAVE_BUILTIN_CTZ) + ft.longest_match = &longest_match_unaligned_32; + ft.longest_match_slow = &longest_match_slow_unaligned_32; + ft.compare256 = &compare256_unaligned_32; +# else + ft.longest_match = &longest_match_unaligned_16; + ft.longest_match_slow = &longest_match_slow_unaligned_16; + ft.compare256 = &compare256_unaligned_16; +# endif +#else + ft.longest_match = &longest_match_c; + ft.longest_match_slow = &longest_match_slow_c; + ft.compare256 = &compare256_c; +#endif + + + // Select arch-optimized functions + + // X86 - SSE2 +#ifdef X86_SSE2 +# if !defined(__x86_64__) && !defined(_M_X64) && !defined(X86_NOCHECK_SSE2) + if (cf.x86.has_sse2) +# endif + { + ft.chunkmemset_safe = &chunkmemset_safe_sse2; + ft.chunksize = &chunksize_sse2; + ft.inflate_fast = &inflate_fast_sse2; + ft.slide_hash = &slide_hash_sse2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_sse2; + ft.longest_match = &longest_match_sse2; + ft.longest_match_slow = &longest_match_slow_sse2; +# endif + } +#endif + // X86 - SSSE3 +#ifdef X86_SSSE3 + if (cf.x86.has_ssse3) { + ft.adler32 = &adler32_ssse3; +# ifdef X86_SSE2 + ft.chunkmemset_safe = &chunkmemset_safe_ssse3; + ft.inflate_fast = &inflate_fast_ssse3; +# endif + } +#endif + // X86 - SSE4.2 +#ifdef X86_SSE42 + if (cf.x86.has_sse42) { + ft.adler32_fold_copy = &adler32_fold_copy_sse42; + ft.insert_string = &insert_string_sse42; + ft.quick_insert_string = &quick_insert_string_sse42; + ft.update_hash = &update_hash_sse42; + } +#endif + // X86 - PCLMUL +#ifdef X86_PCLMULQDQ_CRC + if (cf.x86.has_pclmulqdq) { + ft.crc32 = &crc32_pclmulqdq; + ft.crc32_fold = &crc32_fold_pclmulqdq; + ft.crc32_fold_copy = &crc32_fold_pclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_pclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_pclmulqdq_reset; + } +#endif + // X86 - AVX +#ifdef X86_AVX2 + if (cf.x86.has_avx2) { + ft.adler32 = &adler32_avx2; + ft.adler32_fold_copy = &adler32_fold_copy_avx2; + ft.chunkmemset_safe = &chunkmemset_safe_avx2; + ft.chunksize = &chunksize_avx2; + ft.inflate_fast = &inflate_fast_avx2; + ft.slide_hash = &slide_hash_avx2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_avx2; + ft.longest_match = &longest_match_avx2; + ft.longest_match_slow = &longest_match_slow_avx2; +# endif + } +#endif +#ifdef X86_AVX512 + if (cf.x86.has_avx512) { + ft.adler32 = &adler32_avx512; + ft.adler32_fold_copy = &adler32_fold_copy_avx512; + } +#endif +#ifdef X86_AVX512VNNI + if (cf.x86.has_avx512vnni) { + ft.adler32 = &adler32_avx512_vnni; + ft.adler32_fold_copy = &adler32_fold_copy_avx512_vnni; + } +#endif + // X86 - VPCLMULQDQ +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + if (cf.x86.has_pclmulqdq && cf.x86.has_avx512 && cf.x86.has_vpclmulqdq) { + ft.crc32 = &crc32_vpclmulqdq; + ft.crc32_fold = &crc32_fold_vpclmulqdq; + ft.crc32_fold_copy = &crc32_fold_vpclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_vpclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_vpclmulqdq_reset; + } +#endif + + + // ARM - NEON +#ifdef ARM_NEON +# ifndef ARM_NOCHECK_NEON + if (cf.arm.has_neon) +# endif + { + ft.adler32 = &adler32_neon; + ft.chunkmemset_safe = &chunkmemset_safe_neon; + ft.chunksize = &chunksize_neon; + ft.inflate_fast = &inflate_fast_neon; + ft.slide_hash = &slide_hash_neon; +# ifdef HAVE_BUILTIN_CTZLL + ft.compare256 = &compare256_neon; + ft.longest_match = &longest_match_neon; + ft.longest_match_slow = &longest_match_slow_neon; +# endif + } +#endif + // ARM - ACLE +#ifdef ARM_ACLE + if (cf.arm.has_crc32) { + ft.crc32 = &crc32_acle; + ft.insert_string = &insert_string_acle; + ft.quick_insert_string = &quick_insert_string_acle; + ft.update_hash = &update_hash_acle; + } +#endif + + + // Power - VMX +#ifdef PPC_VMX + if (cf.power.has_altivec) { + ft.adler32 = &adler32_vmx; + ft.slide_hash = &slide_hash_vmx; + } +#endif + // Power8 - VSX +#ifdef POWER8_VSX + if (cf.power.has_arch_2_07) { + ft.adler32 = &adler32_power8; + ft.chunkmemset_safe = &chunkmemset_safe_power8; + ft.chunksize = &chunksize_power8; + ft.inflate_fast = &inflate_fast_power8; + ft.slide_hash = &slide_hash_power8; + } +#endif +#ifdef POWER8_VSX_CRC32 + if (cf.power.has_arch_2_07) + ft.crc32 = &crc32_power8; +#endif + // Power9 +#ifdef POWER9 + if (cf.power.has_arch_3_00) { + ft.compare256 = &compare256_power9; + ft.longest_match = &longest_match_power9; + ft.longest_match_slow = &longest_match_slow_power9; + } +#endif + + + // S390 +#ifdef S390_CRC32_VX + if (cf.s390.has_vx) + ft.crc32 = crc32_s390_vx; +#endif + + // Assign function pointers individually for atomic operation + functable.adler32 = ft.adler32; + functable.adler32_fold_copy = ft.adler32_fold_copy; + functable.chunkmemset_safe = ft.chunkmemset_safe; + functable.chunksize = ft.chunksize; + functable.compare256 = ft.compare256; + functable.crc32 = ft.crc32; + functable.crc32_fold = ft.crc32_fold; + functable.crc32_fold_copy = ft.crc32_fold_copy; + functable.crc32_fold_final = ft.crc32_fold_final; + functable.crc32_fold_reset = ft.crc32_fold_reset; + functable.inflate_fast = ft.inflate_fast; + functable.insert_string = ft.insert_string; + functable.longest_match = ft.longest_match; + functable.longest_match_slow = ft.longest_match_slow; + functable.quick_insert_string = ft.quick_insert_string; + functable.slide_hash = ft.slide_hash; + functable.update_hash = ft.update_hash; +} + +/* stub functions */ +static uint32_t adler32_stub(uint32_t adler, const uint8_t* buf, size_t len) { + init_functable(); + return functable.adler32(adler, buf, len); +} + +static uint32_t adler32_fold_copy_stub(uint32_t adler, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + return functable.adler32_fold_copy(adler, dst, src, len); +} + +static uint8_t* chunkmemset_safe_stub(uint8_t* out, unsigned dist, unsigned len, unsigned left) { + init_functable(); + return functable.chunkmemset_safe(out, dist, len, left); +} + +static uint32_t chunksize_stub(void) { + init_functable(); + return functable.chunksize(); +} + +static uint32_t compare256_stub(const uint8_t* src0, const uint8_t* src1) { + init_functable(); + return functable.compare256(src0, src1); +} + +static uint32_t crc32_stub(uint32_t crc, const uint8_t* buf, size_t len) { + init_functable(); + return functable.crc32(crc, buf, len); +} + +static void crc32_fold_stub(crc32_fold* crc, const uint8_t* src, size_t len, uint32_t init_crc) { + init_functable(); + functable.crc32_fold(crc, src, len, init_crc); +} + +static void crc32_fold_copy_stub(crc32_fold* crc, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + functable.crc32_fold_copy(crc, dst, src, len); +} + +static uint32_t crc32_fold_final_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_final(crc); +} + +static uint32_t crc32_fold_reset_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_reset(crc); +} + +static void inflate_fast_stub(PREFIX3(stream) *strm, uint32_t start) { + init_functable(); + functable.inflate_fast(strm, start); +} + +static void insert_string_stub(deflate_state* const s, uint32_t str, uint32_t count) { + init_functable(); + functable.insert_string(s, str, count); +} + +static uint32_t longest_match_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match(s, cur_match); +} + +static uint32_t longest_match_slow_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match_slow(s, cur_match); +} + +static Pos quick_insert_string_stub(deflate_state* const s, const uint32_t str) { + init_functable(); + return functable.quick_insert_string(s, str); +} + +static void slide_hash_stub(deflate_state* s) { + init_functable(); + functable.slide_hash(s); +} + +static uint32_t update_hash_stub(deflate_state* const s, uint32_t h, uint32_t val) { + init_functable(); + return functable.update_hash(s, h, val); +} + +/* functable init */ +Z_INTERNAL Z_TLS struct functable_s functable = { + adler32_stub, + adler32_fold_copy_stub, + chunkmemset_safe_stub, + chunksize_stub, + compare256_stub, + crc32_stub, + crc32_fold_stub, + crc32_fold_copy_stub, + crc32_fold_final_stub, + crc32_fold_reset_stub, + inflate_fast_stub, + insert_string_stub, + longest_match_stub, + longest_match_slow_stub, + quick_insert_string_stub, + slide_hash_stub, + update_hash_stub +}; diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/functable.h b/internal-complibs/zlib-ng-2.1.0-beta1/functable.h new file mode 100644 index 000000000..1cdfd4df4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/functable.h @@ -0,0 +1,41 @@ +/* functable.h -- Struct containing function pointers to optimized functions + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef FUNCTABLE_H_ +#define FUNCTABLE_H_ + +#include "deflate.h" +#include "crc32_fold.h" +#include "adler32_fold.h" + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +struct functable_s { + uint32_t (* adler32) (uint32_t adler, const uint8_t *buf, size_t len); + uint32_t (* adler32_fold_copy) (uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + uint8_t* (* chunkmemset_safe) (uint8_t *out, unsigned dist, unsigned len, unsigned left); + uint32_t (* chunksize) (void); + uint32_t (* compare256) (const uint8_t *src0, const uint8_t *src1); + uint32_t (* crc32) (uint32_t crc, const uint8_t *buf, size_t len); + void (* crc32_fold) (struct crc32_fold_s *crc, const uint8_t *src, size_t len, uint32_t init_crc); + void (* crc32_fold_copy) (struct crc32_fold_s *crc, uint8_t *dst, const uint8_t *src, size_t len); + uint32_t (* crc32_fold_final) (struct crc32_fold_s *crc); + uint32_t (* crc32_fold_reset) (struct crc32_fold_s *crc); + void (* inflate_fast) (PREFIX3(stream) *strm, uint32_t start); + void (* insert_string) (deflate_state *const s, uint32_t str, uint32_t count); + uint32_t (* longest_match) (deflate_state *const s, Pos cur_match); + uint32_t (* longest_match_slow) (deflate_state *const s, Pos cur_match); + Pos (* quick_insert_string)(deflate_state *const s, uint32_t str); + void (* slide_hash) (deflate_state *s); + uint32_t (* update_hash) (deflate_state *const s, uint32_t h, uint32_t val); +}; + +Z_INTERNAL extern Z_TLS struct functable_s functable; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/gzguts.h b/internal-complibs/zlib-ng-2.1.0-beta1/gzguts.h new file mode 100644 index 000000000..fe0927063 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/gzguts.h @@ -0,0 +1,145 @@ +#ifndef GZGUTS_H_ +#define GZGUTS_H_ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#include +#include +#include +#include +#include + +#if defined(ZLIB_COMPAT) +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#ifdef _WIN32 +# include +#endif + +#if defined(_WIN32) +# include +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +#if !defined(STDC99) && !defined(__CYGWIN__) && !defined(__MINGW__) && defined(_WIN32) +# if !defined(vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c + where the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +/* get errno and strerror definition */ +#ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +#else +# define zstrerror() "stdio error (consult errno)" +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#ifndef GZBUFSIZE +# define GZBUFSIZE 131072 +#endif + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + PREFIX3(stream) strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state *gz_statep; + +/* shared functions */ +void Z_INTERNAL gz_error(gz_state *, int, const char *); + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) + +#endif /* GZGUTS_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/gzlib.c b/internal-complibs/zlib-ng-2.1.0-beta1/gzlib.c new file mode 100644 index 000000000..e1290fc61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/gzlib.c @@ -0,0 +1,525 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +#if defined(_WIN32) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +static void gz_reset(gz_state *); +static gzFile gz_open(const void *, int, const char *); + +/* Reset gzip file state */ +static void gz_reset(gz_state *state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +static gzFile gz_open(const void *path, int fd, const char *mode) { + gz_state *state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_state *)zng_alloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') { + state->level = *mode - '0'; + } else { + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + zng_free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + {} + } + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + zng_free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + zng_free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, (const wchar_t *)path, 0); + if (len == (size_t)-1) + len = 0; + } else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + zng_free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) { + wcstombs(state->path, (const wchar_t *)path, len + 1); + } else { + *(state->path) = 0; + } + else +#endif + (void)snprintf(state->path, len + 1, "%s", (const char *)path); + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#if defined(_WIN32) + fd == -2 ? _wopen((const wchar_t *)path, oflag, 0666) : +#elif __CYGWIN__ + fd == -2 ? open(state->path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + zng_free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +#ifdef ZLIB_COMPAT +gzFile Z_EXPORT PREFIX4(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} +#endif + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzdopen)(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile Z_EXPORT PREFIX(gzopen_w)(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +int Z_EXPORT PREFIX(gzclose)(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_state *state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + return state->mode == GZ_READ ? PREFIX(gzclose_r)(file) : PREFIX(gzclose_w)(file); +#else + return PREFIX(gzclose_r)(file); +#endif +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzbuffer)(gzFile file, unsigned size) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzrewind)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzseek)(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (PREFIX(gzrewind)(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzseek)(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = PREFIX4(gzseek)(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gztell)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gztell)(gzFile file) { + + z_off64_t ret; + + ret = PREFIX4(gztell)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzoffset)(gzFile file) { + z_off64_t offset; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzoffset)(gzFile file) { + z_off64_t ret; + + ret = PREFIX4(gzoffset)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzeof)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * Z_EXPORT PREFIX(gzerror)(gzFile file, int *errnum) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void Z_EXPORT PREFIX(gzclearerr)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void Z_INTERNAL gz_error(gz_state *state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + return; + } + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, "%s%s%s", state->path, ": ", msg); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/gzread.c.in b/internal-complibs/zlib-ng-2.1.0-beta1/gzread.c.in new file mode 100644 index 000000000..67a21a3e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/gzread.c.in @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +/* Local functions */ +static int gz_load(gz_state *, unsigned char *, unsigned, unsigned *); +static int gz_avail(gz_state *); +static int gz_look(gz_state *); +static int gz_decomp(gz_state *); +static int gz_fetch(gz_state *); +static int gz_skip(gz_state *, z_off64_t); +static size_t gz_read(gz_state *, void *, size_t); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +static int gz_load(gz_state *state, unsigned char *buf, unsigned len, unsigned *have) { + ssize_t ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +static int gz_avail(gz_state *state) { + unsigned got; + PREFIX3(stream) *strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +static int gz_look(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)zng_alloc(state->want); + state->out = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = NULL; + state->strm.zfree = NULL; + state->strm.opaque = NULL; + state->strm.avail_in = 0; + state->strm.next_in = NULL; + if (PREFIX(inflateInit2)(&(state->strm), MAX_WBITS + 16) != Z_OK) { /* gunzip */ + zng_free(state->out); + zng_free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + PREFIX(inflateReset)(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +static int gz_decomp(gz_state *state) { + int ret = Z_OK; + unsigned had; + PREFIX3(stream) *strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = PREFIX(inflate)(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +static int gz_fetch(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + do { + switch (state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +static int gz_skip(gz_state *state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } else if (state->eof && state->strm.avail_in == 0) { + /* output buffer empty -- return if we're at the end of the input */ + break; + } else { + /* need more data to skip -- load up output buffer */ + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +static size_t gz_read(gz_state *state, void *buf, size_t len) { + size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzread)(gzFile file, void *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfread)(void *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + if (size && SIZE_MAX / size < nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + len = nitems * size; + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#undef @ZLIB_SYMBOL_PREFIX@gzgetc +#undef @ZLIB_SYMBOL_PREFIX@zng_gzgetc +int Z_EXPORT PREFIX(gzgetc)(gzFile file) { + unsigned char buf[1]; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +#ifdef ZLIB_COMPAT +int Z_EXPORT PREFIX(gzgetc_)(gzFile file) { + return PREFIX(gzgetc)(file); +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzungetc)(int c, gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * Z_EXPORT PREFIX(gzgets)(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_state *state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) { + do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + } + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzdirect)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + + state = (gz_state *)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_r)(gzFile file) { + int ret, err; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + + state = (gz_state *)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + PREFIX(inflateEnd)(&(state->strm)); + zng_free(state->out); + zng_free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + zng_free(state); + return ret ? Z_ERRNO : err; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/gzwrite.c b/internal-complibs/zlib-ng-2.1.0-beta1/gzwrite.c new file mode 100644 index 000000000..08e0ce9aa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/gzwrite.c @@ -0,0 +1,526 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include +#include "gzguts.h" + +/* Local functions */ +static int gz_init(gz_state *); +static int gz_comp(gz_state *, int); +static int gz_zero(gz_state *, z_off64_t); +static size_t gz_write(gz_state *, void const *, size_t); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +static int gz_init(gz_state *state) { + int ret; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + memset(state->in, 0, state->want << 1); + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)zng_alloc(state->want); + if (state->out == NULL) { + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = NULL; + strm->zfree = NULL; + strm->opaque = NULL; + ret = PREFIX(deflateInit2)(strm, state->level, Z_DEFLATED, MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +static int gz_comp(gz_state *state, int flush) { + int ret; + ssize_t got; + unsigned have; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + PREFIX(deflateReset)(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, (unsigned long)have)) < 0 || (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = PREFIX(deflate)(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +static int gz_zero(gz_state *state, z_off64_t len) { + int first; + unsigned n; + PREFIX3(stream) *strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* 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. */ +static size_t gz_write(gz_state *state, void const *buf, size_t len) { + size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const unsigned char *) buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzwrite)(gzFile file, void const *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfwrite)(void const *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputc)(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputs)(gzFile file, const char *s) { + size_t len, put; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +/* -- see zlib.h -- */ +int Z_EXPORTVA PREFIX(gzvprintf)(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; + len = vsnprintf(next, state->size, format, va); + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int Z_EXPORTVA PREFIX(gzprintf)(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = PREFIX(gzvprintf)(file, format, va); + va_end(va); + return ret; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzflush)(gzFile file, int flush) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzsetparams)(gzFile file, int level, int strategy) { + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + PREFIX(deflateParams)(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_w)(gzFile file) { + int ret = Z_OK; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)PREFIX(deflateEnd)(&(state->strm)); + zng_free(state->out); + } + zng_free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + zng_free(state); + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/infback.c b/internal-complibs/zlib-ng-2.1.0-beta1/infback.c new file mode 100644 index 000000000..9f5042b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/infback.c @@ -0,0 +1,511 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateBackInit +#endif + +/* + strm provides memory allocation functions in zalloc and zfree, or + NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + + This function is hidden in ZLIB_COMPAT builds. + */ +int32_t ZNG_CONDEXPORT PREFIX(inflateBackInit)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window) { + struct inflate_state *state; + + if (strm == NULL || window == NULL || windowBits < MIN_WBITS || windowBits > MAX_WBITS) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->dmax = 32768U; + state->wbits = (unsigned int)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + state->chunksize = functable.chunksize(); + return Z_OK; +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateBackInit_)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window, + const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateBackInit)(strm, windowBits, window); +} + +/* + Private macros for inflateBack() + Look in inflate_p.h for macros shared with inflate() +*/ + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is NULL or the state was not initialized. + */ +int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in_desc, out_func out, void *out_desc) { + struct inflate_state *state; + z_const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == NULL || strm->state == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* Reset the state */ + strm->msg = NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + copy = MIN(copy, have); + copy = MIN(copy, left); + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && + left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + functable.inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (here.op & MAX_BITS); + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } else { + from = put - state->offset; + copy = left; + } + copy = MIN(copy, state->length); + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && (ret == Z_STREAM_END)) { + ret = Z_BUF_ERROR; + } + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateBackEnd)(PREFIX3(stream) *strm) { + if (strm == NULL || strm->state == NULL || strm->zfree == NULL) + return Z_STREAM_ERROR; + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inffast_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/inffast_tpl.h new file mode 100644 index 000000000..9ddd187d8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inffast_tpl.h @@ -0,0 +1,326 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= INFLATE_FAST_MIN_HAVE + strm->avail_out >= INFLATE_FAST_MIN_LEFT + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - On some architectures, it can be significantly faster (e.g. up to 1.2x + faster on x86_64) to load from strm->next_in 64 bits, or 8 bytes, at a + time, so INFLATE_FAST_MIN_HAVE == 8. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { + /* start: inflate()'s starting value for strm->avail_out */ + struct inflate_state *state; + z_const unsigned char *in; /* local strm->next_in */ + const unsigned char *last; /* have enough input while in < last */ + unsigned char *out; /* local strm->next_out */ + unsigned char *beg; /* inflate()'s initial strm->next_out */ + unsigned char *end; /* while out < end, enough space available */ + unsigned char *safe; /* can use chunkcopy provided out < safe */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if wsize != 0 */ + + /* hold is a local copy of strm->hold. By default, hold satisfies the same + invariants that strm->hold does, namely that (hold >> bits) == 0. This + invariant is kept by loading bits into hold one byte at a time, like: + + hold |= next_byte_of_input << bits; in++; bits += 8; + + If we need to ensure that bits >= 15 then this code snippet is simply + repeated. Over one iteration of the outermost do/while loop, this + happens up to six times (48 bits of input), as described in the NOTES + above. + + However, on some little endian architectures, it can be significantly + faster to load 64 bits once instead of 8 bits six times: + + if (bits <= 16) { + hold |= next_8_bytes_of_input << bits; in += 6; bits += 48; + } + + Unlike the simpler one byte load, shifting the next_8_bytes_of_input + by bits will overflow and lose those high bits, up to 2 bytes' worth. + The conservative estimate is therefore that we have read only 6 bytes + (48 bits). Again, as per the NOTES above, 48 bits is sufficient for the + rest of the iteration, and we will not need to load another 8 bytes. + + Inside this function, we no longer satisfy (hold >> bits) == 0, but + this is not problematic, even if that overflow does not land on an 8 bit + byte boundary. Those excess bits will eventually shift down lower as the + Huffman decoder consumes input, and when new input bits need to be loaded + into the bits variable, the same input bits will be or'ed over those + existing bits. A bitwise or is idempotent: (a | b | b) equals (a | b). + Note that we therefore write that load operation as "hold |= etc" and not + "hold += etc". + + Outside that loop, at the end of the function, hold is bitwise and'ed + with (1<hold >> state->bits) == 0. + */ + uint64_t hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const *lcode; /* local strm->lencode */ + code const *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + const code *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char *from; /* where to copy match from */ + unsigned extra_safe; /* copy chunks safely in all cases */ + + /* copy state to local variables */ + state = (struct inflate_state *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - (INFLATE_FAST_MIN_HAVE - 1)); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - (INFLATE_FAST_MIN_LEFT - 1)); + safe = out + strm->avail_out; +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* Detect if out and window point to the same memory allocation. In this instance it is + necessary to use safe chunk copy functions to prevent overwriting the window. If the + window is overwritten then future matches with far distances will fail to copy correctly. */ + extra_safe = (wsize != 0 && out >= window && out + INFLATE_FAST_MIN_LEFT <= window + wsize); + +#define REFILL() do { \ + hold |= load_64_bits(in, bits); \ + in += 7; \ + in -= ((bits >> 3) & 7); \ + bits |= 56; \ + } while (0) + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + REFILL(); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + } + } + dolen: + DROPBITS(here->bits); + op = here->op; + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } else if (op & 16) { /* length base */ + len = here->val; + op &= MAX_BITS; /* number of extra bits */ + len += BITS(op); + DROPBITS(op); + Tracevv((stderr, "inflate: length %u\n", len)); + here = dcode + (hold & dmask); + if (bits < MAX_BITS + MAX_DIST_EXTRA_BITS) { + REFILL(); + } + dodist: + DROPBITS(here->bits); + op = here->op; + if (op & 16) { /* distance base */ + dist = here->val; + op &= MAX_BITS; /* number of extra bits */ + dist += BITS(op); +#ifdef INFLATE_STRICT + if (dist > dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + DROPBITS(op); + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + } else if (wnext >= op) { /* contiguous in window */ + from += wnext - op; + } else { /* wrap around window */ + op -= wnext; + from += wsize - op; + if (op < len) { /* some from end of window */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + from = window; /* more from start of window */ + op = wnext; + /* This (rare) case can create a situation where + the first chunkcopy below must be checked. + */ + } + } + if (op < len) { /* still need some from output */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + out = CHUNKUNROLL(out, &dist, &len); + out = chunkcopy_safe(out, out - dist, len, safe); + } else { + out = chunkcopy_safe(out, from, len, safe); + } + } else if (extra_safe) { + /* Whole reference is in range of current output. */ + if (dist >= len || dist >= state->chunksize) + out = chunkcopy_safe(out, out - dist, len, safe); + else + out = CHUNKMEMSET_SAFE(out, dist, len, (unsigned)((safe - out) + 1)); + } else { + /* Whole reference is in range of current output. No range checks are + necessary because we start with room for at least 258 bytes of output, + so unroll and roundoff operations can write beyond `out+len` so long + as they stay within 258 bytes of `out`. + */ + if (dist >= len || dist >= state->chunksize) + out = CHUNKCOPY(out, out - dist, len); + else + out = CHUNKMEMSET(out, dist, len); + } + } else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + BITS(op); + goto dodist; + } else { + SET_BAD("invalid distance code"); + break; + } + } else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + BITS(op); + goto dolen; + } else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } else { + SET_BAD("invalid literal/length code"); + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (UINT64_C(1) << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? (INFLATE_FAST_MIN_HAVE - 1) + (last - in) + : (INFLATE_FAST_MIN_HAVE - 1) - (in - last)); + strm->avail_out = (unsigned)(out < end ? (INFLATE_FAST_MIN_LEFT - 1) + (end - out) + : (INFLATE_FAST_MIN_LEFT - 1) - (out - end)); + + Assert(bits <= 32, "Remaining bits greater than 32"); + state->hold = (uint32_t)hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inffixed_tbl.h b/internal-complibs/zlib-ng-2.1.0-beta1/inffixed_tbl.h new file mode 100644 index 000000000..7292fa06e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inffixed_tbl.h @@ -0,0 +1,94 @@ +/* inffixed_tbl.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + +/* WARNING: this file should *not* be used by applications. + * It is part of the implementation of this library and is + * subject to change. Applications should only use zlib.h. + */ + +static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} +}; + +static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} +}; diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inflate.c b/internal-complibs/zlib-ng-2.1.0-beta1/inflate.c new file mode 100644 index 000000000..0cbed041d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inflate.c @@ -0,0 +1,1408 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "inffixed_tbl.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateInit +# undef inflateInit2 +#endif + +/* function prototypes */ +static int inflateStateCheck(PREFIX3(stream) *strm); +static int updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum); +static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len); + +static inline void inf_chksum_cpy(PREFIX3(stream) *strm, uint8_t *dst, + const uint8_t *src, uint32_t copy) { + if (!copy) return; + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold_copy(&state->crc_fold, dst, src, copy); + } else +#endif + { + strm->adler = state->check = functable.adler32_fold_copy(state->check, dst, src, copy); + } +} + +static inline void inf_chksum(PREFIX3(stream) *strm, const uint8_t *src, uint32_t len) { + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold(&state->crc_fold, src, len, 0); + } else +#endif + { + strm->adler = state->check = functable.adler32(state->check, src, len); + } +} + +static int inflateStateCheck(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->zalloc == NULL || strm->zfree == NULL) + return 1; + state = (struct inflate_state *)strm->state; + if (state == NULL || state->strm != strm || state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int32_t Z_EXPORT PREFIX(inflateResetKeep)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->check = ADLER32_INITIAL_VALUE; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + INFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateReset)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return PREFIX(inflateResetKeep)(strm); +} + +int32_t Z_EXPORT PREFIX(inflateReset2)(PREFIX3(stream) *strm, int32_t windowBits) { + int wrap; + struct inflate_state *state; + + /* get the state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= MAX_WBITS; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < MIN_WBITS || windowBits > MAX_WBITS)) + return Z_STREAM_ERROR; + if (state->window != NULL && state->wbits != (unsigned)windowBits) { + ZFREE_WINDOW(strm, state->window); + state->window = NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return PREFIX(inflateReset)(strm); +} + +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(inflateInit2)(PREFIX3(stream) *strm, int32_t windowBits) { + int32_t ret; + struct inflate_state *state; + + if (strm == NULL) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->strm = strm; + state->window = NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + state->chunksize = functable.chunksize(); + ret = PREFIX(inflateReset2)(strm, windowBits); + if (ret != Z_OK) { + ZFREE_STATE(strm, state); + strm->state = NULL; + } + return ret; +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(inflateInit)(PREFIX3(stream) *strm) { + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit_)(PREFIX3(stream) *strm, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit2_)(PREFIX3(stream) *strm, int32_t windowBits, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, windowBits); +} + +int32_t Z_EXPORT PREFIX(inflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + INFLATE_PRIME_HOOK(strm, bits, value); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (unsigned int)bits > 32) + return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (unsigned int)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. This returns fixed tables from inffixed_tbl.h. + */ + +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state) { + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state) { + /* if it hasn't been done already, allocate space for the window */ + if (state->window == NULL) { + unsigned wsize = 1U << state->wbits; + state->window = (unsigned char *)ZALLOC_WINDOW(state->strm, wsize + state->chunksize, sizeof(unsigned char)); + if (state->window == NULL) + return Z_MEM_ERROR; +#ifdef Z_MEMORY_SANITIZER + /* This is _not_ to subvert the memory sanitizer but to instead unposion some + data we willingly and purposefully load uninitialized into vector registers + in order to safely read the last < chunksize bytes of the window. */ + __msan_unpoison(state->window + wsize, state->chunksize); +#endif + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + return Z_OK; +} + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +static int32_t updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum) { + struct inflate_state *state; + uint32_t dist; + + state = (struct inflate_state *)strm->state; + + if (PREFIX(inflate_ensure_window)(state)) return 1; + + /* len state->wsize or less output bytes into the circular window */ + if (len >= state->wsize) { + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * it (s/390 being the primary exception to this. Also, for now, do the adler checksums + * if not a gzip based header. The inline adler checksums will come in the near future, + * possibly the next commit */ + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + /* We have to split the checksum over non-copied and copied bytes */ + if (len > state->wsize) + inf_chksum(strm, end - len, len - state->wsize); + inf_chksum_cpy(strm, state->window, end - state->wsize, state->wsize); + } else { + memcpy(state->window, end - state->wsize, state->wsize); + } + + state->wnext = 0; + state->whave = state->wsize; + } else { + dist = state->wsize - state->wnext; + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * We need to maintain the correct order here for the checksum */ + dist = MIN(dist, len); + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window + state->wnext, end - len, dist); + } else { + memcpy(state->window + state->wnext, end - len, dist); + } + len -= dist; + if (len) { + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window, end - len, len); + } else { + memcpy(state->window, end - len, len); + } + + state->wnext = len; + state->whave = state->wsize; + } else { + state->wnext += dist; + if (state->wnext == state->wsize) + state->wnext = 0; + if (state->whave < state->wsize) + state->whave += dist; + } + } + return 0; +} + +/* + Private macros for inflate() + Look in inflate_p.h for macros shared with inflateBack() +*/ + +/* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) { + struct inflate_state *state; + const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + uint32_t in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == NULL || + (strm->next_in == NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state *)strm->state; + if (state->mode == TYPE) /* skip check */ + state->mode = TYPEDO; + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = MAX_WBITS; + state->check = CRC32_INITIAL_VALUE; + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + SET_BAD("incorrect header check"); + break; + } + if (BITS(4) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > MAX_WBITS || len > state->wbits) { + SET_BAD("invalid window size"); + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + if (state->flags & 0xe000) { + SET_BAD("unknown header flags set"); + break; + } + if (state->head != NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + Z_FALLTHROUGH; + + case TIME: + NEEDBITS(32); + if (state->head != NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + Z_FALLTHROUGH; + + case OS: + NEEDBITS(16); + if (state->head != NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + Z_FALLTHROUGH; + + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (uint16_t)hold; + if (state->head != NULL) + state->head->extra_len = (uint16_t)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } else if (state->head != NULL) { + state->head->extra = NULL; + } + state->mode = EXTRA; + Z_FALLTHROUGH; + + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) + copy = have; + if (copy) { + if (state->head != NULL && state->head->extra != NULL) { + len = state->head->extra_len - state->length; + if (len < state->head->extra_max) { + memcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + } + if ((state->flags & 0x0200) && (state->wrap & 4)) { + state->check = PREFIX(crc32)(state->check, next, copy); + } + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) + goto inf_leave; + } + state->length = 0; + state->mode = NAME; + Z_FALLTHROUGH; + + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->name != NULL && state->length < state->head->name_max) + state->head->name[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->name = NULL; + } + state->length = 0; + state->mode = COMMENT; + Z_FALLTHROUGH; + + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->comment != NULL + && state->length < state->head->comm_max) + state->head->comment[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->comment = NULL; + } + state->mode = HCRC; + Z_FALLTHROUGH; + + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + SET_BAD("header crc mismatch"); + break; + } + INITBITS(); + } + if (state->head != NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + /* compute crc32 checksum if not in raw mode */ + if ((state->wrap & 4) && state->flags) + strm->adler = state->check = functable.crc32_fold_reset(&state->crc_fold); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + Z_FALLTHROUGH; + + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = TYPE; + Z_FALLTHROUGH; + + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case TYPEDO: + /* determine and dispatch block type */ + INFLATE_TYPEDO_HOOK(strm, flush); /* hook for IBM Z DFLTCC */ + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case COPY_: + state->mode = COPY; + Z_FALLTHROUGH; + + case COPY: + /* copy stored block from input to output */ + copy = state->length; + if (copy) { + copy = MIN(copy, have); + copy = MIN(copy, left); + if (copy == 0) + goto inf_leave; + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + Z_FALLTHROUGH; + + case LENLENS: + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + Z_FALLTHROUGH; + + case CODELENS: + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case LEN_: + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + functable.inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code */ + state->extra = (here.op & MAX_BITS); + state->mode = LENEXT; + Z_FALLTHROUGH; + + case LENEXT: + /* get extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + Z_FALLTHROUGH; + + case DIST: + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + state->mode = DISTEXT; + Z_FALLTHROUGH; + + case DISTEXT: + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + Z_FALLTHROUGH; + + case MATCH: + /* copy match from window to output */ + if (left == 0) + goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + copy = MIN(copy, state->length); + copy = MIN(copy, left); + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) + state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } else { + from = state->window + (state->wnext - copy); + } + copy = MIN(copy, state->length); + copy = MIN(copy, left); + + put = chunkcopy_safe(put, from, copy, put + left); + } else { + copy = MIN(state->length, left); + + put = functable.chunkmemset_safe(put, state->offset, copy, left); + } + left -= copy; + state->length -= copy; + if (state->length == 0) + state->mode = LEN; + break; + + case LIT: + if (left == 0) + goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + + /* compute crc32 checksum if not in raw mode */ + if (INFLATE_NEED_CHECKSUM(strm) && state->wrap & 4) { + if (out) { + inf_chksum(strm, put - out, out); + } +#ifdef GUNZIP + if (state->flags) + strm->adler = state->check = functable.crc32_fold_final(&state->crc_fold); +#endif + } + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + SET_BAD("incorrect data check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + Z_FALLTHROUGH; + + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + SET_BAD("incorrect length check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + Z_FALLTHROUGH; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + case MEM: + return Z_MEM_ERROR; + + case SYNC: + + default: /* can't happen, but makes compilers happy */ + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (INFLATE_NEED_UPDATEWINDOW(strm) && + (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH)))) { + /* update sliding window with respective checksum if not in "raw" mode */ + if (updatewindow(strm, strm->next_out, out - strm->avail_out, state->wrap & 4)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateEnd)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->window != NULL) + ZFREE_WINDOW(strm, state->window); + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary */ + if (state->whave && dictionary != NULL) { + memcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); + memcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); + } + if (dictLength != NULL) + *dictLength = state->whave; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + struct inflate_state *state; + unsigned long dictid; + int32_t ret; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = functable.adler32(ADLER32_INITIAL_VALUE, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength, 0); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if ((state->wrap & 2) == 0) + return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +static uint32_t syncsearch(uint32_t *have, const uint8_t *buf, uint32_t len) { + uint32_t got, next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int32_t Z_EXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + size_t in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state *state; + + /* check parameters */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) + return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) + return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; + out = strm->total_out; + PREFIX(inflateReset)(strm); + strm->total_in = (z_uintmax_t)in; /* Can't use z_size_t here as it will overflow on 64-bit Windows */ + strm->total_out = (z_uintmax_t)out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int32_t Z_EXPORT PREFIX(inflateSyncPoint)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + INFLATE_SYNC_POINT_HOOK(strm); + state = (struct inflate_state *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int32_t Z_EXPORT PREFIX(inflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + struct inflate_state *state; + struct inflate_state *copy; + unsigned char *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)source->state; + + /* allocate space */ + copy = ZALLOC_INFLATE_STATE(source); + if (copy == NULL) + return Z_MEM_ERROR; + window = NULL; + if (state->window != NULL) { + wsize = 1U << state->wbits; + window = (unsigned char *)ZALLOC_WINDOW(source, wsize, sizeof(unsigned char)); + if (window == NULL) { + ZFREE_STATE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + ZCOPY_INFLATE_STATE(copy, state); + copy->strm = dest; + if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != NULL) { + ZCOPY_WINDOW(window, state->window, (size_t)1U << state->wbits); + } + copy->window = window; + dest->state = (struct internal_state *)copy; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateUndermine)(PREFIX3(stream) *strm, int32_t subvert) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + Z_UNUSED(subvert); + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int32_t Z_EXPORT PREFIX(inflateValidate)(PREFIX3(stream) *strm, int32_t check) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long Z_EXPORT PREFIX(inflateMark)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return -65536; + INFLATE_MARK_HOOK(strm); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long Z_EXPORT PREFIX(inflateCodesUsed)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->state == NULL) + return (unsigned long)-1; + state = (struct inflate_state *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inflate.h b/internal-complibs/zlib-ng-2.1.0-beta1/inflate.h new file mode 100644 index 000000000..39cdf5d68 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inflate.h @@ -0,0 +1,140 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef INFLATE_H_ +#define INFLATE_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). + NO_GZIP would be used to avoid linking in the crc code when it is not needed. + For shared libraries, gzip decoding should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + PREFIX(gz_headerp) head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + uint32_t wsize; /* window size or zero if not using window */ + uint32_t whave; /* valid bytes in the window */ + uint32_t wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if needed */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* bit accumulator */ + uint32_t hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + uint32_t length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const *lencode; /* starting table for length/literal codes */ + code const *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + uint32_t have; /* number of code lengths in lens[] */ + code *next; /* next available space in codes[] */ + uint16_t lens[320]; /* temporary storage for code lengths */ + uint16_t work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ + uint32_t chunksize; /* size of memory copying chunk */ +}; + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state); +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state); + +#endif /* INFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inflate_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/inflate_p.h new file mode 100644 index 000000000..a007cd05d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inflate_p.h @@ -0,0 +1,225 @@ +/* inflate_p.h -- Private inline functions and macros shared with more than one deflate method + * + */ + +#ifndef INFLATE_P_H +#define INFLATE_P_H + +#include + +/* Architecture-specific hooks. */ +#ifdef S390_DFLTCC_INFLATE +# include "arch/s390/dfltcc_inflate.h" +#else +/* Memory management for the inflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_INFLATE_STATE(strm) ((struct inflate_state *)ZALLOC(strm, 1, sizeof(struct inflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_INFLATE_STATE(dst, src) memcpy(dst, src, sizeof(struct inflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define ZCOPY_WINDOW(dest, src, n) memcpy(dest, src, n) +# define ZFREE_WINDOW(strm, addr) ZFREE(strm, addr) +/* Invoked at the end of inflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflatePrime(). Useful for updating arch-specific buffers. */ +# define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0) +/* Invoked at the beginning of each block. Useful for plugging arch-specific inflation code. */ +# define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_UPDATEWINDOW(strm) 1 +/* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */ +# define INFLATE_MARK_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */ +# define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSetDictionary(). Useful for checking arch-specific window data. */ +# define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of inflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +#endif + +/* + * Macros shared by inflate() and inflateBack() + */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? PREFIX(crc32)(check, buf, len) : functable.adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) functable.adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = PREFIX(crc32)(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = PREFIX(crc32)(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = (z_const unsigned char *)next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Ensure that there is at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate()/inflateBack(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + (hold & ((1U << (unsigned)(n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Set mode=BAD and prepare error message */ +#define SET_BAD(errmsg) \ + do { \ + state->mode = BAD; \ + strm->msg = (char *)errmsg; \ + } while (0) + +#define INFLATE_FAST_MIN_HAVE 15 +#define INFLATE_FAST_MIN_LEFT 260 + +/* Load 64 bits from IN and place the bytes at offset BITS in the result. */ +static inline uint64_t load_64_bits(const unsigned char *in, unsigned bits) { + uint64_t chunk; + memcpy(&chunk, in, sizeof(chunk)); + +#if BYTE_ORDER == LITTLE_ENDIAN + return chunk << bits; +#else + return ZSWAP64(chunk) << bits; +#endif +} + +/* Behave like chunkcopy, but avoid writing beyond of legal output. */ +static inline uint8_t* chunkcopy_safe(uint8_t *out, uint8_t *from, uint64_t len, uint8_t *safe) { + uint64_t safelen = (safe - out) + 1; + len = MIN(len, safelen); + int32_t olap_src = from >= out && from < out + len; + int32_t olap_dst = out >= from && out < from + len; + uint64_t tocopy; + + /* For all cases without overlap, memcpy is ideal */ + if (!(olap_src || olap_dst)) { + memcpy(out, from, (size_t)len); + return out + len; + } + + /* We are emulating a self-modifying copy loop here. To do this in a way that doesn't produce undefined behavior, + * we have to get a bit clever. First if the overlap is such that src falls between dst and dst+len, we can do the + * initial bulk memcpy of the nonoverlapping region. Then, we can leverage the size of this to determine the safest + * atomic memcpy size we can pick such that we have non-overlapping regions. This effectively becomes a safe look + * behind or lookahead distance. */ + uint64_t non_olap_size = llabs(from - out); // llabs vs labs for compatibility with windows + + memcpy(out, from, (size_t)non_olap_size); + out += non_olap_size; + from += non_olap_size; + len -= non_olap_size; + + /* So this doesn't give use a worst case scenario of function calls in a loop, + * we want to instead break this down into copy blocks of fixed lengths */ + while (len) { + tocopy = MIN(non_olap_size, len); + len -= tocopy; + + while (tocopy >= 32) { + memcpy(out, from, 32); + out += 32; + from += 32; + tocopy -= 32; + } + + if (tocopy >= 16) { + memcpy(out, from, 16); + out += 16; + from += 16; + tocopy -= 16; + } + + if (tocopy >= 8) { + memcpy(out, from, 8); + out += 8; + from += 8; + tocopy -= 8; + } + + if (tocopy >= 4) { + memcpy(out, from, 4); + out += 4; + from += 4; + tocopy -= 4; + } + + if (tocopy >= 2) { + memcpy(out, from, 2); + out += 2; + from += 2; + tocopy -= 2; + } + + if (tocopy) { + *out++ = *from++; + } + } + + return out; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.c b/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.c new file mode 100644 index 000000000..f04d65f86 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.c @@ -0,0 +1,295 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" + +const char PREFIX(inflate_copyright)[] = " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int Z_INTERNAL zng_inflate_table(codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code *next; /* next available space in table */ + const uint16_t *base; /* base value table to use */ + const uint16_t *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + uint16_t count[MAX_BITS+1]; /* number of codes of each length */ + uint16_t offs[MAX_BITS+1]; /* offsets in table for each length */ + static const uint16_t lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const uint16_t lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + static const uint16_t dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const uint16_t dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAX_BITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAX_BITS; max >= 1; max--) + if (count[max] != 0) break; + root = MIN(root, max); + if (UNLIKELY(max == 0)) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (uint16_t)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + root = MAX(root, min); + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAX_BITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAX_BITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (uint16_t)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (LIKELY(work[sym] >= match)) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } else if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) + break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) + break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (uint16_t)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (UNLIKELY(huff != 0)) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (uint16_t)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.h b/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.h new file mode 100644 index 000000000..eeae9c6ac --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/inftrees.h @@ -0,0 +1,66 @@ +#ifndef INFTREES_H_ +#define INFTREES_H_ + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + uint16_t val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1924, which is the sum of 1332 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distributions. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 10 15" for literal/length codes + returns returns 1332, and "enough 30 9 15" for distance codes returns 592. + The initial root table size (10 or 9) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 1332 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int Z_INTERNAL zng_inflate_table (codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work); + +#endif /* INFTREES_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/insert_string.c b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string.c new file mode 100644 index 000000000..cfe39837f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string.c @@ -0,0 +1,21 @@ +/* insert_string.c -- insert_string integer hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 16 + +#define HASH_CALC(s, h, val) h = ((val * 2654435761U) >> HASH_SLIDE); +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_c +#define INSERT_STRING insert_string_c +#define QUICK_INSERT_STRING quick_insert_string_c + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_roll.c b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_roll.c new file mode 100644 index 000000000..dfea347bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_roll.c @@ -0,0 +1,24 @@ +/* insert_string_roll.c -- insert_string rolling hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 5 + +#define HASH_CALC(s, h, val) h = ((h << HASH_SLIDE) ^ ((uint8_t)val)) +#define HASH_CALC_VAR s->ins_h +#define HASH_CALC_VAR_INIT +#define HASH_CALC_READ val = strstart[0] +#define HASH_CALC_MASK (32768u - 1u) +#define HASH_CALC_OFFSET (STD_MIN_MATCH-1) + +#define UPDATE_HASH update_hash_roll +#define INSERT_STRING insert_string_roll +#define QUICK_INSERT_STRING quick_insert_string_roll + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_tpl.h new file mode 100644 index 000000000..4acd67fd6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/insert_string_tpl.h @@ -0,0 +1,108 @@ +#ifndef INSERT_STRING_H_ +#define INSERT_STRING_H_ + +/* insert_string.h -- Private insert_string functions shared with more than + * one insert string implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef HASH_CALC_OFFSET +# define HASH_CALC_OFFSET 0 +#endif +#ifndef HASH_CALC_MASK +# define HASH_CALC_MASK HASH_MASK +#endif +#ifndef HASH_CALC_READ +# if BYTE_ORDER == LITTLE_ENDIAN +# define HASH_CALC_READ \ + memcpy(&val, strstart, sizeof(val)); +# else +# define HASH_CALC_READ \ + val = ((uint32_t)(strstart[0])); \ + val |= ((uint32_t)(strstart[1]) << 8); \ + val |= ((uint32_t)(strstart[2]) << 16); \ + val |= ((uint32_t)(strstart[3]) << 24); +# endif +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +Z_INTERNAL uint32_t UPDATE_HASH(deflate_state *const s, uint32_t h, uint32_t val) { + (void)s; + HASH_CALC(s, h, val); + return h & HASH_CALC_MASK; +} + +/* =========================================================================== + * Quick insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + */ +Z_INTERNAL Pos QUICK_INSERT_STRING(deflate_state *const s, uint32_t str) { + Pos head; + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + head = s->head[hm]; + if (LIKELY(head != str)) { + s->prev[str & s->w_mask] = head; + s->head[hm] = (Pos)str; + } + return head; +} + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first STD_MIN_MATCH bytes of str are valid + * (except for the last STD_MIN_MATCH-1 bytes of the input file). + */ +Z_INTERNAL void INSERT_STRING(deflate_state *const s, uint32_t str, uint32_t count) { + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint8_t *strend = strstart + count; + + for (Pos idx = (Pos)str; strstart < strend; idx++, strstart++) { + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + Pos head = s->head[hm]; + if (LIKELY(head != idx)) { + s->prev[idx & s->w_mask] = head; + s->head[hm] = idx; + } + } +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/match_tpl.h b/internal-complibs/zlib-ng-2.1.0-beta1/match_tpl.h new file mode 100644 index 000000000..d07679852 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/match_tpl.h @@ -0,0 +1,289 @@ +/* match_tpl.h -- find longest match template for compare256 variants + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Portions copyright (C) 2014-2021 Konstantin Nosov + * Fast-zlib optimized longest_match + * https://github.com/gildor2/fast_zlib + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "functable.h" + +#ifndef MATCH_TPL_H +#define MATCH_TPL_H + +#define EARLY_EXIT_TRIGGER_LEVEL 5 + +#endif + +/* Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is garbage. + * + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >=1 + * OUT assertion: the match length is not greater than s->lookahead + */ +Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) { + unsigned int strstart = s->strstart; + const unsigned wmask = s->w_mask; + unsigned char *window = s->window; + unsigned char *scan = window + strstart; + Z_REGISTER unsigned char *mbase_start = window; + Z_REGISTER unsigned char *mbase_end; + const Pos *prev = s->prev; + Pos limit; +#ifdef LONGEST_MATCH_SLOW + Pos limit_base; +#else + int32_t early_exit; +#endif + uint32_t chain_length, nice_match, best_len, offset; + uint32_t lookahead = s->lookahead; + Pos match_offset = 0; +#ifdef UNALIGNED_OK + uint8_t scan_start[8]; +#endif + uint8_t scan_end[8]; + +#define GOTO_NEXT_CHAIN \ + if (--chain_length && (cur_match = prev[cur_match & wmask]) > limit) \ + continue; \ + return best_len; + + /* The code is optimized for STD_MAX_MATCH-2 multiple of 16. */ + Assert(STD_MAX_MATCH == 258, "Code too clever"); + + best_len = s->prev_length ? s->prev_length : STD_MIN_MATCH-1; + + /* Calculate read offset which should only extend an extra byte + * to find the next best match length. + */ + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_start, scan, sizeof(uint64_t)); + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_start, scan, sizeof(uint32_t)); + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + mbase_end = (mbase_start+offset); + + /* Do not waste too much time if we already have a good match */ + chain_length = s->max_chain_length; + if (best_len >= s->good_match) + chain_length >>= 2; + nice_match = (uint32_t)s->nice_match; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0 + */ + limit = strstart > MAX_DIST(s) ? (Pos)(strstart - MAX_DIST(s)) : 0; +#ifdef LONGEST_MATCH_SLOW + limit_base = limit; + if (best_len >= STD_MIN_MATCH) { + /* We're continuing search (lazy evaluation). */ + uint32_t i, hash; + Pos pos; + + /* Find a most distant chain starting from scan with index=1 (index=0 corresponds + * to cur_match). We cannot use s->prev[strstart+1,...] immediately, because + * these strings are not yet inserted into the hash table. + */ + hash = s->update_hash(s, 0, scan[1]); + hash = s->update_hash(s, hash, scan[2]); + + for (i = 3; i <= best_len; i++) { + hash = s->update_hash(s, hash, scan[i]); + + /* If we're starting with best_len >= 3, we can use offset search. */ + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(i - 2); + cur_match = pos; + } + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + if (cur_match <= limit) + goto break_matching; + mbase_start -= match_offset; + mbase_end -= match_offset; + } +#else + early_exit = s->level < EARLY_EXIT_TRIGGER_LEVEL; +#endif + Assert((unsigned long)strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); + for (;;) { + if (cur_match >= strstart) + break; + + /* Skip to next match if the match length cannot increase or if the match length is + * less than 2. Note that the checks below for insufficient lookahead only occur + * occasionally for performance reasons. + * Therefore uninitialized memory will be accessed and conditional jumps will be made + * that depend on those values. However the length of the match is limited to the + * lookahead, so the output of deflate is not affected by the uninitialized values. + */ +#ifdef UNALIGNED_OK + if (best_len < sizeof(uint32_t)) { + for (;;) { + if (zng_memcmp_2(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_2(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# ifdef UNALIGNED64_OK + } else if (best_len >= sizeof(uint64_t)) { + for (;;) { + if (zng_memcmp_8(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_8(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# endif + } else { + for (;;) { + if (zng_memcmp_4(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_4(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } + } +#else + for (;;) { + if (mbase_end[cur_match] == scan_end[0] && mbase_end[cur_match+1] == scan_end[1] && + mbase_start[cur_match] == scan[0] && mbase_start[cur_match+1] == scan[1]) + break; + GOTO_NEXT_CHAIN; + } +#endif + uint32_t len = COMPARE256(scan+2, mbase_start+cur_match+2) + 2; + Assert(scan+len <= window+(unsigned)(s->window_size-1), "wild scan"); + + if (len > best_len) { + uint32_t match_start = cur_match - match_offset; + s->match_start = match_start; + + /* Do not look for matches beyond the end of the input. */ + if (len > lookahead) + return lookahead; + best_len = len; + if (best_len >= nice_match) + return best_len; + + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + +#ifdef LONGEST_MATCH_SLOW + /* Look for a better string offset */ + if (UNLIKELY(len > STD_MIN_MATCH && match_start + len < strstart)) { + Pos pos, next_pos; + uint32_t i, hash; + unsigned char *scan_endstr; + + /* Go back to offset 0 */ + cur_match -= match_offset; + match_offset = 0; + next_pos = cur_match; + for (i = 0; i <= len - STD_MIN_MATCH; i++) { + pos = prev[(cur_match + i) & wmask]; + if (pos < next_pos) { + /* Hash chain is more distant, use it */ + if (pos <= limit_base + i) + goto break_matching; + next_pos = pos; + match_offset = (Pos)i; + } + } + /* Switch cur_match to next_pos chain */ + cur_match = next_pos; + + /* Try hash head at len-(STD_MIN_MATCH-1) position to see if we could get + * a better cur_match at the end of string. Using (STD_MIN_MATCH-1) lets + * us include one more byte into hash - the byte which will be checked + * in main loop now, and which allows to grow match by 1. + */ + scan_endstr = scan + len - (STD_MIN_MATCH+1); + + hash = s->update_hash(s, 0, scan_endstr[0]); + hash = s->update_hash(s, hash, scan_endstr[1]); + hash = s->update_hash(s, hash, scan_endstr[2]); + + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(len - (STD_MIN_MATCH+1)); + if (pos <= limit_base + match_offset) + goto break_matching; + cur_match = pos; + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + mbase_start = window-match_offset; + mbase_end = (mbase_start+offset); + continue; + } +#endif + mbase_end = (mbase_start+offset); + } +#ifndef LONGEST_MATCH_SLOW + else if (UNLIKELY(early_exit)) { + /* The probability of finding a match later if we here is pretty low, so for + * performance it's best to outright stop here for the lower compression levels + */ + break; + } +#endif + GOTO_NEXT_CHAIN; + } + return best_len; + +#ifdef LONGEST_MATCH_SLOW +break_matching: + + if (best_len < s->lookahead) + return best_len; + + return s->lookahead; +#endif +} + +#undef LONGEST_MATCH_SLOW +#undef LONGEST_MATCH +#undef COMPARE256 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/slide_hash.c b/internal-complibs/zlib-ng-2.1.0-beta1/slide_hash.c new file mode 100644 index 000000000..b9fbbdb69 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/slide_hash.c @@ -0,0 +1,52 @@ +/* slide_hash.c -- slide hash table C implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +static inline void slide_hash_c_chain(Pos *table, uint32_t entries, uint16_t wsize) { +#ifdef NOT_TWEAK_COMPILER + table += entries; + do { + unsigned m; + m = *--table; + *table = (Pos)(m >= wsize ? m-wsize : 0); + /* If entries is not on any hash chain, prev[entries] is garbage but + * its value will never be used. + */ + } while (--entries); +#else + { + /* As of I make this change, gcc (4.8.*) isn't able to vectorize + * this hot loop using saturated-subtraction on x86-64 architecture. + * To avoid this defect, we can change the loop such that + * o. the pointer advance forward, and + * o. demote the variable 'm' to be local to the loop, and + * choose type "Pos" (instead of 'unsigned int') for the + * variable to avoid unnecessary zero-extension. + */ + unsigned int i; + Pos *q = table; + for (i = 0; i < entries; i++) { + Pos m = *q; + Pos t = (Pos)wsize; + *q++ = (Pos)(m >= t ? m-t: 0); + } + } +#endif /* NOT_TWEAK_COMPILER */ +} + +Z_INTERNAL void slide_hash_c(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + + slide_hash_c_chain(s->head, HASH_SIZE, wsize); + slide_hash_c_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/.gitignore b/internal-complibs/zlib-ng-2.1.0-beta1/test/.gitignore new file mode 100644 index 000000000..96a3cad07 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/.gitignore @@ -0,0 +1,5 @@ +# ignore Makefiles; they're all automatically generated +Makefile +/switchlevels +/switchlevels.dSYM/ +/switchlevels.exe diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/CMakeLists.txt new file mode 100644 index 000000000..d434ec308 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/CMakeLists.txt @@ -0,0 +1,257 @@ +cmake_minimum_required(VERSION 3.5.1) + +macro(configure_test_executable target) + target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}) + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + if(NOT WITH_GZFILEOP) + target_compile_definitions(${target} PRIVATE -DWITH_GZFILEOP) + target_sources(${target} PRIVATE ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) + endif() +endmacro() + +if(ZLIBNG_ENABLE_TESTS) + add_definitions(-DZLIBNG_ENABLE_TESTS) +endif() + +add_executable(example example.c) +configure_test_executable(example) +target_link_libraries(example zlib) +add_test(NAME example COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minigzip minigzip.c) +configure_test_executable(minigzip) +if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(minigzip zlibstatic) +else() + target_link_libraries(minigzip zlib) +endif() +if(BASEARCH_S360_FOUND) + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + set_source_files_properties(minigzip.c PROPERTIES COMPILE_DEFINITIONS BUFLEN=262144) + endif() +endif() +set(MINIGZIP_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minideflate minideflate.c) +configure_test_executable(minideflate) +target_link_libraries(minideflate zlib) +set(MINIDEFLATE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +if(INSTALL_UTILS) + install(TARGETS minigzip minideflate + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() + +add_executable(switchlevels switchlevels.c) +configure_test_executable(switchlevels) +target_link_libraries(switchlevels zlib) +set(SWITCHLEVELS_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(infcover infcover.c) +configure_test_executable(infcover) +target_link_libraries(infcover zlib) +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + target_sources(infcover PRIVATE ${PROJECT_SOURCE_DIR}/inftrees.c) +endif() +# infcover references zng_inflate_table() and struct inflate_state, which are internal to zlib-ng. +if(ZLIBNG_ENABLE_TESTS) + add_test(NAME infcover COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +add_executable(makefixed ${PROJECT_SOURCE_DIR}/tools/makefixed.c ${PROJECT_SOURCE_DIR}/inftrees.c) +configure_test_executable(makefixed) +set(MAKEFIXED_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(maketrees ${PROJECT_SOURCE_DIR}/tools/maketrees.c ${PROJECT_SOURCE_DIR}/trees.c ${PROJECT_SOURCE_DIR}/zutil.c) +configure_test_executable(maketrees) +set(MAKETREES_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(makecrct ${PROJECT_SOURCE_DIR}/tools/makecrct.c) +configure_test_executable(makecrct) +set(MAKECRCT_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if(NOT BASEARCH_WASM32_FOUND) + # Runs tests targeting CVEs + include(cmake/test-cves.cmake) + + # Run tests with data files + include(cmake/test-data.cmake) + + # Run tests targeting GitHub issues + include(cmake/test-issues.cmake) + + # Run tests targeting tools + include(cmake/test-tools.cmake) +endif() + +if(WITH_FUZZERS) + add_subdirectory(fuzz) +endif() + +if(WITH_GTEST OR WITH_BENCHMARKS) + if(CMAKE_VERSION VERSION_LESS 3.12) + message(WARNING "Minimum cmake version of 3.12 not met for GoogleTest or benchmarks!") + + set(WITH_GTEST OFF) + set(WITH_GTEST OFF PARENT_SCOPE) + + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARKS OFF PARENT_SCOPE) + else() + enable_language(CXX) + endif() +endif() + +if(WITH_BENCHMARKS) + add_subdirectory(benchmarks) +endif() + +if(WITH_GTEST) + include(FetchContent) + + # Google test requires at least C++11 + set(CMAKE_CXX_STANDARD 11) + + # Google test requires MSAN instrumented LLVM C++ libraries + if(WITH_SANITIZER STREQUAL "Memory") + if(NOT DEFINED ENV{LLVM_BUILD_DIR}) + message(FATAL_ERROR "MSAN instrumented C++ libraries required!") + endif() + + # Must set include and compile options before fetching googletest + include_directories($ENV{LLVM_BUILD_DIR}/include $ENV{LLVM_BUILD_DIR}/include/c++/v1) + add_compile_options(-stdlib=libc++ -g) + endif() + + if(NOT TARGET GTest::GTest) + # Prevent overriding the parent project's compiler/linker settings for Windows + set(gtest_force_shared_crt ON CACHE BOOL + "Use shared (DLL) run-time lib even when Google Test is built as static lib." FORCE) + + # Allow specifying alternative Google test repository + if(NOT DEFINED GTEST_REPOSITORY) + set(GTEST_REPOSITORY https://github.com/google/googletest.git) + endif() + if(NOT DEFINED GTEST_TAG) + # Use older version of Google test to support older versions of GCC + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.3) + set(GTEST_TAG release-1.10.0) + else() + set(GTEST_TAG release-1.11.0) + endif() + endif() + + # Fetch Google test source code from official repository + FetchContent_Declare(googletest + GIT_REPOSITORY ${GTEST_REPOSITORY} + GIT_TAG ${GTEST_TAG}) + + FetchContent_GetProperties(googletest) + if(NOT googletest_POPULATED) + FetchContent_Populate(googletest) + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() + add_library(GTest::GTest ALIAS gtest) + add_library(GTest::Main ALIAS gtest_main) + endif() + + set(TEST_SRCS + test_compress.cc + test_compress_bound.cc + test_cve-2003-0107.cc + test_deflate_bound.cc + test_deflate_copy.cc + test_deflate_dict.cc + test_deflate_hash_head_0.cc + test_deflate_header.cc + test_deflate_params.cc + test_deflate_pending.cc + test_deflate_prime.cc + test_deflate_quick_bi_valid.cc + test_deflate_quick_block_open.cc + test_deflate_tune.cc + test_dict.cc + test_inflate_adler32.cc + test_large_buffers.cc + test_raw.cc + test_small_buffers.cc + test_small_window.cc + ) + + if(WITH_GZFILEOP) + list(APPEND TEST_SRCS test_gzio.cc) + endif() + + if(ZLIBNG_ENABLE_TESTS) + list(APPEND TEST_SRCS + test_adler32.cc # adler32_neon(), etc + test_aligned_alloc.cc # zng_alloc_aligned() + test_compare256.cc # compare256_neon(), etc + test_crc32.cc # crc32_acle(), etc + test_inflate_sync.cc # expects a certain compressed block layout + test_main.cc # cpu_check_features() + test_version.cc # expects a fixed version string + ) + endif() + + add_executable(gtest_zlib ${TEST_SRCS}) + configure_test_executable(gtest_zlib) + + if(WITH_SANITIZER STREQUAL "Memory") + target_link_directories(gtest_zlib PRIVATE $ENV{LLVM_BUILD_DIR}/lib) + target_link_options(gtest_zlib PRIVATE + -stdlib=libc++ + -lc++abi + -fsanitize=memory + -fsanitize-memory-track-origins) + endif() + + if(NOT ZLIB_COMPAT AND DEFINED ZLIB_LIBRARIES AND DEFINED ZLIB_INCLUDE_DIRS) + if(NOT IS_ABSOLUTE ${ZLIB_LIBRARIES}) + get_filename_component(ZLIB_ABSOLUTE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_LIBRARIES}" + ABSOLUTE) + else() + set(ZLIB_ABSOLUTE_PATH ${ZLIB_LIBRARIES}) + endif() + + add_library(external_zlib STATIC IMPORTED) + set_property(TARGET external_zlib PROPERTY IMPORTED_LOCATION ${ZLIB_ABSOLUTE_PATH}) + message(STATUS "Added dual linking tests against zlib") + message(STATUS " Zlib include dirs: ${ZLIB_INCLUDE_DIRS}") + message(STATUS " Zlib libraries: ${ZLIB_ABSOLUTE_PATH}") + + target_sources(gtest_zlib PRIVATE test_compress_dual.cc) + target_include_directories(gtest_zlib PRIVATE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(gtest_zlib external_zlib) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + # Link statically in order to test internal zlib-ng functions. + target_link_libraries(gtest_zlib zlibstatic) + else() + target_link_libraries(gtest_zlib zlib) + endif() + + if(BUILD_SHARED_LIBS) + target_link_libraries(gtest_zlib GTest::Main) + endif() + target_link_libraries(gtest_zlib GTest::GTest) + + find_package(Threads) + if(Threads_FOUND AND NOT BASEARCH_WASM32_FOUND) + target_sources(gtest_zlib PRIVATE test_deflate_concurrency.cc) + if(UNIX AND NOT APPLE) + # On Linux, use a workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 + target_link_libraries(gtest_zlib -Wl,--whole-archive -lpthread -Wl,--no-whole-archive) + endif() + target_link_libraries(gtest_zlib Threads::Threads) + endif() + + add_test(NAME gtest_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2002-0059/test.gz b/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2002-0059/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..c5c3e184b1a90692f1c2dc729eb106476d231378 GIT binary patch literal 4610 zcmb2|=3oE==C>CV8G$T;1@EN)&o6EfRlAUMpn;K@jYq;DVU#f%2%{-sG#8BKg3(+s vnhQpA!DucR%>|>mU^Ewu=7P~&Fq#WSbHQjX7-G5L2bCV85!7kBn%P`G%zxAfEl}iz!@q6kpjs906!lM=l}o! literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-1849/test.gz b/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-1849/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..b28f278263c0a3154faeb3c3dd7b083a3a593c8d GIT binary patch literal 52 kcmb2|=3oE==C@ZA85!7kBn%P`G%zxAz!-252m>Ss01LtkQvd(} literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-2096/test.gz b/internal-complibs/zlib-ng-2.1.0-beta1/test/CVE-2005-2096/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..11590aeab9ac844087776ab66eb2f5d2c9f6d013 GIT binary patch literal 52 pcmb2|=3oE==C>CV84oltGP4!m+X9 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-382/defneg3.dat b/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-382/defneg3.dat new file mode 100644 index 000000000..5fa6a0804 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-382/defneg3.dat @@ -0,0 +1 @@ +oÌ™Ì?ÌOÌÃÌḩÌÕÌ>ÌÌÌàÌ̹̘ÌÔÌEÌsÌ—ÌÌ4̢̙̑Ì6ÌÌØÌæÌ\ÌÌÌ5̪̲̕ÌmÌÌ–Ìç̺̜ÌÙ̧ÌÌíÌíÌ–ÌÌëÌmÌìÌÎ̵ÌGÌïÌOÌÛÌ ÌÃÌòÌÎÌôÌ„Ì;Ì”ÌýÌ’ÌÓÌÀÌ×Ì,ÌÑÌ¢ÌáÌAÌ9Ì»ÌæÌ‚ÌÂÌsÌý̼ÌÝÌÌ­ÌeÌòÌÝÌUÌuÌí̱ÌËÌwÌùÌ•ÌDÌß̋̽Ìt̞̣̹ÌöÌôÌOÌîÌíÌ…ÌpÌGÌìÌ°ÌÀÌ(ÌÌÌ̤Ì{Ì“ÌßÌïÌÕÌÌøÌÌMÌ#ÌÌí̵ÌdÌ·ÌIÌßÌhÌ_ÌpÌJÌÇÌ¢ÌÎÌÌoÌÌêÌÁÌ;Ì<̘ÌZÌÈÌÑÌoÌWÌ„Ì¿Ì}ÌáÌÌÌ:Ìá̧̻̕ÌeÌFÌtÌ(ÌEÌoÌàÌpÌÌ¢Ì(Ì;ÌþÌëÌóÌ!̹̹ÌÉÌÌœÌîÌÖÌ4ÌÈÌ3ÌëÌ‹ÌBÌŽÌÆÌuÌPÌ6Ì“ÌþÌ&̦̳̕ÌÁÌðÌ»ÌÌÌTÌÀ̧ÌbÌÌÒÌÕÌëÌ{ÌÆÌ¡ÌÊÌNÌ9ÌÇÌÌBÌÑ \ No newline at end of file diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-751/test.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-751/test.txt new file mode 100644 index 000000000..ef2143ece --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-751/test.txt @@ -0,0 +1 @@ +abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-979/pigz-2.6.tar.gz b/internal-complibs/zlib-ng-2.1.0-beta1/test/GH-979/pigz-2.6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0d76ef8757e36dc5ab02e579a99442c211b6d978 GIT binary patch literal 106840 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 z zQ1n|J5S!j5iKp2>9~XxzhB}$s6cj4te@4Ujb}O4u=fsK~95r|-4jjF`LhqAm(>JWK zkNjcmeiY}OoBKLuO!7=HrxRgIpcKwEKq*rF9uGdJ6vMcNDdh)!Dd{1f26gk&eA>8D z{-hmE;l_>rhzJmO?3JRht0S(ih22k=!Y)}f( z($=5Mio%E}P;yWQC<#wq-rDUMaIBJAAP%U-vGhP=%_%neqWe&K8oZ|?H6T3rQY=eJ z#o_fAwwI}(C&%b@V_0!DsAKC(Qq6ygvBI4-SL|6YqGeVCgJJW;T3p*c7@1;E7U=MW1X4e)zE2S z`3xR4(SKgijSz%p=JtydglKq4qkH0w4N?{aeH#qOXyw)JL8&=bO8 za2=mzbCMVRde<>w0?aAb9YqM!VAo$-)+__uMPE_eS(3z$H{KtmvFpkkg6y6kD9-QY z|5r+~%?IDK0j~2tXBj}1|B88P>jh80l+M1F-^#%eWZkta6>gGR#Jial9PqXbrl3NtP(sl$lL$(`cdf~N-4GDj9-1VR5}{y{H>?t(OA zPRbyc@2v1iI--{X+pk`OoV(g63PauZ*FJiDM#BApEu@H^IwKX-BlW;}*ZCc2eIy3l z$^$=7SH>Cc2CN356sFf$=%sLtDV%kY&68!#=2JlE3~Zoq*duluJ&3E<#MAj=aJI8#-$U64^)$>!Wkc7r3o2!orH~mQeY%1&%`w8r*%VV( z2txAk)Kj9MdfclpU>tMKan?Zut++ZE*6w7rtyEl^XzTG#Jfv0u2`?%=Kz_`J)X z+N-F2P$w8L7=o*S-&%Ke|NG;zWBW>5%d0b=fd$s2JHHulEvolhx6tWZ9$Jh zA!KOyqg1L%urp=RO=#c>FOTTt?f5LoF*;+Nw7C>(Q3#y*~^6Aztqt~b)N+1S9i)If*mb`2s@MQ%Zv|7 zF`gGx<3zItKa?($Cn^pzIl|Tn{dgTQKfX_&-5jKuEPG3Gc`P;T(kAhAFq<+7ViHb? z=%JlM4`=HAODUL00>*BYw3)r%X_an3cHBkh8o15hq-BYRCL%}NA+LO?^N`aD z2lJ4h$Oztw?=IT18)sIOPZ!6g6@1j-qhOY+BR;tRd{%|E#nW`v>4l0(CMQcZ^V4oWwCYOwqasX?vlu%t9aDllz3c|$gY zFYbb0(ZauOneexVI!LLZTR}>TSK5SM^G-P___vFfj{c=u4VG?j#KQ=rT2n}8ux4_- zbd~RAslV-)sh5Fm?+Q%f0r1M=-$UrXTkSvP8nf;^qOEPVAL&oymUo$U9+j`zUb+9u zZ2xu9FZKguZ&XO$|ces?NNwH|}GRBK=kSu41;M|=nK?fC4(E>IZk)OOXW=4br0kNhc~QT8~Mfj*1V5+2#r0D0yEH2DKXR(JG+k z;D#3xvz;%unNmoL0gkdYXC0W1ziE?w3U3GzMaN>O1H0XDN*DmTw6Vhe zC;@L0Tas7z*ux-+;8d3q#O9TJCC{v}lT?lD$E&{48Rw z>+yt-6UJ6%gCqaOpQKa;^Jjg7(s7CPmkqWDj&JuMCGZmW@_2^XG=o2LgepEW@zi*x zvoDPNH)TfyFz-t>PA5b&;?O|R4f&%p3V>fxu+2~%R zewG9tnB0m^LOe5>&SbZ8V@wdeg5ou{Ra|^ha{CPqR-ijI{CrzigY$ugBsvieZSNj? zx-U*jk^5tjn&O}st8CB55yAI3{9B?-W_I@ThOk~O$c0{SG33BdQG*KzF9aM$}LsWrXb4wdJna*Ud1 zbXQhkuJPO*a?techDHC)&!WNR5jDB*IM~yvtW+ZlQt2o}iT-A+79y1B1WZ+Wzf9ER zfVKCQ?2Y4T6o6pLp(SCcY+6~@(IE8I4|{0gu=Sst8>-q;*7Z+AvbT5e&-WTGhh+hy z{wmGu!&S6k_)AJP0(k_ZLC{_fRyPvxU6-p=e=8gAUJM z-FuUw+P9krOOIWgSt%;#1@)BP%E9k3%knd{uqU;3%!t^#4^G632MugugE5a$>F znhjev_WXUCjqFL?kBuGlv5kE^EH*_Ods4bzKio19_)K&wZvHG%`(tCzhEW!JP*X;B z5c^|f&jy*`@rsupZt==EA0vASHU6arGYl(uA|~>ZAnYeVrS23?UYZRET8G^aR0oBJX9Y)=($HX(DrtO?v`GX; zf#Ux#yBrz@8glb=^3fmakl;Kzje1i_;N+qr5GM2ztw!c45Yue1%c}sR6DS7%w@%8q zfbYdPIPo-ebZkCs(EZTr{*{|~a^k+70y-&`3w#QC3bav|#Kulit zCRuP4fCQ#tP;_a{0jdi?aXh%o7d6>Uf@9k7)uZVaPOsaYCBru51BSZ@PfjY&$u@1V+co&om8a#S z1>N-(>A9P|mJh9RmrE^dmcz1S2!21ch6M~*=vGOD%jG|4cYBUE2hFLuC!2D$L&9m- z9>HF_S>AwrIu{floOatHtkDDEW2&t`*=SnNDtwo4bbKdJ|&d9ee!9PdL_ z;9@DKLpD%GNU=zG)_@~>bP5Anj6$~tjbxoZc6JW|U88JqT?NHxe(UhR2P`{7z}Hxo zSNrC%g#5RIH8_*_^IIU1`E_(V0~XD%qW}r1p^V|xkV5Pju4TYy7{dsX6c`5=XTvyI zlNkYy3x^plCgsQbQQYx|q{NH|lkRXc<_)gm1%i{3<6vwf*o~ZRG#4dHZYxM^9GS7l zcnqA&bug%IC5&!>Qsp+f7_*@X7?`h4nO-(!s!OK7OQvG{2`k1WrJ8VqmuhAiZ90=7 zzTLbhEEp>6RRskv&8rL{jAIQ=UE5sf0mLhn=sv0L7^Ly>k zygL3!obQ3xDVg(7!|ivUXq}0*!(}b-p42<}1)9z{e7g89x2`HtP!ficzwnUD1%m_m zdil(#Q)|$d9Pl$^VRA{Y*GOuhE-A@1Lwu65%1|K}$ZJD5>Dg@YAKh@* z&AlW%Zu?y7JmN!uY*v54UQ?KlZi+INAM>!45v@p$^o@yR`TF zGG7aFan)#n0K4oje69ye+J$V-przTkIhNy{d@!lz7H})0%j?S%y-&L>&Bn&Y{1=f5@kq#;M4bJMaG&A>tt#0fBf0}b@G z9(Jp`<>22aoI~1Z2+9iE7w(adk4qnW6LoM5p6ql94yDQ=Dto-;A|=YZG9uFdCG{pt z9%Fkgm|t$=%=1VZ#1t@>@)%12IF@Rb<2MdEp?~HvGOO&Q4vuNpVhSlEoY^bYl%ZOv z%V(`q$-p!RkxZaZQuI#i4G(%iCagpGu~nO~^W0EPidBbHOSuxAWPf^a7v_^oQwS*udPA7cUZ;^TpMUCa=&c!o5QZ%dqr2vLGJhopSu}tR zWqzNw(~e;mnp)ck4cmmEt-%ty>6Dkk5z5ug{8aE|pgR3d0{tP*Oi$xkPA<@I1q zoN~vAs$#Y3t5=<>Tog~d-P7d)M75eogOwF56}B;rQ{5zVPupX=ZY%zH?JZ>g8BWNw ztU-_I3}RT}!mKT>{%N;p-2}a{gZHrHn~hrX>s`e(I;=&3XBsW~@aa@4c|q0jGfkaezqY!6t4xdCa{BvlahKpC@X# z{=){J&x3~@U!=}9cA0A&CnilPcN~Le2Oo$r3Qrw;ThPyew=wyealld}TCFzh@;AZ6 zN?G=h?JdiQW}(X->p>Qy80WTXuX9y+$4cNJ1ELVP_~{it9QElX26A3@K2fV=9(&uA zB97s_SW*h-6~$9?epwGLiq#)L`0X+nN-c`1qNe5E1&Ep)s~tq5{$t|@1b_3C5f5^V^yIa$c3~%M~?g7hPd%%Y1l@Av4HO&0>lqL-mbUSgM-@ zy)Q7q;p&R;a}L#9Uc(xtG6yYsgG0y#I+D{XF->XkQfNv;x8)=bp2B`==I)bf(bx$q zqH=VY)@J=#YAQs%;2Df%<}dsIr=fkvrck0n)Bx>k>?1bKd4;`57N~02OG%KEJ_URL zRSY4fu@!xItU^&5yFWT*IEAD~3e1ToGY7c%t$MN6Tc(ry98ROcX;0t zIGh}-2o?T|FrmBVJ;wneN!^MaiQ&|aezakfXqpaURLqK~^^IVOq2i3#{lmo>Q?`!b z02cAp7{-t;b}RfQ8EXtfU}sGn&Q1wJz)${-azwVeV`*=PmM&M~g`%T|#joGU(J<9Ve~n6+pQx0h3NemKiHAu}-l!A`ifzE~hUK`OPD*Uz z*Bt+jO4*E^7ig#Wf%#4#e=qi>CM#Cj<^=_YlfB zoN*Qn-+6;p`jn{`ZPP@jYAkyfdpoJkD~0M{O6Y8Ojvbbu+&d*hbsk85`6p*}Y4Ji9qO_H=KfXw@Kh+RtM7Q2k3O zX6L;+Ef}ZU@OD5b2aj*NGWg*8IqMF8O79sS*{0Q*qztdmH(m)*B}$(5!Qv;irNl2% zJU(U(UR0Zc-IK1M+>pnqxWYq)B2RD6DX=%*N^`w0?bp+6EL3-&-%C~RixY2-rTz48 zHOLrn{E;3WJ*QOzT}vr0|4=-9GM;3gIuNfvxf|j$HW%|gbyg0KeFWUgd3PO`jnuCL zam%3z$Z}Gye!V~~9$d25Zkmqh{M$yUrEao`av}^(Lpu#gn>QhUB%V&GAj$)|6^+Jl z<-J@=8}i#S=uVuh@~%SGTl6hq^MKNyo)Xt&wzjB8?lVgulLcm7*Q$JlEMbx;W2r)8 zZi00y`21SH30m5(82eM%J@ZXHuBzNfUAi`8SlG>QvV1p9j-E9BDofO=urFnlVzRTO zRLNU|Rmt0TrJ^$WwB3Fkh~^9fS<80T^SDl^ILKp5tB^&TMGp96Y5;tJ2JlTtDl`lOQ9ICT?vddI1C&Cp}*N4JI{L)R4g{&U`gqY zw;}xhn*z9A1u#0}bzTKfwwluaE^=qS>Yoa!miqU5hJUGl@mz}b;9>a(t?FO>ERLi| z{45<1WJ3&dL&Gww`E)l@!WMHq=0C|-jr(ek1Bj?=qk$1Qo&U8JTewM40VDwA)9}M^ zKbQWnNl=WN;dem;0qU1CD|`0gZB9n4?ixIWX6MX`kXn2|hUZKVZM-(n`7kQzXT8*G zbqZ`WkZ$Nb3^&S$dz3Px%WaGX(gVG^T~oX}Zo_Pt+ZTh<#D~UhEl z18BiT1GUMUevFF3>u;cx8JL<4!8qV& zqT7+b0ZJj!eR^2utc!iRcLSx;uKW0EiFSvBm0Rd`P%v~hkDOAq z4*KNs!;))u(|UO_87eiKq^{H_zNi*DNc6DOi1t8du=50{$!RDeW&<6RelLv_U+D$W zYUou1*VDr*8y8F)ru@~vy^00VmHqsh_&CmmRakOgbZXVlb;F=@sx53AWhvF}R5X#N zQ%K_GQ>ctPaMQoJDY-me!L%^`j~XPM&tJQ)%UF^d^&zipM?5=vIq<2Ip&_J`fmqhb zz7*F&=U$~w25MR-1Jyq|SvFLLbP&TjSyIwlc8y(D$wCGHsFEc$&POH729*{Y?3NNX zcoWb0sAPF;-75_VM6>b~itaD1EF1Q<<^?LOl_j;RPlH!o4eHm-^So+VG`NpSD@%Ic zk5(1}B$ZZ%hOkx!YFaD%^l8(*SNFm0X0@OF~JIXN{GYJlL&>z38Mq+Eda>hdK^=U%d-dgIX=ml zlTxM6Xr%f_C(8yIDIq9@YnSGtYvIDB)XB0Tnw7GotcM*?Qo>Hn?ATAxDK>OMx_OeC>YJ4=ZcvSpN8d=iOq>_c;##G5bl{@`EpRv%% zf`DSGWJ#>?QOS}iD&5B&=90n`=Z^TH6eHJ2Ir47!>bs?qVbPSD<@2F*vQQ2J>SRed zX9ov68tr=Uu}YSN>ksfWXdjI%nw~%!S<=xz8X1sg2=|mS5=Qya%0eJZ-vt4f)XI|5E&qSDvi;G@Ci(iS zm2IY3Dzz*+izkdnWkkJC2@(JMf6no5y(}JMNg7hBgkqMRp~nzhe4#&#dxi_~TGSD1E&eyg4}7jnuHnN0!v&%yf&O z0d(@yAzUgXF;ILQy>(R`4Y)r;)k_1eQBZ@_slgo$DTcfh9}ielmn8d4^}}=OZ-OsQ zcj0K}P@qRl<%?4 zjUgByY|(#{srG4Hpc{xEO^G(Rwuz|+bxr+;gPra9qC4()@SL7Vg9}p+LKFxULX@}> z{3O|c-m{E={Cx^YpNu7F2JLmRZ0=79E4IA~xp|{(_%d#V&HeqLS4(R1N>w!Lr^eE^ zxj9%|BzI^2jjU#RT-o${YDTz4ZUkI9ZDVf zOuin&h;Jzo3Jem*2==9F60FlYog^|Fx-j@Sw-g6)c;Zdkk7SF}ftUs*ejM3^8drdf zKHDGikv%Xu^R?CSkQ#b_+D;YFlIv94wSf@ENN4UiE*OV>w=JpX!Wx2!Ig4y4bdM(5 zq&lM^(pWTzx0}0;&8>KX!>Lqs5l8HH2=1wgU5V+UTM^Q!b&T!mO4DN%d7U!jIF@=F zpOu!SrQOfSm(@7awd*~Z@3@YBf5L+WK4=`Q3RImt@L}}(sIQ?Ae26F9&BQHWyV9OC zYj3X#w8xGVHS4Qa`6V=*Z}%O)sBgr+<+cSw11OrRBwszcsa2~@_ccmX15zLfKTeJ9 zeEgu0H~2SL{Y-J3l*a~NPUlTb8_2xk*Sm__U%d3;&_!e4PBzy9wzTWF&MH+L~}5Qq)^^NaEBhQHm!K^URJ)tDu`N{ zp~US@0uwH>jBsYGHrZtlDAm52+e=dpcCT?+TvYdd-r99aOan^{s6Wd0U0vIzIK`&U zO8r=rKIj^$_9%;`-cW5Rm(5F5^}^N}tcus<>v zX~OY1+G^GoBFGrKf>+*N3!TwRT7yHeOj?nA3o^Atr&VKf5eoOL6LS1{fuMN?D1AD1 z`EdE#wD(82PS@-{TsEN^I9v+JF+kwioGKzhSnQ3p&Gc*fDxdS%C-ijf&@0_-+Nah# zPdUE0n4p%<@8R1TWkU`s2zqmPB3^py&|7?S54-V!HhwCG;QAfvdtg?^1oKamavI=b z0r$N3+Z=Ky&2w@6NG^;L=(zs|Ek~2PymRb$Kf6RUPW(_Zy^?h#iH>5kg^9J4G^zGP z3AL>_MrSzbfY)HM25?$6}xfa-U=QHBi`;%i@7tBSK4{+H5eliv{|a zRr|U5E+jGsyCsQ3l>Dw@t?Z?kXK14Tut6zSQ{G%pxg^?`l03c&6O&(`3BBQk*re=| z&{#!(T~6#eWCzp|sHFzWZl7xU5`G4mAAdx+d%PldN^D+=+8gn^qY;Kpi95Vov99SiF>1&Kf)An_#cXe*~{o445P(@*m;(Von!+ z30|t8Hf>Bg-9Cc_@5#l2L-aFoaO{FB;BPhTZv$P#%0A!*@!_1l*%gn{T*uEUOk zL543({A18}#|V8OJ{H#Ui8=KE5Y+!x!?jGVwW%Up2+z{AuMm(jJb~3JG59>m+5Kp-Q7(TM;Se^xN@@^TfgvVZG z4bH=D7E0+E9vl0;36^Qxj89_5B6uh)QT}f}iSzMET!uK8PhvI|`!1hEuE*CQF`JX% z$szG;f`2L*3WbWMV}mP4 zsnk+{+zby7#6yJY^2K^*g(V#JCEVZvg)1kGbuRUg4G)dzxx{ubaTkQ7%@hI=R?#+N zodPmdY*mCqG(}SIkO%@5{7$5k2n}7J9uDPK-^$z?d}Gwn0|9%nRSd4otqM3LzBDN$ zf}`1oNwbkFm?8}g&&1Rw1+NW0WUNZwrq`!0dKGEeg(ZfT$8RGrJbWJiez{T{&6HGoIS3<4aC5u_)Ql8+u;&B4W@zg0*uUThY?o;Bsq;nJT`Z+rl zr;OSgv93Y(X*^}_^tW0{eq0xhTKv?aE~#xwgOwOS-2yG8V7HmHkP~UJ5KhU2_oF-k zY2n+Cp-{s^=c#+#j|0U!7pF?jw7LoYYvZ&EZfGE^EY`dVG`L*HS25)n<}@$v!(Uy=1}!fJ5Lsp!DrX~cfN1M zLj1q#uBAtg+X&wm(0}OTZh&~Z`7B;7$by9=hiH8=a#CVLfMf%L1ONT7>idf1XlAk* zNI4h_EI>BN>8>ii>Z=EJoptv}TwxG6J6RZuX&>VH17^Hf-KM&s_QpI(@9 z4RB9se&gdMrOdc@5L@PFQ%W$s?1=QL6+7))G2vStx6}enH*d*BJlj>kLP146Mso5cM zWrOBGwnQX&ij#B+5&n$2WWx*bCW=2O;BWU87tfUZ$BbwOp? zARPOmCr5QKQQ~&d1@7K+^7Q^sQMgkUN81724ZGVZ;4yCYstgBZC`y$k=KN5F>`Z^+ zOL8@Sdg)WSkhN?kP_~YLH#?d0k9OAm6hRj0-PlYh@#p2cL;TTmcoy}IZkSd0F=5Ug zce$*Y8Y{7DQj`PNG$`r~UUPfovkcB0o&Z*P?7bYK<2eS2R#caF1W;NBoaS zi&6?03ad-zaN#BK)g_T3rn8gWHnM4Fq1~U%Gm_c>My55-Ipy}Mgx+tq+zzQIWOl=* zHxE6P(6$9#MG6AXk)~>}yF->03N&$O)8bvKZj$EBuJaB2VaaUu2|ES>uk+u^`THfQ zo}{W7oix{=0#35oOu0(#FxP& z;W1dzf+=UAzom9)xJ$=l?>)eLxvk$7Rb%6`g)<5JMI9_y?{}_1ag(8=mVl@kHEv68 z_so1)^2VLR=G0-OYkp04JjB7&slFjTjr7;?(ASvC9US9a3U{2Peh5#*H7-z}Hzir* zUKxG|2m;eIX3expIs5r;9DgzfeCIbtlR6n@*L<#U<3%km`J|Oj*b6KE=FIXn5>dP6J$P%FsUx4kF`z&&MDQ%alw3@ z(ls-ywfpWjt$-T|4y`ziB9$aA(5FqN2$T|r(}eO10I;}2p;1lG)(ApXwAywU7*7?G ztL9Sci0;ipD|Z{;euvX^fq~NH(zR*3ewqd! z7sV_6sK>uDrSexE<7*!?p;+tBypu~Nv$bxJxf}s3zg(*Z3Z;1u^LP!TkZNi%WK3vp zEL0Q)kjTJTz&N;>6g3tc)s0GiB664=of5?%%gzu=YG78`M6-YAQ!W$}_?roWl=|`{ zP%&}mT8@4_)Y-vH5R^tFQEjNR6W zvMrEkl!?R(SaQGzX^E7HU`)A>Mrl1Ds8I%KLXbiwq*d-oZ^oR`yM;nm);8)68-!(o(a~{&giv}zPWT9eaXib?1dB+DH_u{*;@L{8eFl+XP4!B zPL~H|3Dna)!8uFk^YRQbI?&)P+IaQuM<02+p&;lww6bmMm`+0WVuIw|i4-@;;s-S@ zeY{Xt@pa8gu&B4lkCW)n*<3{1(8UwNG?&$K=C>m*k*BR1lWy$&0lcQ77-6})in)iO z=OjN5@8`<{_xGJwp;o{9x1=nuoDDw91ud`3W8%%wP(N!qJKgmT&(`r7`*er;n+Ban z%Xcn4-UCWfkaToyFQ+Ex50i32*z^G`2dF=~ly&(Or2ifdhqdh7a3U%snOE zy|`B3A*(2b==nhgvnVm^PH*wHF5_UaG5-1d?3)idlW1%{4Bcf${xMa@Pj_xJFF)VO zdItPUlCe>j#FRe%Wt+l{{)WC4nrX@@i zMsUFp-mUj;1Ak_B!Bywy$1(d_l|>ls{ys$ygHy+@_F2SR7BCq@3$A)TIyx<9ZxwQT2R2`t&~ZUMQ7|UzIh5tMro6wk?wzY5oN(+MIgiD3$CP zw7AqZozyn;5(yl-p3|Iky01D51P+P!IbfM8N6rZ~U{o9~lD)Fkq!R{u`c+Dauj8OE ztu#a;uEx|<5s-Hpk4KER`#xC#rA2Ia(vopbK^{jh_bx3SzJPcgwu7SrQqg5*o#u?R zVr(g;<@ADg{*%YVrJ%Kx(u8|#16eWdIk+>pQH{FSj8{Z~KckIo{KNTX5D*j+ z77?KlGO)HVbhLnD5V8H>ZCluy5izJ)*b3M>S^THqFSXLvS=hwM$kD>y`D6WzEdRj4 z|Kc1Sot%Zt4IGJB*gsH@2LDlDWc)xqs#zF2n}1+6Sy=voPX2er|MvdBEB;>-{5#>l zI{#m_{6K@7IT0~4!7)fUe`szbU~6V=LInJPa~*xCM>h=}pSjQ`I6LDT%ZVSmYz z_!l+$zq?qO|L!3R$6sVA8}nbRCll*mbNG-k0f{(RS&7(K{z6Iry;xX3815YGAF_Yj z{HOf?oU$-66R|S=)%If)_J77?{X}*oB37B1|4RP$U}t32`LFf; zmHg-Zl`(NPFg9>D_}GZQ3VrZZ|96mghW~)UvjJIvEdL1&{Xma0G67jw{yPFb{nQ&) zTX|{ajq`qT5TS3p8vy|U2tk@1NU|L$WgIVp%KlwJUI9fu(rVo;oSd9EHF@y#dGkAM zU$XGHrDB}vRw}v8EO~0a#;W-pOGNKG=Y7T=X2a2v@7dCO6;`H4=5^-p&V!DF^k+d} zB=ey5!*osfSC!v+=Ta+){SONZksg+kVu{LKEO|qggP9#a8OJaRNQW@Ho@L$$2k&@; zkg6i7spyPST35`szU1Xcr*h<2_UrOJy)}L@a_eF*rRMlErbbH;Y3InaeZ;9Rbj2De z@^!*Oy*2qOGv9d(W3tcW%R=3Alut!u&5Ra~)v%p~t+^+|n9BF7qC8)Hc!WhSI?s5w z?Dag8o>~jCmT@FC-Q4P=PJ3}Yc`NFfx>&_Uw3DEL{8i-%93e%rytB8Fa=agq zrmFzRC_S__9yJ5o*PDJ~~EBKX!T5cxi&Hc&DwN=XFe10#pajS#&jKY`pz2wZ; z=Eh-u^76TBL$|(X-R*^^^N7pu3E@3f3TH|(p08#`Y*ej!Gtgsi#*HjX;2`Y}aT;l^PiP1X-pJ|oU|>G!uPJ@uu?uA7Uy-L56Ss(0P@jzh)DoqeUng*u3LYQA~M z!34LIdp(z~cRl(IBsL|F%*O?}720e?EaRi&wCw=vK8G{IW%F%aeOMsOCD=rF``#)> z9p@-pVsYj~VVRUhg(v%%vX**KYXsd((ZkZU+4Itc@mq<7HOo5^r*N1G<$X2k=o+n1 zOGbj>S^AyXv0r_aBLU5?t!i!)G`zz2I^I$2edSU0PQ{U@*O*loXSJ6KuQvuAOURKM zExgP~w58E+6VpkL$Sd*q*3fIhQ?+AFMT;*7QtGBG#~4ld82D)=gFYP0LNa zO$BXuue0jsv3Euq7*>(>dSQ2C)4cc=UE@tPZCYmo>i1(CcCHsEZ@}Fpic>43E_XDb zD4o)WgZ!RntXII8`=Dq>U~U|=5BYRUD2+ycb0z%BEw(=Gh16kB>icNI>u z0DRLmS!ZC?f!a0918;_|*))y|xla6KdEItst6T$PC&$&j1|?1GmM_)mjaq)uw|y4m zZQ*xWmjR~2*I(&Szbr9R!`tg|G6pf)!oIqb$QPA}d@`*%s`!-aKSl92nEpmepHAyH zgn_-l;v~9pW1(ba6}X@hM@=D%&1Y*pko;#RZ&XqWBo_S{fXHXGJWU(~4}*yRW35R} zc4|D5@Xfhu?WlUK9MdU&#C-ZhIk+xe(NCj;AztIltjUvD%sJ`k8#FdV94#rRl<``4wlqQrz~$nEwrarc-JDl5mi^Clnm!|j!!S+oxTxzYESyfHFz^iYx`-XlFbuDs8CqOMCI{BQ;w*i9o z1N%zY0<)tZNWm%PyN$%GdG$F|EH$--_5E>)s%0zcHEgQG^7u@aMvwb&Su4Sv(dj%k zT3lz=sy?pHaa|<_o-*P#{6%aH^%ZCBKS;Ue$Mn#S8}=dC3)k^Suae?JYG1L-4QFHV zE`RX$o!>Y3^li7lcNYz5;gVnqg}maC=O^#R0&{dNp|`e)_mdLIy<4i8yG?UYEGx=$ zYGWq;eAggiZ)3}!k4WXI9mD{zR@Cl`-+TI{x+@pl#$I61oy(ul>Sf^z>pf3)vmg5q zv)1{l8bxe}?6dhvzz$Tjk^?9MKC=k#Yp%{PV4dL|GlsX2ASAHnXut3NnB)72+r5oG zrEjYewfJ?G?iVdm&C{TGmAtJ*_~n?|s;ZtK5~$`SfwfIT;J!2ZjdyAid@*YQj!*Dv zz@0Lsz=l<(PH59p4t?>!S}%%%4p1!eVEM{A(XdPPc$TC4Y~RLm7OlxJe)fH_wkElS zvF}%z0=H#_yC(2q^m6A5Cjy2mH+=dkFfWw*>~xoNR!Z=FgfQerB>03V4)80f{Cv~9PaDcPhml^GqUF&{^3zu z7(J8w_web;<`GV{mjMWQDg8>$&w|#uRfAinRkucnP~?kYE#c}`Q%$*}dJ3EkqF$@9 zDvCbZ;m7bL07Hx7M5qF6t7_Uc(l2GIgarvP0I@829r`jK8*)Dpl{D=2FE~FQtAl_R zLZ%*l!NE1JHLPRyt&d~4FT8D4Vnox8&GnroVc30ooAdisr8xUD-Wkeu zn{}e=)QKvWpyOB{NBg_T)645?8ZPjcm(mi}wzJ5`$*M|N8f~h|FB)qz5H753J{;?; zWhCXjlyJNXD5NriJ^2myr%1rX(uHG|AXVGbU($6c`B8O)vccA_7E1bav2@uh{lTHX zYz4v`))Svn`}Z`|)@D`pXxOkKhVuH^ksaRcF%@6>xS9>akWyYJNQE%p#SIwH?nr9! zzHfvD_v~>7l1}C~dh$(D(H7(G@6-cS81t*@+S*#l&qSsIR#|8pj=JYl<(1hceSHS8 z>+!zIBVQNGTNwpi20>W~>lul97||tG;G@Wl3MpU{Q!{~U##{LGI|>(xa^rFHSNPGu zY?VoKz3*3ZSx= z6%gU%?ReyUQHi?c71kQUEvueCqGk0Oo{c0`NLnfHISp54Vx(j3Gh_|TeKO?thX3$g z)|k)Rr>-S6X;pAdf@p8&H4GlZ6a#CL50M*G>bL{nITcivdxUP7JSxjJ(gjBmVXuid z5_bH9HLo2kl<&5wdzT?TLuNO!T6l0-N;NOpgJrkURN2jSYez4`b$o$hh(Q<0(12;m zmeyKz%{7;pg|1C5`bfA;g}JFArJUk||B6W?rW*Jpd9|odi(l~cEy3wL#_^gFC9PnY zY+yyPUb033gs51aWS9Z4Do`gKu%uFzs8IxADAFbwrU0Z0IHW)WinKosa{%!9$qWPB zRFmj=$@mRw~z=R@;#0=#CEfsElagt#nfH}W7&af3Qm!C{6QUPF9l#Vs51qe`; z78L(9{0T@P$5ZNtG*q4OyYN)JNxRHcNRkfxAi08v2!LPWE;Wye%O|kv!z(v7B2Eb18Dg@A#u6mvV>$uuD1w0hXj3G5|}G4p9I#DTf4rnxsQ8AW6z01;CZxtPIi@MkDXtN(<#DE;hJIlC=*B&N&cxN^TPAu zED^;4#hK>hGYH3OVg*OSb76&O3up@{GQ_FU0J2i@Qj%0*WeJv8bMP7WTnAyJaO$wZ z?>xV=9dl<4rm&|eb8D-Mz?E_DBB2scFwmp&TT$m3_?3lUL(nq>SRyr%zTygQz@THG zA(G&Vv-m@w$SL#Z{X+kZdYjkd82+T##VgDyydvBY?umL!HkzBm9L{7uPAKe~>x}y? zYFO;GUARP;N_a$=FgM?R)?J6Gg%`Kurou#Ur>F-W!{7fkc)44 z6E;a#HCgd{Q=55F_t%%r_HDkXk&7W6R@9O{OcGs6szup4><`UXbykjKPDzJjlW zGt9zVzfhO{&KOq4MDwEof@+ng^RWw&t|4GC)(|}3hReaY8Xd9AmT&Hk> zntk;6gWg8VtSI#X<~%NX9}kph6|ilo{ADH2)VT@5G+~M8bflV+LJT?QW~g*XZMXsv z=GDRTj{lgWuo>D!fiIn~({SC&d`C)gxF#Fg1c@b4DMhLTOAxt^Sf&g`s%TuMq|nlA zlx0}qkG8lYQ32e7)MAi1nu5tP&LPYA)#x5z z3`Mi%xeCU#@LcTvl6{lc{9g?YMCBcpSKx4QqUj)_h~Q8#P(R!Z?!Hb=WzSYu=V7wM zn~N_KCl2c8_EsAK%;lFAAU@pfOG6=Mx4sEO8HgcKW@+vR6Bru4_9E4=JAD}MJ+E^p zey%lcIlBS_ZaIYlrUJQw=rVEce9*9*QQ=&&1xs>_=oMOlVizFSm;_k?O~G(k7sfI4 zjF}(S;8|LpJ2qli0w4yEBEX;Tkrl;LK!{DCOx4sZE=Y+~5GE%fjSbK|E-8qPq>dHr z4_D7#V;iHHHnF-PY-II77I^>s^2r-{&8_+s;{o#l`T_T@%AY~u9%?iTA`1*A0HWFt z?gh%lPxKLe+i06~yDyn@lW(Bjo$u2o%qGNLUnBAh{Uy?+Sp54ZUp#mC2cAo=6Yh(& zMeYl{?Jdm%FTEyHPd|uu=+{!#wP(0Xrc1PAz3*pGC*T*?(^CR`@UM}#(ic?~P91Vu zTJ3Tg2k!T|7gfN`xNda*Y%gTqFEE4&*C>|7kx8Q9mpaK*XPjR0(7eRK6CrG zJ}We#Hv*@@zWYDZmUY}~F1laTlwWV!Xk6GdSzm5Kt;4>cHA6HLG*8S9dC@#zZkyh; zz(pq_LBuNu>aycpQzE_IDF z_clyBC)yUgL+`a&`@Etx4>!i)JJJFxdg|7+g7AV)g78+CVCYU-OghYb2A&#D)|R?D zc!87px>(xi+H0NU&EJ}tnoE65>_wjcWZSklJ=Xp{UK;awcGRs+zt@_?Xk71HZ_lrg%rF5#hvO#@57O#4r+}q!>*St>x~%mbvb9 zKN!3Ba(f%|$#vIFUAKr0aT8Aw#^72>{UN97unuo`7bMY(Z)UvO6<*l)U8#Uv?{FNo zhGn2=PrK9zq^JKeU1o<9(KPhDtCEzg_0oLI6cr&Eb`5RrM1XZMMO)X>Jn`Fwsz4XZ zEZQe}ilFqw;d#t;z;usIt4RiSd3qglFG`_b%qjs!Wa`%Mqb~M)z)ruOsf4-5}WDJ*^$>u z&DEAW*H5nUT^hY8_~9`plKKj#I31TM{fl8w$(-dkj;`XyAew;%;-UxS2F=HHn>F>( zVUWC}ii~>4)nI&V14fQ&4g{Et8~ns{KAYFz>~E>Mx}=Hjp~!-<+6KG$2SKk1#ZZ?1RNclzpOqn0y2-N9l0Qp-8id&Mui=LRLQ}$sLge`~ zWdkU|KmoDcpNT#J!1@B1{SCV1^*;l#DIuZ3AOgVn{jxs|!~F60<)@#^A8BY6iJs8%f z1Be4KEq^DCxiHn}*QuI!&O5%Lw}a(({O2sAcc)Xo|5^Bm_Q~wi5KgxPw0$}l{{O4l z|D3yHs^*^aj(2GDVEGx}E6eD@>C`9sukd~2;L`6w<@v&OoA1SOD!m6A{rw`eQYz+o z?ss44#G3K)+Xm{Yo+k{x^;Zbp zYDza`fXQ!e^R&f1_`O@5dzTFdK?Ld*Wwt08GnevAR{ghKyQ>2drt4+zMt{0_Nq7Zz zn5;U5)NoY}X%?UQ1(HVfXDp1dWyeNvy@;G7QOVqM+6vmYjseL=P=%@0vSwp+MT~dl zJne~mohVHeI9qj;JCj+ROzKbR#EDaUSNhCVk5g~g9t$Zfd5#!Dnr)kkgH6&`tuu1MZf;@KOzKyBITl>Jo3HrO-4Cvd9I|G^^7g-%7UuOx?w z6mNX6=E{1NbR2Z=#f{hd#l2fa(eT*F8{xt>`0?_NeP`%;*I%Yc-R1KJve#T zQL;gN9aT(3G*0>g0&n&v{O{6!o{_mLPssQz+H}KmD#}Im2x`J9WmN>JrLr8>@@x+g z1mTt1Lu78E#irlE2 zwAF0nrcX1LnR=7NM*8__y}4HLJaK@Kkyk5aqW-PSau4fc)SCuiZ|QXm)dArX_` zrU|wlh8wG5?9s#H6D%BxjMr^AN=pW3zp60^Bs5|@%tZDpYE<^@2HNXLt|yO`@dJvB zIrP$FL~8P7ZQ<0lm>)Bx-z3SW##zWfdKg+Xb^HV&ma5L#;^hUcb%{hMEj2+f2m7m3 zgpZmm06$I7{ZC@=0ZS!ARaA?6k+&SuI%c9PaeIbwr-PN;aebt3JnQx6L9HsDUuX>3 zVHAJH+1Rr0pEa)a!QRC$DkQF;OMkOdmfw5`)1{ynYaq*JqiKM%a z!(g)iA=EEj{&9kiWEOdz%vvy4F`JSbH51ItCYRy11j?Odbz?);;>td82^GS^AQ-5s z=^sip3YE@Uh_y()Kj&%F_D)~nmH1*TBErp{W}3BBMK4517(INnv&%|urkTsNVF7Y1 z_)1pDDI<|wrfV0;cC`5uB(mrV)h=n6=f;fHvIlDZuYl%fFq&%}r=7vgRqO6?9xPOU4-)|j>!0rC?EF74T9<= zWIb-}n!A&vA8A(SC$1DCf=PfYR;pbq#r~!Iuqp{di^99%h-kKm1uM+5C0f-gjdI;O zJehHl)^aa7B8Bg*L*0@QTs^5LlP6Y}cjY(GMnRhG5g;Rz}v&P*5{n;)q(Ft`bm0vtXgn zD(Vn7mvneHfaAnX*Xhf%uHapeX;(w$!HkZz%h-Oq1!c)YQ%QO6+$w(&`v`ni$HLqtJPixbubU*a{er$mcUL*S%a_ zRmSzxsK`(bbDOFhv8n4wEDA_y_;!_*4X~4FC;*hwm(K16QyqVj7Z`ge;d_gZcE515 z57l5D$VA=`q>6H0+1BO%GNXEiuKM!r=?`OQCzGZ~b-Cz<4$s^KY)5-&*3p)_UJ_T1 zPvD|@gP%q7_y$1Nz>owZ>VDHvy36HJh1B8tV|T-` zn|PC9WyR$V;ts-4VDG0`i7IiE<1hJzk@D}eNu41|?TLt%MpvV0$D*{UOe{TteG333 z;8i(eu*(3?ABqW`Wu_AS!*!|Bx}r!tOtWdK(jLS5Uy1XGI2<*8ioOde@Kfc~+t-CU z^T}T>q}NwUNYTUIbo|P1zqQa8%58a8_FV7|#33^TC{Pa+8Yn!zD43nBh9jIhgZ z?|k9$$puNsn&P5`xqwL%9~|b7!>Ml$)Io{$vo20feO?)>Os9T5>4nT$L7PzKfP8FH zt!MO|bVGUWbs!{@JT= z=5Y$us0Xcg{~)N#K>YxYtAK>TT~hSu7-ejR~ zX~D~AY6JYt2F@2_`_%ZF6>rDv@t+)z6IXdTSZ5MBa;5b=MO~va& zV8&;z`1T6{1(Z}r8Qhp!hK+wR7^?I#e60;b8M`o%*piR*z&HkMI zxhJY~d0JSf*K8ii!$~)ig_-sX=;4)*lKzHf3A zQ_W!l^wpM7Ocy8E*cxK-=v76~?)BBb=f^Qz136Im*TCA%D^&)ty9{i3=Hihje#@6tP zoC*7gm0k_xDQ_1!yYgp{9-FJBBIiAO5T5#(&De+9Y`|>r`82vdd?C)u#@p5E@%!0S zC7muB{x6m?tvzm6B}viIYG#JA4421ruq*mZ5Nx;vu2Q>B)Fi;jS~1<^bg^j3+S}q8 zGHD6#0AmU!#VD8_J;i9WUHd4qNe7yH2d6XXX(;3AE8-Mq4i9!ftF~jQTt0|vziVTZ`=@pEu@DS z-T*P2`MWV8m?^k>pQAtV*1hyFDaVBgZ!ZE)Z-g1sj|mNO_<$O%i_K%(k`C0L_nE;NS3Ma8WQW}98i-L zKB}0PdQEZkX1YjGZRF~*$%Fo4+HoG==h${#Lu zBW;Eg9auXTqFI17vRmUco6Yt?)iyeIY6|V?<(Fh3m&>smnAW zw}NX&G?~X#vD4EKw8H5WbK|L8D>=F;S+?QBV;hN#=ue_WtJukM`#}t0Tg?+~1irlQ zbKCl#x_^aYmV4$Qx|n6@&j{9F=@RsUy$FS?2F;Mm)7cjF1=n@xojTp$+%+@28F`rf zN{^lL3eChus?_Ddh4l09rx!YnzO-VV53{i+v#kDv=?*owdkc&|y;KQE`Sjs2@>BzI zUBPh;gGg2NN2tEiEvii@ddUohEMvuv$42G2IW6{ORW0QB?LD z;g-C#WHY&TejWb)(RCrg_s1uQDSRZ)Sh-TY%?Q?3FB4AFSau0fHT*=9?(~SoXwx%5 z9@fKKVI0CQu_xZD5mH4&qMUXrPL5I*>Vp1kQ|ld#qlw35jl$mazEOd11(l`j_m^gA z(7WV_h!7zC`BOjD`hoGs9uqz9C6jA6YYW-v#vzYIl?3>=aqHf#TbA!Kk7hD8__#_N zQeC|a{C+ov9Yr;m+T2HSPjQxbnjO(42Hho&(uGGtS~NJD2r$W)fl5jRJ*@V>O2{ZA z$Y8nX7L4-GhYV>5^LQ-?!}N-`URGlJo%KLP68NFmQ=;D%*@d5GqwRUE z_Jf@|gcrR4{jNK|b2=d6<9TX(Deh$bHlw3~AoY6een?gZJ*ezec5MKCj4P2u<7N<8 z^NM`F#c3?<|FlXMO%oCdV)&r9YuOmy?QmT_qV4N)*ZMY2oY}5%L{BAb2AxR>1k{8MwBC4p2K9D@f$j)T5V5{)Ph#l$n-*Wa8OHZket9qyl)=z*2VgvO#;H4Q! zK>#J%I8 zA}~_2GWmZ8l*PaMx>&5(9UTNa5>4(aGqTF3ZMyvel+uT~p>9*K@boj3#u6GR>rk>5 zL^Hjb&j(LQF^mmVFpmXyjg4k28zd_v85hf@=gS~=?A6@Hj2EV25o)0mT1w&Iz+tIq zXB)U|Y;tM0l!T0%vy}^r1XjV33z+;_>0h@QvTJ`%&^qy`TPt3~9`NtOaL({_J*~W| zWw^t-*wyGE|eQ=z3Z**nP7Z0A0MA7 zF&$J2>F~B@m$^6f8JMbn8jm7g6sL>I38(2Zg4U`i%is=5_;9urtZl5uo^_5!dU92- zi>KpdZ~W_S=hDlO@*V1}!#T9aYGFizQ)JrGipch8J-P1Uw=m_!VMn336y-7+>q;3m z8dd_e-kJP9Q$*4;MblngP%F@(cNWt&1ut4u47pra4Bj+qDW!=)ni(!c8Be55tH97g z@8TSBo3se47jI(@nAoVkM}W~F4T8DFLFuzy;z-i-)KNS21AHPwcNTNltZZ1kHHx{ zxX@z?j+xR5PG`b)N0#FhQ}#T<`@QOiRDpB_C0+zZmb6DKtw;jiR&}70ub+qP5Ax`4 zGSLWf@^4?X+OFn|dLBZiBdF3M2Eiq*4Gm-?N^A^8Dm@jIga-17VA zQNK7vt!xqgUEAD<6~CStNn7&`g>k6$4E^Q99@cbK?F|w4LZLrV ztas&)tIgDEQ$~;oRU93le@l=pWR=?ivnK>B8dtdobvx~41^B|C?MXF_PhBa|cn?F# zfp7yIlrf#~)!2e%&~mmQwve445%Q;qo;ZX|+zkx4Wv;sj{-Qk$_u|8R2ED<#;$IhR0QT{xxl$1^;8@SrIsEq@ecy5@@ zhKKQ6OWYbij%u$s+Kp-g(!{83JQ*$Tg&m;IEwz=lSh`wQleFTTSr^Eq3p+;#ak}hE z3*Hw`NFvu0-p_tvn%TJ7Pne3ep6s@^($cew2ny&pl~t5V;KEGTiG?lIh+1PTI?>wd z1!t1`mn^8mfDBcpLlBo-htgD6OfpUD;rM3f;E^eKd8;m|Fc@Ab=Jv>1=7^Qp^;Ogia0X+do3@=z<KPV@~)r@sc{ zMnfTDqAzKJv`fUc90Mgj=YwDF86}0ZcM~L*T?R5%PHq@LEo*I>2p}c^mxs?(g^uC2dYe=#k3R~EH%pjsJ77D zM5e|i)$oL6V9`Q9&k>U=qB>n5)w_eP= zg|9tnkA-x%yt&wHUM*l3GT#%2LT7GjdC852$(YmqKY;fLn zRyuO}7P@hn?7KKy?}LKmoAkBKr`pOZ4gF=Pa_;`7@s!U2g8Qy}uk$X% z$?WF|5@s&U`?q=-@HKZsUZ@vsMi$jVwTOT*45Lt?8j{3>Foh;Y=J>!)eDw1xr*CFW zNFq?wg5C6)R4Sg#CJDOpv1L$!@e@i9OAeseF+{eiN#%snYi&a4&i&R%ncsg__bCWaDdC(bXkdi2Veo6A!<@(*u z3}AJ(9$mR}A}PJv(#3tc$fH&KwJGP;ORGpjfuq>CxWB)E0EONTrmZ7>xk)X<+MzNI zjiEGPjiRL~_)6|8GicA}4o7#^=fm-2N-;v%&oxarp}tq6&Kz?|W!)6Y8J|WIuH4)b zft*z(=VGCtxqo5?XR)G@Y#*flA|_u-Od{km?f#gab~5#Q{;Lv-+{&$ENnl~@fsqM8 zdn0R@66STVSQ1Z#)=`nU6YLU;WKLD>#n>BE+JLFP-h#QGo4Y>#?R<`RP+pXU7whp22Wexp!RRbz$hsS<+ZbfWJBP7SlETVedUGZB8ZInf#Tb9> zE`V}dM$0M9p%Nrr=(xb;Qzb_jbO_CZIr2pFIk*(Un9&#pa2613x(L>M$7fh5gO~0e zTyO76O3o~Mnf&k8o0Lg?x%cZL`GpP;(w^F$Qd>*gdJW8MROocM!ZaqITaAZdTLaN0 z>4z}~zktN3{1Wg30{_H?te;i&AgjXDhDUh)Zy*E`4m zESiM;8z}j6jNi}YPZ>n=&hdu=Pf4?Q(^Zk=vjqAQN=;bQtr%2llu}seb+fo(Ws)sp zrE0847z%FRF>SsD$z(r$iTw$tsRgViUQ}6d*5U#<{h$#xxaSe z42%57DakQ4sT2*cm}I5S|0h zS!Qw9fzr-qh0Ln`w4FXxU^alI;ywIje~%gfCf{JPB153V=WtYejv@Hy4DyiAyj6N( zeiALA%R1#A0MXI3pMsDB3t3sklL~QzcC0OsJYoZj?Dgdn$r%%KE5|!T6DbXv%yJue zrwE>LNU|0&&m9{IFBFm(icu3a$IIJ|A<-K_23=o-C0Zi=>4~pNXNs9uj;~zvwRZre zcFO+9mm22x(B;Tl5d^+ac;GhbDCj*v%)!;3;gVzE%asQ1Oc1uf1eO|q~ZF~r$tSQa_bPV?2)=Agow0N1{x`-wU zY5CRp-WTT|r5)f7C)_4s2fjwXw0y~UCJPQvr8!2sWbiT33CsnlJ(PovFcvBcXX5iz zm5W~{Ve)(=%8I-yo2;DbI+*lbJjXrb+AL@dqKk!C-9co3x1hMey zCSY2F*{J+%^0;0*`|(Bx)-g1KlL5?K+}ncUc+~s3c-J0y)Pp>e1jVmJ1B3wzadOM$ zihDM(=oPk*EXXEFZ1ep{*9Z*^+MUqMNFh}@FD)J;sBqlj3#cI$0t>{W;tbxq{H+|k zL0D?PJVUu2;D_~0@PE+u4nUSf+qP(zZM(Z{+qP}nHoDYh+qS*S?y_y$cGau%?z#8f z|K7Rx$B%eFV(yW1j##-eSH{krJJwt|W)a0CRUkvDwVPxP^#qmPOIbJ3iy)?AFj4C* zP*9RE3dePkz1}^8*l#$b^%(H01YR6B`L3Y7C|)VtE+4CB%I10Pd8TxE+tp1`iA;^A`30Gd+29g zYX#6d0=Eo?)RCBjMAN~vo`8(Gl_QsSwfPmhsn9g36nbq7Ca5oy?KebB368N7PDwAtQR#XCCY(DY>!V=Q*GS>7*3#EZ{aTCA2J>B}C@2WBZA#KeSGI^}wd$UcCMBi7C*L0z2om!E@~~S{%1OQ?X34m4*#)Sc z?GYKRw!cj@O!!oUd*8OvymA`)&P$9@!%#Xlhes(^_BprNRxAImNu;KZY>!=tR!pRR zskme&)a4tmsNH-NqDS-rjJd%uTk-&?+^|ULY~x%xdf*Pmh9gI6{@3;IqJ9#dfmduE z!hzwH=`!;ODrXd%`3vdplvxfg!IHn)BUcL8cDGgfu-Vci1n zZp*u>)(;dV6`BMQ7J0FqY(s60hMlUiY^;_I5&AN+xlJs0b)qx|P?K7&6|P2iRAa=+ zB}au6t+VgA=@mldQ_=mA0RYB=-;K@_K>^DMo%|^E-9-EJ47C7f*e;mu2G9Z#HBGP^ z6)d2l;6;5j^LKRIZm8)Fi4vwVid|XUZlGZ>n6hB~0msu0Y|{QxQVNI$Ns~{hF}1I< zLk*658piQPMW}4@R1w*OlI2~rS5b`JMCB%929jbCDLuu2 z`7+j2KUvpib?9*dk*7Eg0XmPTQJ+W2rxoX@w|iAnORB!KRr^ok6R8lP6HWIVCQNu# zDL>Gw*t4Jcf9P4>vx;)AerG?=JdMT%Uehfx(5>CxFh(_NtBYvxRqGZlWSqvsZ_R%eZVnf!Cyq!j&U{F3EbKeO4)2@N+GsN`Og<~nw|!M$$Af}K8Q z;FjgxDORkYlMbkNZ%SfE0I`OwN3R78rp6*>?MeV?a35-r0^IEt3iK_3!P>r<2Xcf! zkr{cA4mK)ql&@s*?5ZB;aG zGEyOp#Ug%@8TZt{9}14IbeePVmVk@F4+y!9MA0FT2)3dak2hQVlPw<1`^O8slPxC9 z0TwR3x4wbvz?uyJ2p)m^MRc9mkrUh!A3f{iFfcc7C}MBJJ(BE50KJnvE=z3$;Dw!( zd_`p1alH*4T$k1Brn1qs)SCuXMj^P7;({twC`1W5YcALAbUB6@oJB&O8idkVvX?wx zM2-|ZN-$jo(F)(tgtA?M9!l~QEpq_Kk=A+;oc$JF2!_Rgro_P7#_QKkAfGxok9W2U zCsVRW>-|jt%wV}mmv$-6lf~KL6 z)ENVO0(5k1s=~>FBUXRe?`kK)JOwUfX#N8SKL&IHrnK9e?flb69qY&2qIf540;691tHTyb-uH+f(=88F7}O zJnw7(*rO{j4o?)x^<}2z!s&K-@^-mOFFJ5l)ru>$k`*>f)ZbMR{c#FUHL;X++j_TI z0Hn0o$V0HoQr#U^7kxiXRV4)~=K!qVC3b`OtYE&PFip1;OT+OwsDso8+|+o}6@G=v zEV2J{unhcEQ;W5=lUnrptXoCA(N7}BbMLX{%ikPLlq%hMWYxKtF!Pr-mS+Gq0M)RBn;o4}-z#0k;ax^PRUi*GC+gGPnf`tdMl5uVff1!w z`YTPGrk?j+`}iEi@!{e^5_Jbm3M>k7d7aWmSX&MF!sPxU_8x@^83gVgk_f8-w&_vK z0x2OqZDSEMu-*rTC!AJM_pOfr|!Bx57+; zx%`t17`zw1yfJRcfs^SC+sC2yI&YYh!N0s2F%kYIq2H4$N}p(hF5k3q)`RniR5=QE z@80iPt|YlAcU9Ds(6u#rBhhHaD2uy=U0k&I8A+Mm$xBxJoJsf48~a{k``R1Y{&c7y zM!mhD9tDqMYc@|^wy=+*t+Ux$V=I-}@oDAMlsQ=n2l$p|#;gK2TWh{NS5CgsH8m9N8uQO~Zvz&cfjz^VlUe6s1f}+_F8U5T$}|pUX05#~4?1BY#P=-^cK8E^pAQnr$nT@zQ z=qhsaC#2w4n&PiFMr|2DwIGOMUb=gxV(D>2LSuXpIp!E(Yk^?{#A+mfH(Rc-nn}5t{jV z-G4mV;NA$ZY$hndMLt6~e)Xu^Mvmg^V$0*ZsWEnpde$pKVrgz7~ z#J8z*g#=IH}(HF14I+AUo2O(&qy08Uo3dDYkmdSU5}%vZ<%`A~FjF-Z54&?b@qw03h6bKB<0g{m|`_UMk3&g&wrI$MN z8wDEyZ5n1x+s_kv6TCtZ_+WQdj03Dgevw8+CGHcrvr$KYZl{c`f2XX>Ns&a`5c>oc zd_eh`u`iDoYNsP}{bs*!x@$y~fKC+RiMMrZDWyWW-x+e6y8qSc6-DW(5+3RB@N?$W z=Beg}&#Kfvac&Ntf~=i3Lu<(xL{IDEnI=UMo~)iywjfztO#W%(#W~IyerjH(#U1Gc z*WFdC(9#@z#TBOUg6p6%Az7V_rY^dz)=~EZqdJpp^SgGG{n3(Z;pt&cn%Iz8U>45l zs;Sn7|0LYQaVQRg_tj_Dq0rXHz5kU@HJ#gWRLG;Z2dR3?N1TK^?1G&is7R~D3DI>l zb!{ah^N>#bs5!4K%{h1Lv(5c5Lk6R7HD8@qEDD9bUs0oA+n>mI{FZHE%k2f0~O_-zJv*}p7?Ruu_-Zw zqF51)R%L1p+c5)04UuXN z(pHP7ow^!ueS)PP@@on0dT0lU3pDNcu@fod+h4@-eqzG)8eay#XnB)GdcIg9o=;u9 z9eg}>+*lwW{=}P5X%=IjEix|~kghm@NJ38Efx8k9)!WL5NKrFv;^$EevrTh)V{4k} zU&#+=pGGi`H@XXmEXnjEZR#H;Vn-}m1Z*2cH-S>E7LZEX%!ZS)SX5ggaLoNGSg|2p zAcZU0Q_0*Ye`vHd53jL}B8RNcH-W?E_$-1M*kGg!TA?f@FW1I><<0v6mGnjE&N*}f zl3b2pjD#^orQI;g>1R&L5C|yD6z|C)L*}Ao7}+3vGSNJnF5uYlCXuEQPdxeEpSXzB z++N_ikYa$T^fGkwj?v>Pf904%wIDDV*D*n^83oS5J5Y`mJW|`qY}coz^Imr^9i@jN zI!sEVe#x8+BuCpIq2n);o4xNeI$HeoTeoK2nELJ&P1x~)2K$pLDY%iW=6M>)=GfFO9#NvSuYd{t+Q7&gTXE0v@NKT#Z{-f0rRFrutG|!=q7_G zF`~)RetM!D@Sz7G>CR7f*Ygwk9%q-y!?$vui+-Elh!$P4}nRH61?ra`HG@ z=?Jj8X{l6rF+J#u9-|@pU@RWubR7RSNriRuh-96t2pzBs7d7;x`Zv8UpRJJ$OPr@} z=b?*h_ew*1xvA#~p6coHjZP!Br?zVlgs)G6VzHdh?Jzp;>-GC%CIW8}kFPU`(>H|f z4tZ``wIp$n0k1QQ@nC#yLqv5FD;jP~;FIu%FsCmBNl8i3#T!H^@(XYUN{U{2AjVRQ zIz<_%Rq@fv`{z}(#_l^*s(DlB-vmiN{6K+xYp;*POnSc5A97znO-P6dETv3}V*a)i zfl)d8Y)Gp~17*nVq7uzVU0P~BrInR--Azw6xWiI};x{5?9bR}=ZRpDb4eo=m*+GW9 zovmN~Kt*EBTK!q-k+YPU-qF-)vGp-U+c6l5URG@Xk3Z2ZrG)WnKfi?2!u3heZn!`{ z&FT2sJ5s*Bs6MyizjG(Shc9)JKgpny(q*bw7rsZZp{R)DG)7YNzyqa%^u_Jm^_UJ5lkZIt+ z=&Mtge;+3;YDt1OBR`E)9v}T&v*#%x#2+})hYSWwrRqlwrrmmRHkuzVP1U8lJV!Z7 z*VUq}?3p#+mhURpB=pfH8W=8V)w|T|pG)-BE#-yqJ7U)cJgVOk>6(uplV(0?)AfVk zv5SX3oN%M1y#457m^fi*e`B9RLYy%O(GXd`Z|s^m|97eRALDq~eG^9i-=N^aCOWPv z=$+7|9iT2eqt!8i)n;<)8ZJKPDr!2(8!j4)X#3Cn2oXDVCwCR6*~Y-30Jp2wr8wu}fx`y5qoH~=Pbx5RbP9u|#RJc%3 z=oL&Pi*d*Fq=f)RQkrbu&tiuYWCG)G>|Ys%&pd-40sJSaB4;bwqBfZl(-A&FK|^}> z#OxA49G5cOcAj>w?w)qPG6WJPZ26!q1_n0VSshX)g2Izl26QkYKBUQoC+j)EloyLb zM^_6p>RIuiyN9xe?9elsexiEHm||g|>Jp~c1uhL_yEEvSpxd|Hvg$E$E%U(m^@B&G zhPB!o*ROh+iQR9`Fev+kiT3sd1OsHkGF2vuAu+TKqia!T+NE|Y2CKZ5DwpTfw=Gt1 z+R(baE=Isq8n~S>Vj|=!9+wiQ@Qz&5g4!>+9#FR4hq^bLPpm%Q3hnM@Ta8ex*gEDN zuW<6hD<#-mHu3Q#1PSznKTjt{B?~mln5lwIN#`nw)04!Vw3*5L4;|KqhUqgx`0Dz` zFYXI`N^7 zFt_zQucJv90g@xvqYbzggp-QD(RB`wZLHk-sGo)607$m&rrDawU}J-iD$r~*14M`trkquJg3UA#v?r8EW~$EN4g zT-N*k@ZaTWGHYWqv2rheZG?m(`UD+0F)V{bh4UVQ!3);#6`OfpgUF?E*_;L)Sxy*I z-opuhN%#zRHg{2$+oyBko0JRvDdT3d`ontm4Rl_yNc0N{IalvBmZe6kOvYp!6L=C0juxu$6S8?6Bg_eI@+-9IS^Q4B z7P7b#VMQG9;iQwZGt^<|#7di5gQcA+1|2YQ?kjmbWre(X&d+))DAE)nBGEph9Cnn< zxaZeS^fC6eCynr~$PTp}jnO$!GsG$4mU<*Rpgr(>VR8_IrV_WPdas0mSs>~tmQ$#; zOFErJonv&~pxG_jmqnq^IINXrooMG*LsjrN)lv>juho-jtc*4TrOZQrj{*J{r$ypJ zp_%?DJ7taYd2WTRnby{Vkp_1V&gZ|5)fj{2K6Ue=t$j&1W31wCjJubTxsnf)Z$hku zH;s5|T-A-5bSh2_e;CREmWrD{fkVa8gWg+(HJoteFo(;2D|zGC-P z3`b?~Vd^YM2VnscB1ovMAV6Str?L)=BCQXnQR@jw@m_Njb_Xvn>8+q}cZ5i)c%LhQCjmy16l0*nd9Qd- zEz+Xx>hSDJOIu;lIp-_=QKGDsWn$r3W~9tQ^-7$lQ7iSY=uZbR$sEt*t=P+gNi#)H z=N8L5+-I4xOGTpCjq`_O>*iUXN6ZG<=`>inaP&-PLlm1?-av_v%L!w|fF|(X@lSsn zrnA*DVtEC|W6TIF$+T(EwZynMx*kTd94cG|_JGJuGU@wt87PR2v8p1v2&#EM-QX)8 z4w4U#f~c)$zY6!f5le#M7GW*t{25crfw@m z-)Q;qOdF8?3cgk^vASq3&fiv+DK(6WcMKP8V4?_Txfq+sOg;ziDVj|=%2CLKQFT{KHj9ekP%A(& z+)yyo&8QeDMVN$aMn{CJSNIy5D5NpO zMa3qi?#edOHZ4Q&qEBW@iA#FWbHiKpg%MVoAROwMe(X)>^$%n6Fs{ zLmf8^)qaUqLB$Zvx^*ZFWZyWkQth+^k7>V!VBZ?vA<PmmAF)YY_e$> zGojrS%XuW-eyo^Rpv)vMDv~=mI%9mzPf`2u5~jh}MCMS%oUzbhS1nx}%jMa|zWmE- zCSzCD+B}hAEko5=ZX_z`&}Ge1zuA|XdLTj5ZP^$xx}+xC*-Ck0+pe9i#7;Gl#=^?w zCM~Kwvz$@m98;yIcXso3sA_f=scPk|?VKrN#*AHGaTF6SGjU6cnZiIicM_iE=%XRX zP5Y#<<#-^~OSfM0*uR;o9&hSOJUdWQpju)!J6_^qrO={vEf(?A-SV~eg+~0$R7_iz zw#d!kGq6uGSFQP71!)^oAvsHfvu|e{H(>`q%eFvmQnM+y(A?MVqA_VHC3&OPQ1j(I zd_M8Jm_6ARJt=L~Ew=kI`2lRF%yOtNd(uO{oYzDL5pPPpW(#ROM%VtAzb%s}*$_uU zfd?J60^nhaIDuvoDFw4A!t^czj8&=KuUUY3P?Ttcx=F!bQDF8)7XW=I5nwVZj&&Bi z<(2)=7hH*x+yS3J<`bt;_2<0kDwN}Y(C#b$Fp!MtFLlMo;Jxr~K|fnuT=r=iKr$j~ydW85k4 zY+Xsj`Zryhk;85vNTLDS%EM1P)YUbYRV^Vy-S0heNtKDJqL{Fvn6yH$F`v(Oiwfl| zmB9lZ;enfhf+yyXCmA0NEhD=+qmh#*`R}K?6WAsW8W(RnnBPuZZp8iMEQu}F=pQY^ z<3B(j4gETE?7T*T7Osh##*D@LY6oV~k}=^Uczlk8UL({w{oV)nvs8*wcZv_loDP(y z;~FLjj-yABGOni4vQ9B$5q^30o)+aJ_!r{RlF?z|&0NT0!equIE6$7RUWs#rQMBXK zuIvTG6?3*>_1F`W=30imfb;qI4&{Qxef+>ZLRAi;NEF{5uM-DLIv+7Wita^J*p!Sc z-FF_t9PfehE$HF@l;EDMRJY1s4BL3Iok#M9EXo6kNd>R{(k_p8iYZrHhKpETVp z)g}kJ=F?J7ag@foBSA*0OQgOnGx`}bB#ky1w&Q9M4ix1$(cf+6ki^`n#GZ_TY=JIT z!TG^SgQ!7N)8Xqga!I6e-05jM^Nb&dH)$yYUv4i4lY3pm%yq0~>em?7qR9}#SzVR~ z6Y%EyX+A2hF=yvyVyu!vs%|=p9#hqEc+fGq8FlBPVS^@wELQ}c3QPslCPim4;f8TT z8j7}cc@@j3rPQPx4F!wn;4HCOBNYqF%UdF;r{(jdMSyKHs`FooP9}YuU+OUrw_64BGKjcc+E@Hit5cIn{MU zt=I%hlm4l5Xd*g``9g0pnH(K<+sWggD-5+FwG!bXwBkZ^;u#-3M1ydMUj%Dq2b(+Gy%&Yw3+hA{caFu>yM?01HqW>rJ~(74)o5MEO9K7 z%Dk2n`+QzBoeO&fzX>l4gC+5Jrj>xvAD7gUn1l?g=l9<*Fr@DJs1e{W&Lqzy?=ik?49Nl=r|iQRb^eUwlKMrW4#i82 zifvKPxCG8R`s0SJfUdZ9vD>-&Iyi*+Jlqn~vRtx~-YETYbMWB(d;zuU)259f;XXvx zX5;_d`-&nKC5iqdcp-Qp6Q82@I3S3hO4$ACPWn^GGh#9Fl^ma4&#+KE5>@s#>p1Hh zmz~rll3hIV6^{^=%CWl_iG>BhNTw}#Iq6MirMWn?!c?y}^4UbmVdXgHgwVD%-p=M{ z`Drb4c(il?am#gQH=&pE6$rDhFW@L}C4M(dLgc6B{s30rblsm%A>v1!E&pC9wn#js zv|DyB{WyL*ez#sZ68N>zx1}vO;2Y#6EC{>L9`>ts^av6sG_5ce^8m9?8-KIVTT-!9 z=mpXs-VxNG=GH4HV@0)1?*;Mc0B)2bKH}Md5&x~8Ud;o-Ag~_Opy3uD3*kcu@`>tg zSVsISd_CwHgPczE<%dD_tyB=(uN-i3Xbb+Z^SyWp=(kFfsy<%RR%L^n@pF}BF;cec zXD9CU8g2pX0rUgj)1E~-bDBqSOXdd!gG}_L4d{!Qx%%lFmoH~%@pFLm?vGI zZyS&oomt059|z22ixCo;<* zBQeEH0y38vDXqlFATu(~Oaj9!7e)g@M|7^niy|kG5Pa$19X^fsto^R(NVPZUJHRLG zF8PAJqftb#!*Ni!On0IV?I;v(yhCAYQtpoZ`ZhQhnlZ@4ox`+?l`rP5iiJ2OPKrLH zOMR(I8funz$Iz!F&JnSiCA?hY9e&LmlOsZ5rm)L#LoFEue;Vvu8ys!C@4z$%1W~+) z|D53tPg5cG%#sKBmPCh`{kLnmntYc-Vrn)H}-!Acxl)heizMQ~n| zu~w6axdBzxYGlAN1hFYWy3!R=foo*kG6<1HFckY2_rzW)lHj~JV*~cD`37fIq99Rx zHYPk(qLDsJf5h*iGnzkzX^3Gezyv|0%>EII+dhwwL3XR2B0f@4K*~`yAZBAd1Mg^< zK=(O;43V(CgQk&=x3E9m1T`lF+zJA1tTH`Of>(k%er*@`Q6u0XOI&Xp7Oyc z;z?)qh>Xzw%)G&gM%V8yp~p!y*CltyVVVF@lgw_G4qOxs@3_+BZ#4<3TIgyQm4Cli zr#mc6T55++D||-}NGIi43jj+qmg-fFs0vrrz5hq(n^|kN!5zyuV0uHR;u`Nd3&tG( zbC&dm&bxf;<^C7RZ*?4szGTZ;;J6XoLY6pF>$6=e-}l$NPE-RBW-^0r^kZs4%^%o6 z)kh$jacUq-HvO6yv#ZanE?++|hkqk@0`1r0T8$yXj z4mepXIl>7Rs8A(X43`>l(alYD%Z+{u7cDg*QSg3ljLYi6q@|@P05Kpxx zl{8-C`qajy3oAlek{D1$9@HYifP34YCXYGyW8r zA+-(u@%4xNjnyi)rVbkdVoj(iO*4GFwZ-DW@~By7fF%S|Y%x@$D&(qU(GzMh0>CHS zY)U&-m2^~_xt6D8^&;-ofUb0Qb@ZqnfX)3yJB>xMkCU}dOLeeoo2@dee-Bn3#WSyiF=>Ma&3H2 z^S6`!fnI+n4|^qE1Pk~D5=-e)boB4ywHoHCUW9IAkn*GXopTJmn^*YS@ zNGT+~zadO?yR9vPWRP2i?-}lJoU#3mh4tvx`z{7zlh@k)CsFTbf3w#8`d?_aGgWGI zCOfMlm|$=B$|IgYPB$5AK)6Uh)(e0;U>5`aFvEw+8kajv9%w$zmtCc6w+AFMY0J{fu{N4aY9h*WXD^m(Nlf}bo>Ec5&p z9T=RYQJq-NG3BR(MLMcD#i#Zh!-kYdr=aKEn%$b%zz-xYvhXgly7Y59tHi5qE#i(q z)6)ZWZgKrmx}D0p^UULGNNP)&enPYv=d7=8ZeLj^w0qm=Fg8PAABgH%<(jm1P$OC= zx3^({X}vp|dAVr`Akh8t|^j^yPrL3PkH4Xd! z94)=Vrf_R|?aAF-@@HQwYHBCJJmycf*{J%IHFtdp59=0REKge_X?a~u9(&j* z?HJ`+j=cRC+m|IcoyFpBsw=2bxxCaL{5eEg=nSUH&$Ap2O=F^RJ2K{-Rb{C${++q* zl1038L!Y=|b7^_zgwV<*)OH55N@uv!CsdZiSJ|fsqwgem6k*`q-$K>re*d|6Vs+i} z%9%2JVJ$Uaxi^TDngQ07wuTOA_+=H)m8&^qXgoa$Q!2Iw#s%_Oou9VxV5_H=y}q4N zb8bDfs9#%<4{%?pHxa4Y8IL$!(~1Zj<66z&^ue1Li#Q96y0Gb`l}Q@J@hR;=E^f)~ z#3|OHb#r?W09G-~Fd@*K-CDthWE6}@cJfp@oUHu2DBBg_YJ04z<*eb9+r?q1_YS^# zs?~;*O0#>KK+k4`1`MSw9Y!w!IS$eg}Sk?AeR#*ZU_lT!)By?DaKZfL zwY+B?)I8gFTa}?i+PVR8+lnN?5PX2PPe#-Uj7v%d0owN@mriw8fA9Su1g#n$XZnd$ zQA)*?vml?S@fJM8Zg%uZL;ERG(1u(IB2IN;!Zg8A{7qq^^xvdDRK|>TVOxHL4cL=n z`1)khID%=-`ZQW%FLN%BWLlCp3p$Sk+n?P<86!xqxG$NPWF>zBYS zZ#_0-fD5n|Kadu-o(mBBHzt4&v~9_WFQva0F2E#U&D{PjV2#?o9e+K&hX&Hts^=nP z`|$_h;ztTuh!cvLhTZ~1J)9}-3+>(9JrRX?MeW!foSR6e!SX#LNwlRQzv4DEIB?lhfwoZEXTaIA1*{p`p8>US_1K_%clwVV2m!rrCp95Xb0lK+ z5x_0X|7;6n3%9)(Y)=E&fU#Zcxsb5;f?D7F(X!>gMz;OP*5NZMxr*|Pm!Q?zf# zSZ@wolk2&Vv46t@;6b!7HD;wBE2ay3S5F3ju3__Gh3i-$(bgUxTxq3S6Vw zegp#ez}l7!)PQv^)BTQ%{jDaY6>YPE ztyhD8Uto0ok2D3bsMqL+U({z@k;tmDL4waPS@fr6GwQq?sH<(Zj;(Qu1*o&=#l>^G zWRaql%-!#|1?u?Tu~$ypJ=HoHtTxL%P8IEB`$>3D^H?qerB^8n!4*|XDfpej4{h+t zY7j(5^w?gDMkl@Dx?4_DJT7_B4`lPVVXD5wSUmHvUV29D*X9rrF2^F}Dez8U&w&EB z+1G|Q_Hf15{0*DJ_r(u+4|%Nslab%T`;vm_cnl|zq9GvGow}$a$9I)+9C~GIe=BBd zZ2YUw@w89qu~}GRN}3CdmR%%4N*INbZdx_3!K#-@l}a*TVqy6 zdeVQQ3ZlFdMH%Ibj(tvlPQwqALRMV!t%`d##YuBo3KIEPQKgZyz}3GNn;P15x5ynt zNqW&0WD(wVstffR3&8~^<^9>!>Vqq)HvgY~->AG$9r!f1BpD);9eIr`v1u6s82+Lm zVuF8qqzVd0RhY`U_{XoNrq>l#l(onHCaXG|RD;xF-i}#2Mx}%%gfZ7E*DFz4oS&pb zENM@6TfSFMU2bm|EjQyU3}Y)9umi@J_U15jmQ`)iv~0(v0z7R?ZmAFR)``Rv03f)w zU!f|21|$_~r4VqH@w4f)#>Mm8!VJd0s~xt0E}^+M3p|4b^1-WK1WBRb@|tp%`kMf= ze{y@JVUtHTM>gLP6U>oi#+B(qvQSM{?+5Zz3PVlj%S)Sx^yXF-E|;1eY_6u$En#^U zwQb#GCSILHjR0uV$)YqE%!m3`n#4^kB!)A1qPk>_>REfWE8-KyHw%>gr#I`aN9rJT z4^Gwxwlu}onA%)s&GHRZHPtn?ILTfIUI*Nc*Ts2^ zK)h6{jBA3z%ClQ_ZeRaNa zwp$jcRIY`0b+7bp_g9AtKzu|xB;2-~3Ev~Rb&~U_ zaT28E_1k6rNPU`3pGB#Hg=c<8rAhBXDW$C|y6Zkx z;W{;b4MUd1stLQ;n$MR$7#iMrP{KS>EVmDTDKp|$#|e{1i&Iu+l`RI-h8thesHxsm zf0-o7D+qe_1zFV?4yakK zQvZT0ddl(&P6@3ZsyLk3QNl#+N-ZxY&mLanPLt4fdI%)@yW~%BI-@7iQB!X+8F0s7Ij0 zO78bNGo0g~W5&a%Pn1-GE{hIa?pAJ2S8A(tG}J{X{)Rq5dr9OV1gyPJ@!fMI$^gqt zGASGmL-OEqbVDWMFAaYDjYfGb&C%Gi8mTun`qjBz>{&;RmtGC;i1Bl>1P4aK=te@c zOjz1&C8bghc05&%vEto;$iYD4o~5>ikURJZzQ6nLx9HLxsr2wohhS$I z+?Asb1aMGPXMY*dC*v^DZ2>Rt>gWsed`QWn1(Y%btUk-QFw#Ml)|(sNm^T{}?I42s zrrW->5FjPMCFm)%T~M>N?iag0J*$I!dfv7YU^tw87PQ5gPvukD=9B6mzonYZAKiuW zE)}27BFJvTIu)Oaq6LczvufSZ17UN@l#O3G3{$>s_v_(6 zvX%k6xR&)slE#B-nvCZ2<=fe0Jv)xNgKf3-?G{_?|Rbqs!#-~8Qi zxLA(Q{k-kfC0cvVx{o))ic<5@Di7Bqt}pdb-L?^*&-wD6TO7gnG^NxosG&dmPkiwo zjzDa&5c?ot{9qD4lX_qeP#95C!N$R>fi3+j{5g79dbst0rgP_!_@*J5sX`=vsKZhN zY5rEtg)@iX{H^s{HdkszC}31~7LFP$8HlF`+JvDMO&#hUxZ<~0lH0K8wpb78Ht)8t zKHIn8F6_7DF0eb0Ss;f05|ST?JIc3YILmdne~Z7{Z#Vy~A6GzEAQ1lDEkskBZ^ z4`kZFmZ7;}xq+=gnnAdJXZ6r-EBvp6KQnx5|I+m+_009?Zj<%M`J4SV^XEN4^ig@C z@qznR2Ijo}bNij6x{YT~5e{2Is&MaQ6zULoDRW2hwfk#Va$EH5#F&gr9PgNU{DVjT zN91oPdJyy;=;a?=J*I7({_5Y##}LRrSf3W)_JLmbf#^YK`2Nr9*<(7f2|EwOtB)j) zP^l^#hgb`)4zmtJw+{IZxeU4vv5s&K{`eyXCk;E0Frd!i02}b1BU}4&_k00iGmdMVCKSN!X$#I{XpX zd0R3UJQZ9T!t@7|zebPsHl;r8DI-EEf;I&856@mNv|4OPAgkX^JvKd@-@?oA+p_vR z*FNVB8XSKLE-<5;jo4SCcg(r|8GH?{ZGB` zN3a#1Ie;VWk1tX(Ns+0e3 zj^R0eGvf7fr^?C(7axa0Og^Yh#mOqax%8FV(WkB;(&w>5QOipbDdAKx`aXKMhY4Ng%1 z8?`c$!v_ewEF1*fE0yOD9Xn_Wo#BuWR5jPGp)maCk1Xkj+W5=60xoEZ^7Dzub)n>1!M$R zFe0Ud0i*{^2x(Cq(n80CwMlpXNd?{&9!strQNBVLcYmMR)o342u)+&wQp~?Ye9Xsf zogVMw*pTnbG93Zd%kZ$6C@S-Xt!9(8&H7&Pc1NnlC}TqPZ?eNl;S zjiN1BLeESk17b`CgJ5VXW%ay1Xf)N*TESp6%1Zfvr&L_67Hub1t2EkKtXfPj7SB)2 zisT2Q%3GMJTF{YQt^1;7mg}InSPh0q0ZBX3*-Rdj`y2^JF|2mb=#@M$uc-RRQV zQ^q%>4lhZZp5j}*D4x^&o}4`6lV_9~GgYT0HAN~c;Hru&HIKTz(zEj(l!b8Kucj1f zYzk%WaTgSLY>L4>v#~8;Y-lQ%>K=MwK0l>aWo1x{@b0NzSy+@{E(%pWzwfEeX;KUu z$C>{E1Y*95Q(oVFy7`Ret-3#LJvQ2y@@5~u%k z2+}LPAc5#{KcvsHb63!`M35|@Gjd)6WEOK>yUe*QO8eTtrE5%MtJvx~kyvnf zSK$QD>><8|)4$VpJNQr=L=I2l>paMAF$4dH+l6rPHvLbK8Vztu8Hemrb@Z|q7-4B2yTNTkBiLtDCjbCItzvKu6VMejLGhFJmcHViX;C-O_d_tiysCMGt!1d@-SM) z3|zzkc#vDfb{`>CZ%=S}J0s+du21k1<^?jhfg7>-Gl2dz$Xh9%Mm!0SALJ#5DB??c z{3mDdgJrzVdZZOoB}BpHKS2{z0jt40Y2<29JIBjzYNuX zkcorE)T}0T6cI8S)}x-I((eDQ9WM%OaF%L8xSZwM;tdp&T3h!0FG#y!Z@@Ea-Wzw# zT(KqV8j|&nIcFR3P53WioNeSeG%{xRKOi;IHDShnLdZtu-*?~ed?7$k1!@CH+f@mDW*Z_Fu&GYICq z8&Y-;FZ%{x6GVeK(f4LxDzjg?Vnvn=ABpA144#?E(^KYUWN%~^STrSQjq$28mYPCV zW$BAEbN8@SCD^O{Q?qoX$*i-ap3$eJ*{n)|OSjxCv*@dmYsX-(BsL|a;j__w38hWY zO{#f|l=GUwniYsvAci*lm2ja=Ky|F{pB$Kt?d~<%?;J~Rb6&?W$KIZFXnwa3|9ozc zWb26NQ9Az;#|ZeBAoF>Cj^|8<<`>|K{-O3N_6k2y?3e!~>Ne+B!g0URXT7f;gc}iS zgycvq7%jr?hcdYpbjP;yF2nAZK-LNq@OA>^8H=AEd{0l4FLq4UxQurF9}l2o3(r4` zN^mxCk_siLE}ZfuApZ?ao4~bI3Z$?c$MdIvwh>R0_|rl;OXNxc>mdI-bztDU5=GlS zW5U*UE}F72%m|@z_;U=`I4zLciI|IK#bQKO%2l&|Ei`yom#O9`vCi{Pp zP*Xtt*&u&p{4!4Lm_BSux-4TEX0TAQ{wLJkxTT)5Ds7mSuSvUPl-WAH4XuANwD^r* z5ICXjYlCs92~4WQ{vR%z>+xUsi^A!sG$*6O^;8Zv(@8KU)!TZqLY;YucCwtrM*!h& z=15!T>hl}iV{;5WJcF}(UU1AGQrLXuZF%_QL3wsGqs|f3?cRZc%OdC>9GYBVQ zng8~C9?)lqMytB>FTkJyI>Y8E^CG)p!>QS8(sgR(vi0W<#}z%?oR&Lfb5*;|neAHJ z_Y1=R(%m%Ex@xF;T3LLvKJ#gQ;9dJ4w7msX9ND7%JuwIp2=0(Tg1bAx3GR(+u*TgX z!JQD?gG=MCO>lRI#@*fRPh{?7W-|BQ_kHiJwbzf``7>Ig^-aQx5Zjd^mVKeUE9wS!%^u9NfPA z9hB!ED0^w@bS^dNZVF>=0pfQQ6=U+M#`kxsjgG|ujU~#eCCCm`nO2<>)`_Jmw>QI?Ok)H6YB z9|&wUn$;FW6nTOf_Yt&xu8#Ulx)lAKPMzQ%co8a=0=fxfL^4A# zJ|&1)5qA2&BKdTxw*C;ae2ov|OSXJybX_QeUIN*YIF>;dt6WO}xh(H;vDKdTzJ;N;corsh~`Z75myRHGrAK}{a-pA_T zE<>mp$+@KKdU|(k2(SH+M-yY8wO7;sF9h{*=UURtygC*xaZ(W~_4?nXZnh~gkA~^KAWs_RxIrX}=m0GWK z=4%*3ajGUc?swv&p}CDBl3HI$8tCRqiFW3rIrGxcxULt*1O!-S{2H4u^^jiL+Vl8N zoWHl&^@-W|m6Wd&MUxV`@1H++wxT{;R@?2YhJ;&JldM@u^{sp_NNb;3G}q({#XipF z{R&H}LjI3TPfMV9$6j<`KUQAyNcuziRj;gEQ|PVuwZUSSu$9dhS!TXRQZoplY2wQ1 zIYrc;_DvS3gX=b{iSS$)&KZ_B_>!pq37&>SzQnFW?(&zRqIWVIJmfdR8F$&o1d+FC z-@@Cmqc5GEdk!;(!*#s|>Kmm6$I5`qJPOybNbW7sWZR7X&8bxDjYJ!b1&)R#MUh2y zU0`{A=_}!LfY<*Pi z)hn!(xNA{&NpmL-uxm+8)maw1WC_ljXV(S7fe2;SJTBw9kNQl%R6k>_e6Yqm4}nUU zes7IqVfK5tPzl~DUSPa$jw8l{;{${s|jmhk&S_?8J%28{hbjD@3RRYw-euR1xHM#8a+Y3%6%JFNdZ>a2Ck!r!A>dEZ|lG~S$?QC@bB!9*;yHPE`KZ4}zv?RAT zTfW0~q8y=iOnaPtTg6v>tH>D7F2DJw;y)^WcP`jpvL5^kDlWOLS@(#%j6c|*a{)%& zhH4L^RoOhDrfSR}DPE6OvT^O4%r1gL8~faZEwAJWYb>q(j69F`Nx!-cb$xgr1?N5o z*eQnB8=m}~^h-}zEO`egw4|Rtc6{c8LZi?A_#?7zqsVqJrY5Bn@b=CwdX9#k+QcWX zA+y942{xR|2-PZ=vp?}QJb75~*@)ntwA+VP6ehsaA?yG7%Z^xyEPQq<&Ua9lE zEn8=8KI1_o>d=177WBdw=^cfKiQvclrzL2-6@(p%k0%3OsQxRI^?hOc^j9c(!i)Vp z{lPCWg_MrR`vdRbJWO~$Qa!z|U-6>Do$q6Vz{h)vAuY>3uEykzLt3UmO2@kY`4cYA zUWhP!ZKnU&Na#C+9vcaK{0sgl{i_?7I^dGUBOUrc_#N4nFM-#ObX-vBX8keu1Og2_ z%4O%sPx5~PLF8rjh;Rls`AMrmlA@7$54H79+I# zSC}e6So11X><7{p^o$&ou{EN6qBHI-sR%zWHtdizZS@SXeM9Grxz$-bpY!?qP3!gT%s+BOS+z5;X$NVEYx00^a)BfvoY@g1;mCEX7``Vur-{+cX zoxA}tU_XoPa}Af;Z*X*)Q?kmcw~hV}I#EEWn|W-`(l{-#Z}$tklP`QP39In8X7rsB z#MPazSYnrn!y)fJ#f$$4c@LcLDrK;GKTmH=ADhpy)P6xZzd8PmO9XL{&nX6dkmwl2 zN&XW$#%`2HZN|JAS(Pg6SG!Y`jfY;|oNA{uf)F^REyF3{L%adf^b#+A13;(DtU%=hD||4U*u4=EIUASO>{$zERo`m@Y_6zZmIn-Pm!}| zL$!QP0Fgb|4fU7x6zP?!PPG~LI1}B|*qEWHch0acJl>6*tskld{41PJuT*q0&iIZo zZdI~I=hqH}kM|yhgK9-7Z*FrWVbjk7HX$a{pmC$njB(Dc)qOypyNVM}GSnZJdv zG0@!<=)axZ7Opqjz^IEx4+^iR9n;k$6nqXHCNacz{Zx<+T9-REx`bDkNY3aVWI7%{ zW;u4ee0W3U8di`Ydx`8C3+8hd9^L>YCEX=~g*3Cw2W&TMlgvKjY!KIESakH&7cEyb zF*~2hI-lLs%K2>Tba(W0ck`1n=|Sl2%-QwLAJ?GH(DYO1#E;|s-53VVi7$Hv8e-R3 zQ0{LT{t@oXjy`oro~fPMRX05=sBi{M*Q42)d(Wt9pD9lKVI!^~V2yx;|9Z25DqM2} zrc;$gRt&-&|G03ie<%pP3viR@9pU4+AP;|vBRE0YB!tAgNv0E<<)@cK808qCw2FU@ zxcgzxIiPA-V&9CVF}VunwneVxA*$OeWSStyPlloCu+2%t+_;^nCA>`ZYhi4mJ&y1C zh^+Brk2(^BS2=$~@{*}m$dTdM2?8sx$VvM5<>1K}B~vV6gXIhp_?A$yvj$kb+rC8y z_1T5cb7_0SYH`9x8_63QHKA@IfpA<;r#*}Qg(xn=NzWhH4WfWx0bVE}dYt?-0EmQ% zZ_-ixY#xTu`$h1k!xQQ~C-W4+66ks%3-x=1$Cr*unDLy71gy8o=T?lLAAN#y)h|?Kf{ww+v%QUD?%&woR`yDms3@kU9)pLwz@vCmb5OWn8y8P&v zk%D6oyOc*|7j(ZOy>fD34fpNe|*}2;=fT-2^=+oz+qyEJv-W#@T9_W*`&$qZE$(~s|{bTbk zC~jbKhTNWP`n0Z~Um0FP2VsjCAES|X1T@=cT~ZD!Bz1=<8W%8y*DdBZWsQ}DbFhS$ z7P~pg?B|Nj>sGgSXQCh~pWq z+2A_k1?DALe^vh$#aqTK$VxW?Ck;Zn(pG+HR{>T}H#Z-zB>Q1oDJ2#p$?QedANGdL zG`2PpfWYSrA5e0WrEk18N#uD_E(xy=FC)hbuX75q5~+JVv##O>8!}nWAGvdM&-KM! zQyVsf9B+yI9nKO4w`@&wb%4#e+sB;Ki8LTsGU(Q={;kn!MCCzNDK;f#1kj-VqHLQX{_nFQc z$mW_NPvvFxXn($&*@-nMS@n;|{1(`w8GHe94D9y=v6Ut8cmEC!xa!i6Kd=KSrCkPI zojS8x`MWwJMyZ+3xgknX7n|?-LsTd5s|yF7Pok*dPU6(j455iD3_g@|;^BIOIK*G} z5kFJ#`00%oc_3u0)HM8pXE?H0E`vj%W*8*pbb?jLy)ys!2VEahc zi|tb??699mHkQhliLv_-wVs`$4$I_th@#2oewKX_NuDjwn*mF%ApJFhfYy|``ZpaF z`%9gYMvt~PDp7sR)9l!G{=UXCz9;*>w{g^1kPhKzLs(&D>`Ga}W$*hALYzysV{BiI zr2%7Hr(pgv&`(;XLkeU4&?S zPpp)F1p?t?OM!oYxxk&!@jqkP-bIhOH<*!SD9i13(`K(Dz?!hnpOs`W!Eb9OW;S@^ z8^$NYSw>86DQBetpliRb(Cl9zW>IF;Kt5TgL2Dr|m60o$kSASgN zOM-KxUjCK2!(-!V@+MMaZSqc2!(3@1#Sp5d?edn9b6GFLIa%d{$_R<~hG)lPiA@V1 z1>}H5PZV+sWnCjTLGqdzm*n3g#B4X;P5Yk!etRO3YcA^=z8Nn+mw#zCTA2+NJfX@p zmvIf;RF$7gy+r?0B$a!czWD>-^CTY{p#qjp7Okz|TQ_Tq4{oy-Kn98EM!4e>AGvs= z8eDEd-_Q>2a-jR7&V|czB%gYEEiKX{1_ZxO>;zig{mn0Nb9cE5TS&NCdUml+N5I7# zo7l_UrB9$&8d@?bJh`1_aw@}oMH=rK@hx8Q<;0y|_ze--f%QxC1AK&i+O}p)L|x9H z1KL#v@H_)}-&rGo#KFPC_Xm{f`pnlBC^)xeTMZn~?eI0an~xln+L|km_Eqqc+MDSW zxO2ON9hEwp74f4Ei{jl`B)IvPr} zx;53Z<%|+Vx8zl_hS(#=a%|E>S#rN)$-F+WTqYx!+*IBuO%z9ADtkyMk~z2RkEq|~ zS?>BHa;NwJ{oK_@xn#5D3fnxUq&*>N+$v(?LHC+yR27RU*V&{aH<~Y_MT;cfDAU)lz)mesE@5u zqTzn7rNKxbd}R3pJTm}x`D>(6Nx2PSc{T~XE6>6xwT`s^rGB>7yF2gy`n$=ZeRbfS zCbGL=L#943CGl3>_@(0E{WX0KTdninq-(R*Gjj{t?nX-JQrsS^|7AmYOR1CO>4>n( z7PF@HKQ{PF^K=Nmqxh~9lGrY+oa{`{U_dN{i=6NGB16h_tDxL$qBVF*1(YRBrc$}Y z#?6&A#{HCxd>38*joKEtyj%fPZum@TX{acNvKgIEL~rk?xv(JIjHm^@?m(>cB1FOs+0@@dkD8zm4wP zQ_isi)<~1m96}b^?hW|EBF;C!8q|s%_ICsbKEL$M!HgK;l?QL7d*UD<17Ibxi4$dBA{W0Qdqn$Xd3O9+nLkDe|sbnCp^UY zX*G;7G~Mx4FOkvri2ks;=w%5Dlr{l;8yM3gWdgBz|H8s?IdCDMT{&NQt*-G1M2&cOfi`QWYRF1ehuAaGt*tf>8hGw(4Rnc zs4tE0NI@Fh)BcdMg^&_`;k8nLo>E9d@6HiqSOZf-lhYZ1+7CfH{hZ-Fj?0AxAKZ%& z5?a5q%YcUaTnu`xjrp;sj%nkXF5c}77JP{9q<5{Wxvqta1$CBXAa-Q zjTz)h_n5z!z~|*%PNgP%En7ysT+QFHsV={l>Vz>`n?0*=UI%$wg;hDPDBgxD-f9}- zGi?dIOI?S+oUfQZ8c?PZrbsaa6jaF<0ihX{6aJ4vGMc* z=N|%@%GCO?4Jr{-f>Q=y$r1(4d)fbx_ z7i$-YFrwEkZx+BCpPGz!?;jYE$LStvqc1NOH>H&OtEEC5JjDHq1itPC6@+oCs;K62 z+=3MgDqmwZweL|;6wkQTJ!r}($4k_@t*E-o|7<+rvf9Kr*_qrjC-K$J@y7e2h+wgC zlkVc*Sa27XAF5FN6YvU04^)1EDP)cKcH<)lQ~bi-rEU*-Iu}oo3V^xeYg-qE> zPbnOn3w~Ix6nl4*e6($5MMsUX^aJ=o=;g#R#>l@!W)n%!UNG+jv}ZAmj~3}^Gwm{u z=XGG)EP-ZI^Z^>~`$v|~5!zmMxXWJrSWkSvZ^j+&Q5UZuL8=xM#JaGVi_GH9J5`VD zjgRK)jy@)uCpTrK^?%z^UAp>&n+ed9kgjMNF&u7nu=byT83uO{~t)Gxg|(YtL535#7daz&Z++f$pX{jYmi@m znqfdHSwJRfTYU; zqwKk3PeMCSBTS@zjS&M@^%czx2+_3jJLgc7y|5jwl6v8avyM~z$=Umm(6_6g*@89X z3&8Rf*eA_`F{H7W6@kct6C7ebAAgQ6`Nf|VhGYpfsHM`99PGKb$moKYwRFY$$Y3#f z|Isx=U(+O}w^X5!``xV}%F4*!Rwj-)=zLA4O+fIaLYmuX_V4z#qfjAkZXV_uL28kV zGk9(Zi!+dCp6wcG_<&R6OY%M;Io%_M1LWJFXc=$7erEkO)we@Ns+2pxtHFB6aiIa^ zfq{NEW-EKJr$&-hIA+(q6BcqFa4(5uf8g4l;_V z)}d}(ZA@jKzfw>RDUYfhvl>^~y&qle_t0rKcdg*>paD zTB34?G#$ZR)Fw4;k=6YgJE&$^798HwWDv;(JJ?FOs>G&m5s5bkDTH?c0oGo+%CiX% zb@#Ic^w;R6`_dr`_5U@dSIld#O`{uj4l5HW*sD{+|4SS-G;Ey{%;0fTx%2E)^18=2 z@I*JTpdOt?+`pn+)?s&tDfxg4=}yxfTB%?C1fuXO>dL!aR)DD55=i9ApVlSdd;!$%KjMDHGuz!<{WBEdtR!RWlP`C(0$tr< zqI9sLFp^**8m=z*r1804iVHUcGBmjdCt+zI-S9dHZs%F>ZgZZAW1!C>G2O92GXy4E z(}rWvH-1?k)V8;I4E_+tN~D%?VwE2)+z$(|9%83bEd#=w+SrDIoYfK;W;s-jF^>}0 z4MQ<5XIsHwRJ1AvHJo}1HRFVk7X>TKRFy`fnWN14Q)|@P@FjlQo}260My=G`1sjQaVo>6ljOKPzXa$=4w2k~hrGzkAGFw^Ez;Niv zv92!l=x}IoEu)jre#5av1%4kj*zRa|(V7r}229jy*=nE8T5ukMit!|QcsSCjW+>tE zxI(}juxaX_L_IvL=R`g{{K%b78T{>TJ29?C79ljFIC4P{#jA>@+fw#uJpb?AurHU?yyTot_P4@c)iL%rr-jOm+< zvsSl1BUOiF=~`JGggzbEdMYbliPwfGP7ALTP!u?^_8yig?M=!ZTx;^7&yuqz=XJC=)akRGiF%sLcLyZ5e zsD{wZasB!TEr!6gyDzI6No_&pAr38*Ns#1l_s;ztY1={EK%Y?GJ>v`To<>F?OqCGg z_`yX>5&s=dDx&XXb}i0qeZV4$Mev@+UKfsqwGu}ClS&=>OsFfNEN_Oiv+CX3{h9Sg z4$l!64vMCfMtS{}3#=79L1V%M&sgHmMl1r^PT~&~7VOeYSel%LItul0vy>^><=Dm=-&m~~CPF^qY}U0CRN8E4RzSfG~LU&cK=h;!qtGm$Zh zPO)C>f&UFlu7-7vZSe+my@Srpt%@aWqGL*(*c8hA;n+1KJsE>)*q#eQKnB_Pu!^{G zmo&ZL0TZuap>-y{LL{f)0pldS)r%4tr=TGe+siDQEJpx#&agPHmS385>QP3DwhCzEOY_@MRT0Os-I zs?4nCwWjV|JY2KtF^+vI*5pm)Q&OXAj7zgSTh8b6+`CSUejqmj3X5PviI#M&7!VI_ zvxI(C=ji?0EyLGOj82#sI%0X}NOn7&Y4?hI^^26dTa%Y1HJ?*ln~-OA2Gs|Z_b7F% z-4E>7rgX6lWGi2cjL?uEAD96Qwe=?2l@R*qBw( zvm=^YuDDpMKA%Na$K=LS_i8;&y??`GYWc#5VZAXn7xPQ86^V)5P}2q1K{Zy2sZhMb z-RAwu;x{v7FdVwI&baTbG!bDcTYYqRa08kx-c4X|bV<62v(ng6hBQBAI*YfPL1_l) zoK8w{Z>(R>TNlH5lq_z23{l+Bl+_OX%5e4_wSJXp_@1m=4~uezV`af)g>66TgDQxd z1}HASqDv@LVtsjmS_VRVX9bxHJ!|S!+%K4HFh1RD^T{a^_BJYo0HaiUt&Dq&`rzdn z-CAYhH!5ecjf3LofNj|Xn6{oW;X>-VBl%y!B-D*%8aP;iX%rat6*6|1dhs$9SbFhD z^opDrN(+YiP1n-a~gA{cOYG@J7wZWU!tS;0w_csULIG3A9`S1jT@%sFk zb*WSa0&ExhQ}-OitEut8_%ric%r>7Hs)(o1xUqIlPlS%W#)TO0ox^NJC%k&WvmW^i z7lYi9ga+O>6G%yXwF1YkJXgOF_!J8A9AXA&J(g){@=iEdnlJ-XKidm#O@x8Etm$!V z;4}%^LDRsx!aZ$!0guqo!$!nv@OUlgc_3YJzb~NO=V}t8$lXGDyBoj3<581&D?$se zn_H1Pfd_x{Bi5bw6AR#5@(}n2XCG?kCsJ9n=#CSsZ{mh$JH%BawY zZV4K3x#!Kb66Dtn_TjumQtiiiJ1Zhvo!GTAV!9S?J7St)MqxWm8n+s4i)ykKYs*<0 z0#rwx5=fCioqE?ApXU%BX;#t|p^%wRZyIR?>QPZHL@QVEp2AGHe<4kj)YkG)&HQuj z?gIdcyKS6fS}aT41vx|invBF?uY^8CsV9xN)NC=HCeE=mmL=Y?ev+DL+K$1Lx%t`R zgnrbCzOs4L$s)6K-Bc@RCMaA#fpKZHmD71TXpVWQve&_uyT7M`n{^~eF=h~!K?NwZ zqkpVI2O7RVQko3uhcm~!_UNZgnlQ$n*tqzH?AVyljAg&V8;_Y0VlPNp!bX5- zzE(2zH9np|HT#&6DCu{##$%umPh~SFd4@YGeRXe6!(fk7M;?nA|pDP7C zMm7jqSwOkCBn;^fSSszq>1SU6zX`)iU;5Xo+yIlF3fKT)h22*5~TAVur%U948-WWfOL zXr++ zpN3nkLAI<=&iL$`0J-HfP&_F0$pNzpsb>a*@h_ZE1kB6V^Qq;FFX$~Tt3;NW10cY# zt>@Js!2+RWpuq3gMXAP?apoTZ3gipjV`olaM?nUJRDK_-eGfHI%E!MKnr3EGDY#eo zPv8(np%-H#fspdC2XlWwA@wBAaMW*%e$Yv+3@Bh+V94aBSZ=5g_zh!c0$bdJHBx1} zDETY`#>L-rbwZWVR0S#(jKHzhR3^EyTtSdZ*)D26$Jd{^f?Lt4_oIBX3xEX6RK5Zq zDIaPu7d?NoY4Y11MzlXrys*bbMxVK}hZt>1LZ&MlvoKc-D{NDiNkf521FhIV&>$>f6WLz{ zNl9cO9U{^hj2g+Yd{J#eFMkPKjME!ycX#xrZ(^fWJz zaocVb7LZ@WpSj#rv2O|}ug>jNNWAP$_S{mNTI%yA&gEbsV-3o7iHMJle}y zCYZ_>Ya-59X*qK|$Xl&pQj4C8*P!7HC%>c2t-CrM<4?xFJRSgWBG&0%+aHgqv*tWj zlas}4XgYaEpAUcmScPdCSwg6>Zx}yq&NTr7lUuH3msvQK6cvT&B!p=;yy(*d_q=J@i-?B2FTSA{VV z^(npbZgfTNX;K&>%E{N`imH|w=+%5?t#A$bHTjq`mBI9x`&U&iThXxPpWD?H6cZ=B z@^ddkJXq-4y0(ghwkQG`wp4OX1ic%G;D?+N#|l*!U~R!~Y0P5|dep5pPIUCIql7L3 zKJnP!jrF*L##xS?DrfakQ|rbijNuICOb?BPtKNWu*z!gR(*%8-KShWgTrpq7mr5Nk zah<#<8s3%Hi=)Uon0DWvcK2IjX6V`|B{+3hi`16%6<)wRU`KCXIJfX+r&Bs1(9a9) zHxwSc!rbEdnl>4qupjM-Ja18-+1lJG*tNASq_|R_-0QksoVkAyQZ?DR&MR!{kQQl= z8R>u-y5F2%gnS@naf{`cXk0+aof8^0Pur{ z^rwF5!`P-$_oM#n-nDJ;rlF=u5iYKd!hJUeLL`gtf(UL#mM-gt60R>2*xscmnmw+; z-fY-e2%m%Lal6t5Hic$dCW4(4?kcL|Z*%y5p0Ewx6SwwfXLmYg(Ox)43agthBX9z4 z_TBejYT$H});GiCXZYtPoA%%kEF{^Ux1V?3Ukz->A-ZFWexz2Maqb)%=~go&1wa>e z`QnH8xc16uPg9VUAUG5x?G~ZpYQoTkot8Iw0uM^QcA4_2+x^^d#)TAZg}oW;2p zUYr5X;_M2QFDldtKNUv>j}1}~UW^Oez7@EAMd&H;>aOZnl9Kr?o=QXh$+XH^fW2F-Q%x`X>~J%4z%$D!f`A(f zQiSHP-CFzECv~a==?d=om&T)-iteD3@y`uVH%$8i_6uy8&@H$27H=$^ER4=U^I28! zC{0-&I2&##ZXf((yll=LiXNCw$U5{_TzQ`Db8~<3UAPJ3Z?5UkX2lhr2U!$iUSNkb z4YESDFR})GIXGtre=uKEWqm-h_$nbtjuv^YE$18o95}qsl@PMG1fSsV-h{Z{&kARt zi`w>>pUB+DTwoSfGxSG47{Z!RlonZ(b~UWE7AYF=W^B&4^GTa!PZr_XQhS2i+Lp^q;(LDpYce*X(RJ)skz@mu&EFhl2M zIDL6^*pu4flzdjQ8}Bv{W|h!kAsMK3K83qtB==BdpRHdX!z;{yv; z>}ry}-5VBcc+`ky1I@wOPpHTZWq1Q&RpcMbdDMI4R6QHE;Mo0=SOsUlgf9=R39tVW zZ`M$cMP)Kr@w6yXqOxQ|k$I*oQ+4uKs}^hTDT&IA04Uzj7A4_)Yjc%(jM{c&V7*l_ zfcmtnRik=>0>gPlr|{?S+F(tivlw8t9hrPkpGL5>yH<6@w(AyBn|yCsub}$CA4<*V zw{h+*6Gx6d$>?@^T%vqwIM7bES2B0|+QLV))30~XzP7y7g3@o`}nVF!y4;w7M% zyuqn>+zzEW+Rkmlk8uCx7Z<>x2w$g~W+{Tx%8odV@Jc&|yzO3)_DSwK3 zy|ErMf4#oam~y`v`@+sqaMOI5yyWN`%WBj2?r&Z7HfWVykiD9ipMc6bx3fn{-0iIK zSSU8TT56-kz(S93DdU=WmN9|%s0exy(~mwvS8Dr2rk=|z9sV1NXxljGw#2 z$Tga`&f#*K$x6&bX{X1nX)%uWp=MiLD8KMg@;wYJek@kpQ`IfwiI&|eI--rXIrx6m zP$2yN&G*MA)A;el=v0Q!G!e%Z@ah6jM6`Xw`-N9f#23~i9S|6Ldyk%b`*Q{1+g>#q7)dg>%%*X@ zJ*1Mer;}GZ9eUdQ@8H)omkw0ae77tgnYGZ+4%QJb=tDeI>9FKz(JHmE&D!y*O83<| z4#J!{Z;{Uyxgi9SVJC9$ZcvqZ1jnR)x33R#jlVA~I=E6gXlpt|^ZDMQUT%m!fmtbH z<)rWQcC%@i7wq9i;mC$x-Ww`KA3XA&H)#5wVHw1{v9gL924mS=+ zj%Ws}ZL>MK1-of;0thmO9cPy*o65>^DWm$!?&e0j2`Hr6YY4(JWlGD}FB=U~bVdeB z@$J0L=7K3FNjZHrlH@fNF8y=J`=OM~g84~b=9fuSR@Hx3^IP-BqtqEw8UJCL-)oi& z%Q&O{6C%FNhCD&WAM=z-tBgt<*z`^&h7vYhP`iZT&baToknN~p755H$?OgOHbuC^^ z7T85;?oc*NDZ7=IUT@B)?RUO_PY!zQ=Oq=eF4*T=o_ZORJ&OvuTPKonRgv$vQFKvw zSBNsH2^|mFcxIi&(vvt#OA@UOoTasQYEJ0zsUF5zy)}!uF^J))*FMcevTI`I(2h?m z>Xn?(Cow5SshEVBQD3CR4I#4NqlL`OT5xEmB^C`zP8gDyl%X(B!Qkw81=}?V{T{EI z?aA9aXVpw|jLv9)YU>s4o%453Rc3a|Yo?8DE5|p@3Qu@)t`Lf{3v723nCnGR9$3D4 zEHILi?e`R22LsJG&xRN2sTL710@FB%*iIs1LiM>b%>SmdEb>&(+PD62gMq)(laOmJp z&!1yad`7LO-=(C9^zT)c!BF-ZY6|(0ssD$HmN%+89b&XQ03d;3AYxf7^wi=b(}R?t zb=iwj;TiPk!SAYQP8zOx^=ZO6dPZ&AM~e-8nei9qivO zE!?y>UxoUvNqPRHD?D^XILbU`B_%3{JIEVLOqnu897~R^iJznQHWT*zcbOri;EnF3pX8j^l{9=cW`;fuNvNGTl%jz(pP%6 zZhWCv@T0EQvPw3N#T^HmHzVnZUbqUxK$E&>yFI3U{gQnBPm2$WDE37xVQkLXgJksI zlF?tV>%IJEeNe}9JqxyUKVZ;(@`dl8#rx#TzmxYD-k(J2{pCN3c>KLY!Gn0UN6ghw zCRWcTma&UEnY6-LT%ZIxQU>G_?^Jl_I2W^CdY zK78buGqzMHuW((S`@TVD>kz0w<_#% zSYpy{b@@bhDT;m)0T80|V(U`uEEg8ib zbSsEqfU|AZioEh8>yljBsN0WixX^!!E$m@Yy5^5z#`GJ5&4*i?7MD0=8bbh@==7V~ zQ{Gy9Kl1}e5mNnXe%yUj(%IyE|B4gZCYVeN0(KO>z_3dbG)>HEG3(wn&x~Grz%c)U=!;l;WX_a1w=`PpXb+&I&Kae;LgIpN2>yt(?b(QD zq`qjcf90}N#Kh!pi+=baG3^*6$)cz+8)2LcF`bVYAg%Bu7jKU7y-u||n!~adS81{f zAFxC|V5mnvbBbI~!_Xmi>c}@87=ogDHgHI%60sz(`$cwv;CVf0MM}^A2zvY>Iz{ud z*v4F%fCDSbDZl`nZdVe%?y2HjxO+bm7w6{`r_>X)6YKeW#CF`L^@#k~AIh@`JrV!_ zty8PKBRaD=Y~6-8g-e*@PnW=6+rbQ*z7eogJiaJAq39Szae=G{VoFzNL7$ZcnT{)2 zM6YrvTF*|p=SGu*;^bxFxSkaesvqYG^aGC>8`a1i$JZ}}Ztu{Bl2D0e1f2vSUp~+L zOSFesn97~dO|Z~mFFD~ISr3us@j8|INl!$%5zcDfpD%Dfve3bxO>1DC7TY9fF{$1J z4VY8B7$2YFIBml^Zo|G@5Qipw_Nn15!F^+S9ben-v5e3YY@Pg!YYZJ~GglrbT;5Qf z<0AfVK;$W7Zcli9zeIE9v}U8%l_{N80``i=U2@;1+{lM}gnCt0NhB=5bZLkB>|>VC z(*eIAZu|Bb_3;qovx;_EhSVR(@ub8r#)mk-nz=H%sKAW5A~MVZc+f8`P;LSS`=6(6 z>Av%cbIIcoRexZk_EjyaAEHM0z}iUpCjwg>RV&B|@?>K+1Tl9HgdDS}J#WWQD_wY9 z8qD1DjA>gHKJr?ty6l^9unm1q>y zL>mCT%F<4%fGOxLv%L3exczBm5fl`cKcTt^qb$5EHVknxQ7}JtDC396y7CM`n>jbL zgZNW>I6DvGH3P$^0>asU<6?v1+IY&f(ZrJ7&|2f}!(ubq^VFTP-$5!75%0h^#H$)6yWf>Z|Rv6pcy=y+y9n*lf307`cv2?n@SRY zw_U0^Gms{AnNSp7aIXEDY1P>?v0g#*fsgdtH*4!4J`lwhSn@J>57Ty#C~Y7t=`x$5 zVw>hmcTZ(d3SL~&XpF*>;{#j@>hR+*933+A8SdThs?7V?} zc{qg67N1I#F4^V&4qKT3x)r&ucFg&z1~3f-e3~?HMRZ0q72wP}9SVUyJ*Sy{8^CyZ~-Z9=V3LMIjUU~7k^Em^FmqIwW3A3q}lLved&FbG7b+%Y5~G#g3Ox7np3v5 zU?R?Sz^h3uDCZIKkK@gWm|}_!C5k*zKpi)Z9<9*W#AkO>tG5Dk9KpG` zeTPG`vKQo^rj5liIfGaGF{zP^jm&K=KQaVCmW|1Ec7)t!24z6UvFq zf0kea8n}hj?H(PX#VECXX}$^LR2z%io`zj?Kvt-UXVun$yk1a&Wraz7|^ z`>h}KNnz%Dz)^Ibd?ag_4{O-vy*^PT8Ru|W5@sqzVo0{4Wywle2{_`F$$bvKU*bty zsfln?qx>9zGHcH<%=h(}p7xJF=*7KPS9xfu^1!s_H-+;D6u8if^qy$&4?#eYrw7pH zhcEIEWIy$#lN=DbifBf-!E&O$(disdN4fAZA@qM0zTG6{+{s(whugLVZ55&Rx?2SQ z`Kh9;XnvA5@0IY>>)R z#P$!f=9Wf1sGBL?7i8fWiaEt3W$}u4))}#^cE=4$ul8RX5ukT?7;271JsFl#<`@e> z(85zPVE<^Vr*4F~)#x;2G3I-cCS&p&&Kuv7mnKhx^<*gH+KN+5Nb&j>l^zBgbef<_ z=<80%v&Tsol&;G&$5VaQEEP1NOKevxrm}f3-4-&eu>Go5)V`S0&Nu1Z*#y5+Y-B0P zF~(_x!l3asnlrySEfdKxvq8eJPC>hb;nyc*j*%)C70W!PEjTVC#usc2(d-xdj$hj^ zoU9w~wrvdqcRO)pnaq1|7`p1KSac!LEPBXiYg94#=ADmXADFkQ(h<%2RBE?z#y~Tm z%tqSlX4YZswFCEWIX^wv+eZ>_48Jg3?P))->`9cGM^XBJ?7ew7m0jB~9*Rtrgpf>0 zGH!cs+csuSrb^~yCi6Vcl`>=w6_PTfC=o>>WS%LZkRcf}&(m*R*QNX3_xrr>^S$5u z9mn_2@9Q}Bxz}FnT<2Qnu+Cv!JKMiJNYMPGM7))-MtQ2E74^D6c?5RYckNR5{j`w^ zp}>G-Y4ggmxEFe%8JrIa0^$-zTRAckFRO?!J(P{5%BlFxSjAa)x{mfmdP7IGvaFw% z4Y3}vfV%JP;!8ohM~d{fJW>T-bE_NAo^0ncx_-r=Gjgf+I7`F6qw2S9zC8%)5I};d##B{K%F3yBe>LdUhsI5g8nR$)dNTCVSvD=SyQ$q_S(zW#-P{C5|5y z8B*lzCizdiggH9Jx#C)AT*6{r+-g4N@-{|^qk2TMSC8E_q)fp4b&Q3qR5X=FnB|v( zQPuPQ>}nxzj&=$NyT~8aIXH1PBRgh5c7vSpI2|kQ9vNk?a{cd1OrkKK_%?`Ya_ z#HC!D9R>EdK2FmlYK=#@`*BV9&T*pCwCru=liu`Q>nRGIlv=i9q)1TX&Uf z8r_HY*0`0zH%fJ%_KsoqErqSrwEJ5PJryyUJyms?OWYaNju{PZ+Z6?W|Ow_H?DI@qn^ps@apIi3D2w5YT=RS3oL6=yk44- zid(iCB7ND?Xu%Mxop+e^P`BHwhh^?EQq88EQ;a1yr-*4GHhzFThZhfaQjc-{D58*Y zOX75byn=fUk5f3OduHTyO{VkTI*zn_xa?~0kljMpSH|H4OP0fT?r zb;zKP{DY=aEVn({>_NS8NM5hWQ*awxz zl$?!S<1Uk&{V3kJQptD!z`eHc-q4fRo78?5f8Q^5!CCy6l#-eF$Dg0>OQmbftr44D z+IU!g`tI|bhfZ15ZlRy<-lyp>8EZ}%7q+!jTe{CeqGHn8{NT8d=a@Q`w^Fm+t=BfD zo)ZfNIgIN!`a1f|Ioz{BS;{_?=HRykzuNENt8Kb=yyAo_%4I!SfO>#PRXhTk#P15!e_qbpm3NyBK`e{>IWXV*O$M_t$M6Idd?eO4^ZH=Mgub-7dAJyUK9 z=zkmbOUNZ(l$$Ni<(#V3FK9i3TU&gZ@0J*)_p6|!okY=GeeBGa*kf_=qkLZyu4eee zy)d4=H+$d(yXkT{$f?3>YLs^l>z|Q&X11`4O2@{U7oX?yY%m-Tk$9D0 z&fj|;%Vm(0XwKcMa!8ohPg;;9923uXO2ydRP+6lhiRzSG!+GIE)l)#$!bvudBX7m; z5Ua#&3bBo!%kSvEY^%GE#G&Y?EqE#$<~UZj<{WS%Z8Uq$I^gzhbKAm+YqhNNb!92i zLv&j_fwgIi48xKyzxZJluQq)(`s3jR zxhU0oZTx@_QR%(L%jqg3yBlR=k*eJ2de!^^z0iY&4JQ`(*Q1)b7VG^!-3c)+kEnD{jGL_t zNQ(V=>gLvY?U)2}I=#rA*NH%-4WtD$e(T)waV@7J?1*p!ipB9Pp}g(d{}!m z4zV?!AdYA~t@QC}bnHkdp1Xm^y!JVPx0s3bA68T3=huF z*4wA6dEOG_r!V%_xvovVOx{ZGl9@9Z*u*tE*q z)R?$BRG}~x@WOKzGrQ_O%i701H7Jb{k{kcA8%ZyaxO_+0hWeEmS+g;h#6`p46W=F{ znbepLI*xKybSd~vI2nhX{&>{-Q*;!G7)4gZ#9?!xewnuT^NCcum|!)lhz1FoUL996 z2bu2rS*F;uchswF55C9aPAio#v{xyoyB`R(+6gVA4-Ja?M7LJSV5=XQ#79H>sqMk= zM9|8_zDE@Eae+-QiR^=la8DwgXaYVT?(2C}T&FGG)hbV1tGD0$rHtzXFCw~j8H}Pq z!Q#z0BhG`|!EB@jCd4wg3NGsE8g(qW!WW8jIrvbMNdUMp#Ic++tiX1Rrvb8-cH3+?+nQgs;(1s zJ_$Rri{sdb8kFPi`sX9YseR%Hp1hr4(N~@AJgR?TwqtXN$p3uPDFNlOIGy>VExN## z!8x0q#24>2jCkUm*5aC(XC51>KGt-7pciD|`Q1=#?zqtbzSqJkGm$^Ockvm$-5Vnx6bo+2D@=@pFbYPrEE_1Ahdpk z+Rl!gqnk-SJ1qj2)EC`h)?Y@VW zE9M@rQe8M{CKM4kyZG}UTZNJtr_KDSkXTRf4aAvEquD{~LdTomFKF7$zEXYb_}umf zDzp0DS=#4y!kshy7q28;nzYEkw12TSZhVk>=+f;eCXx2cqiT+|&+c_-_R3AH%Y;=^ z)P)^-cWV7hqDdqx+s50l2{>i09oCeo}wRq=l%(UrMao7yV5W-6;# zx=d{$CVl&}(9LQ+)Z)q=o0bX`?;FE!&u`GMsFrE-s0|1vOd4N`w+vTU7>IkxH8t4R zq;Jh5J#N6X8mX=vsjhzU4Yfx2O2K9Q`Wl}^#Y)b2&MI2PnwmN#-v=g`drbP1E8*0v zsZ29k2G)WM$My8BDUR7cjn^D89pC5*{MT34`hy9l1tg*+EgsyZH z7j?eQ3hS(EGMIRAYyw4bcJ==_~^Sw&T_O8 zbS$(S%--0G-CtElw_eJsW{$5rynNKr@N}5tsphD1SI**{Y+3h%8rhcnf8ORxy!!aFWaOrM7rsW`5r6qyzr;MUpT}b=LLl8! zwYpIsui9gF`Iwu_W@HZ8?F{Ngn@gAaxhaIX=G`#+*7w%X6nCoHS$+NoLv)?i-NEBBRu$tmSKKN~+Dg~)54sdBqy}sk za^FoA-Nn6Te4x!=tkyD6CweUKX9n@l42jHFFQqWrN=ngHKkmJ}kmT8RL99kZ1dDB` za31+oe=kGvDfqk1qN|FrVVt*qe=g3r!au?59*eqgFYjl8SX@P?MlYrsSM3{q`J1FL zekaWb*FD~N=XqzbJLj9D5B1+aGS9{My`^~h3X?$DGFoyT(%8OA4E>w>QRO3Bjp+Wzg>8b;bjpOVu zZMx6oBDvaGg_rYKlD|97ox;7^!5BEQ+^kelRNE|K*;V2jc{}!OX|w&r=1zk$GcU8v zY4`1(3>QPU1@OmIZ9P{Hg(R7Eo&H8zclQKlsOR_3*q4)u_7$u;)oo?hX7AZ@_74x- zp1wp?X18{>dSK+ztd#nYchrHJP5;|ze1cbd`8Jq0OKQb^#SWcd=rRv&y{mEMsjS0N z$~)7z;XBRNBs$|d{aWQd)8BJdn5$iJ>Ywo*MXTG&GUBp2J`RtqHFWIme~~XLGjA74 z{mFl45dY>!{-j;c3++rF#>&Io%jb1x=G}f#xvnY|zM8UBohTn&RNpw=*k{$8ME$CC zP*78U&}LqH)wj?d{66%=gPwJlcvg>7ieCnbKe`$qp8y||lJZ`DEFd>!HBO&}cZ~b#vbo8M`H80} zMUBimos!kqYK!niRz@?M3m2;EolF8msOzp}h1bqo)0%Ac`45g2QewrSWAGfS6fQ0woK@7tP` zNoyNW(ry3yVv~ns>-4qH57P|$%z|2*1-rSV3TGW=JIAfR=X(8m?r&u`CM~Qkc|v@n zueydtvru!aEalNdZO@TLg*3tMm$C16tPGhW-^{j)?KT{uRe1H{DVjb@srCa_RC=VL z-k((E)raRD-`thotyW?Zm)GyziUgE<-;T@Y00YZ0-V1$UP`O62pr7&P!QIYNS8drLCkb@)AHt>fnVOm z-$(-jHt&21dmc0)&C|t2`7Y=y6N9m0K|^y;kTq6-R9i8z|N8P!nDX2{b@6uoAP^{K(P`nyzN#-f7RXEL^b*eVwY~ShA+}H(|D`MA~40c`BObbqHi}Orf zf7!6Yx||*smJ{C1scA+VKXSRQ@prm6Ix{KhaUOKbrI;FfgQqj% z=r!b~`;!Dupmo=cYc}+jZ-t4njKD^|RJ`=clQHcBP&Q>j4tk6G_}FD2=((;k_(g99if zzP`s9>2%LGiFlq)o-sH&DDJ1Z@s72cDeAXN;QY!ndX-XfuZj1%{6gLJQm|1kS*!L>zM;lY<`%&|-by(`niB%a)zp6a?+ z3;k31mxwo>k(KGunLVo*>&%eyZ}KcYZilvhbI-_I$aUCHOS_dp=W8F=VJgwWUGRTJ zt$vF1zfyP9yj#3AdAr*&S5sX-FXfGFvC3IB{U<4JoSv))Q7Zp*ZfKfZxo=!lG=-Z? z3sl{ysHj+q9)CASu{g`f@@UyE-9BFFeU8e&I8z(xZEry%%O%&xt#7+5(^dqXeKs;? zuePx;&S)sy)7fVP1TlGhT|OM^8Rbc$qu-bFOh>No&d~J^5&#&(sICSL+ME+r8pX zCXk(#)i`-ZGAmcxi&6E3WJS5*SKgxD$?!1T`U+9o+hdO=H$_WF8rrXkzjgJb1i#{_ zv1Fyu^I>kS*78w}bC6Kk^ z*2_buY2H)m`1!A2c=gx=f9S*4Q*^p(8mZzg>wPMWa}-KMheT|HD}|oc^dE}vW40Y- zHIuG=H{-8#)MoeX)f)vob2nb;ppA?KjTk>x*ZAW6e;qxYw{BH$oRgcL&V1XyTGN#1 zz-3f)$w78DW}ozqOPoh(pA6(R&qZsmD1BS1&8X| z0aMDV<{D1~B^o*k!}T^DpOL(mRu_+(y8O!JGoIT$N+~S{Jve(|u+Q91&c!ZuC!xOU zy|&IkTWfjg*vOV^TTR1X_22yK5NS{#`=Bz+S6T*{-B&C-gfCtZd1E?s8IFHn_& zd|R>u@+{hGzYdY3{i4>jiou)E$@&0+BiMHs5 zR2R#&uvAq`WyBA)CZ1t#uJvn zxj3V!^ZY*6O7T9PmH`qz7A~cgU_%NVz4xy%bZWoe;k$SJ1hae(s7J4jhVS(040U8P z&3_GG(N7zk|2)&w%#4zQ#b%0qk>iHAt7xrkK95Jb&MTi{9w@i99GjO!O@_bCn*)(VMlPK3v zl61w{w*C#SS9blIo+@@xtoS30W)(iJuV42SWYm6Y3{f^(5X-t&|K8VcCzC7qhDF$W ziqgvr>a4A7LF#)OT&aZ!W_Vd3ilZ<;}k&Sm~(bs0%s9IGU8|+c*-FC#1 zwD6Zkmw1P(liz9b5x6Wdu-tspDx{1dp7FE}bL;rX07seU zVu&Z}EN{8NgP66}@4YKR8OonOiIN}Z@IUU)Aa64F+j6C`^GD&%Y{vGf-ckBCJ^z44 zqZ3?%7h;|XtBlCrto5eWRf!GZQXze^Rc*)TB_|djK&no9h;o{~=Zzk_`<9EzSdeeP zf!+sfm$q*_*}B&`8fWT%k#t{Xpm86L*z@3atk08H(kRlExkqO-lTn|)FD$s&jb+iB zFzMdN)41-uxP2v}7loELm0J*=MW=d|udn`;E4N+N`Fdw=K)7#(bBb}+Q6b0WeI}!p zK~}eWjh~BDr-XP>F(+Gomhz~r>-@69rl~rLE=9A6W{~z&!JEa8E8LWAe0-_muiLdZ z&K;NQ>1O4(c{_YJ&`2{cJlWm0cUCa%L}vG`(!Aw&=nh%Y8(oVdR@ENsl6?LhvN_Fy zB_x7;qZ1EHR>vyo7)0f@=-xU|&fY6I-fvmD^m$Ng#!>s>H%HIbfZVwbca8qiBvv^b z|58tUsbJ6OSObGy1D_q8H_@)7M_a(p6JG*+`E{zl);|@~c+{=rD~WyXm;G5ROv%&r z+|p~gLo_rm1XKNU1Lvlbzpsxa+*ae`4z3xybXrmIW^JBamXkcs51Q&8N~Sc%(2u-V zs1@ZrEVbvVG%sQ)BYo5@DtunoxZ9XGx0;sG<+yNgkvC1u6=Nr}daHV~GbU$93#yM_ z4t`Q|&N=2j@lE!dCvOtn?2s)YrAy&?pHaXj{o%}Owx>rw@HcdRs?WDeue-!=Mp7A6 zJ@s^W1k1Fm7_GYs--N2N>$}i3S%A2FxSglKwsBE)eGb$_Dl3V&c@+-xXw*1Zp32bp$Z$!99 z?uV_3mt+T0*m323J&9k*Fwyw9xN}GPMqBspyCoabiO#zRo8&aIDVzic9KCho=LcGL zJ%{Djs6M}+zS_6sxaK~Pu(2vTsk_>mYSbd=x3ipH^XQKK>T~lUmzj%Jm0X??+p71~ zPSagADpDGuUo6ZkAX^Rfe_JHZ!`}9(m$y%4LIxsQ)i2KK>o4NXi~7DSZMf~E z9j;Io^ZH)0;=A+kMV<}ycbO^ES3A1&o!(#A&AV-aZ>A(ywSC`sv$OO(9^di>`<_bu z#AF%wjI%?khFMcY+`u;)o37Is%RJQ-Po3iR!L*A+u@+gymI6%TDbYrwkIdW$M&pAW zN^dK|gNU>bb^G)AcPrQ!Y$fIXh$izL+ZN5VWeC)~Pcb@vp4)CLJ7Ll3zf4%f`w;u-gxx3h^djsE| zWoGv)`%1cRA8<{mU|tax+P81w=vOle3kP#oHx~;Nd#L4TYD0m-h_DHyukcAj%L*0TLY%q$Ott1Cp0L70JLUBk@NVu3=id~jh+?xbGNpf6w zb8`|C6!i4;6!1g~IJ#H~qVRaUppdYjurNQs;CJHS9{sh51}=jp8qbCi+H0dwY$y!e29ZlpSHslC!VH#0> z2|-ctG8;5@(Z$hB6GSruHo=P^(gPz2rhKhhOJp#%s9u#hfcvE#6!{}@3189)gO2?=2SriB&$Ga@Q1B7kAT zqEP~9Hn>fI1lbEr7eNxnV+BwM65)h@v=PjI4}nn$3jo=`YZ9!yNBZAS{`aGMr1#zk zasN3&xb{Cs{xS8RLn0VF5E26aIr5K5!lI%A!qCZqn8XQ*f;kApV=$lxfso3ucp)%` zKm-HX7ES~QRDwW47Lb)i!7i|DB6y4djtvXe5CLLC!EGS{Q8vf|z#h>kHoOo9Yy&Hb zg?1q<1ZhqPri&H=*eGEUXfvWBcxV8F0%UL)G?*$17RQ0fA_928DjKp4Q4xqFSW1*l z1S6@OC>q)^v{yU^2gY!s7{DhEvnL#=je`Y)!9u(VL7Tzi z&=Aiez%p@=DDhw&h&Ci*tOz(*Y$Bjvm<=rojS@mU4iBvaLkvm?+6C~b7!)Ko3{Vb` zArOox8wLyQ86yf&!~lu_4~PxNhDHNyAVw6xgG@{q4=Gd>h!^Yy>>LXO1t|>!`T-^y z;sv+{h`I>GEgH}Td&EMVVgMHyU>1F=GFS5o`};4F|S^LregLv_+up0OfH~{nSQ8ZW#2m!{#!lVBu5TQc|k+leEB0Y$a;)Ebo;ZRt}=CI&2;9$jK zArr*`0sJv$G_Zak7!Ztbu((BpaX?(6c!-ZZN-$5z{Jj-~@sPrRxeNbU0X`TAJ{}Lr zV{b0pFM@)O%^yiXa{beWWJbsn!VN}52&fI5epqTy3&Hujk8lpuD~yG>5QQ~_?2Aw? z5C&vqe>8?h!^Vt;bqK~pz(EH_0}Ksl6P5?8Qv$R2Q|KC?gn)d2fr8@zAaX+Cwg@nJ z5w?GU1T_AN{215)?Llw?z_t+hUmbW+NPJir61oF4INzWjW*v)zwzUWGkP5Ld!~rIO zS;7ztZ+#CE&_pOB5Cp7|u#^y4A#JP>P!FQ&zgo!We-BYY03DkA zH-UdY;lDEq6NLdG_TRmK*897M0Qv7uLN)x|OMog2^ag(=b+>oszYvO>X0;UE+0601z$pbzR2Zti~px{uVzyz@%ivUIjYYGcP5rmG2FgWda zfB`3t00krvfBkJ5DFH~(m@CZA^;p<0M}3sC<-hQhy&!Q!1n_oLj905 zupljiiU5$4f|-Ct5D&po7D7-!T>uU=oDboEFM!SgbkapdpcoIXlObK;pcESiY=*9AZgkUN1?MaU%5{-<$a5F%jLz}*0SfYb``1oB#>fWd%R4pK>w`NG*N zL9mrokBv7IpxT9st{*vH|45IR}%0^#NxD zl6-;$SmdvI7!4*sNgiZ)cpycvAA+_h4kW=a1_l@(ZbDK3Du+`Yh%p?<^?`PQra>=Y6=)RXt-#jdvJN_>z(#@0 zpaKFmB&5oPGd?^hJAj#iY#Y!)3P7MR9H?8N6AV|wKqEjGKoroag`7T;Izfp7@BzZG zX!o*5sO%wh*hu^DsE8zrSTF~aN5Bn1T7)UW!3QG(nKlO4Fn~ZoSR7;pXs`|_k3ePv zoknP1!XWN}m2to`fjbXC1MCelJ&5N$bz-5S2`a!q1p^EV7#}b-Kn2ExstQm#!6uG@ zDs%!R{Cyz;XHINoHKmkd|5o*xbfA>YWKGH^3Buw>@9$0jU zhed=2pYOez1F7r~{Qwc{X${!kA3j0a!G?!Z5||FWb7bxwb)-mu#g0Sh?-c`kMGrg; zbRpTt-;Dmp*599z6nak^Fkz%kpgp)3nX%UkCtpab~p0%QH_(uA;d!NcVl0?}|NL4(r(Tp>t9|Kkg~9D>|6d_v%YOBDDPkov*f zg0Mm51O;Ri3dThG|4;>@gv}9I3&KWPgjg65n!!ngA%sCVhK7qcgxY`H*}wa|xBeb) zz~YhJ!affRL!<}c4$3#6Knn9E3SA(9`vkxv4vr|u9U2}e2ZPuTObZWUBy`0Bvn~X` zK`5fI!9s2o5QN*Jz-5A93g?TW5C&|($igTTQs5zygCUfz0FMOk9Fg7M+!Jzz#r`Qr z5#1mQK;{7M8~)NJ(z`bg?iB%X69g=nKB9}gnLzSL3&DV{kbsYcFO?A85RM|ULNE~s z?}EVa{<>y@4kdgr(NL9uhannN23X*>p+F8@W<)ZvLb?ww4vDu76#r80uhYA$IyRa{a1VY@AvQRX^(4YXD|mK z?1HcfL+CTYD-I-LAd5x#1X2O@60jZUiWR=L0@eePHE_!al!F2x3UDY2-$g=c4wRXL zt6R_oBS1ABuw@YAAmVVw2Vy)Z-k`fM5T`+e1bHvm41Ajm4lu|p;U)q_K;`yFQqVdG z7YNsc9AQCb1dI_7h4ci!!_^+4excsIIf&Nr@SP{jC88C09&%P7O7J)aq!%D0gBc(n zgmndD!DEPo5WGDoBt&3Yl246=K` z44f|`5W)Y)C@4!n76M};qyHxmp+g9fwV<0kkhj4Q>A}HQ#85^L^bYm_U3!D#2T1_r z!O)epC^-L6+74YMqj4bX0ht!a0|5q<6GAiaP?sUd0U1FUK-zn_(8>h%@E`6DL@`iKEeb#NfF6y2_yDp`AWPVw@gP?P1t{v_d8UB4ej%U|qy=IIsB}OD1f|SSqKXHJ5EN*kiwl%6 zJeBY|0E$lFPy!KyX>dJ_w6RFq0Qc|p0M`Jt3zG)-;DFp-8-o;8AnS+cAic;OD7%6# za-hr_>A}N6ZEq$4K7xY*OaSG91Q;AuP(=#=ElAv7buRMo5P7^K3d|O07A`%IHu9JY z!NGuI2Q&x6JskKMB{GTzN)QG~KK!%@BVG4U~ zkb*!efgTL*JqAS9g&_(g8+%g`0>~3JLSg)Co3IBVymtc(FM_nuK-Yj>M4WIxGHb6N z=u~u1f7R#0IB@zAt%KHH z(T9|N|04*|`}4xV<_+CdAh#FLqgF`jIPeq>(&L|ai-Yftpt=qmAn=t5D40SK8Tb>B z8iD971nCHh<50~2&hp+fi9hs^nR~S1(iGf~?!|J53iJZSFS0Q70Si~I&^8f<|JnNc z6GR3BE_%Qg{%Q%sUL2VR^}@`;eOOQx0qp^*;K~-60gDjALdO0)%7p7_IHCA^3{E`= zH1yXsga|kTVC%3mgnT`a0!Uwhc>=8g2MFW{91I9XP_Yi*7QtyJDB6J=1(^aojstz5 zOowOhwZZZr0{|`)I4XDr1QUUH_=1A42f73TkpW~bP{IoN%zteY_8^ooVAl}y&?-n9 z+`@yMAQX^(WY%6koVO!A&=Y4U*1&V&75CaO4&3!Q*g$zFi8wQGmf?h5md5=zp5vd#5NY8vdpf_`Z*|otuRV_>PaAiJOJI zg_)zd1;JNRz4{{8NSrdJx=E?(#yDgvXsf|sEgkHO%ot@Ca z#P=B)OLokz|Ei}xf^{nrBC78o$(XSVR(CSz@K`w+MQ=IQ%Idwdcjp0;ai`S@dOOwsZBh`i&k z>$MsRlum_CB4lSsQiGyio}>N9dXH$~w#dhdoQ~>PqAM-@DLa>+^*j)J&nQMr#7b;S zY4$j;>rO;O9(g;>TrA6D4lc@z`DA@N7JQpYMEpNy$M)SHf3U;++i_N!Sg&Vi!tT1A zot2s6^(hk*TT-E-d{W|LpDZR)`%|rnZWo^pJkF#q-s``{T*{=c%gp3|d`qvC{oK{_ zP~^5xow6HVs^&glT{Di zv9+-MWjVFXYHnjIw$T;*Qe(X}>t?voX(^FUE4vSE z_U-ClHxaju-+dA9BC^$Ugxvr=wOia#rTo2$<@%HBLw0sMUyp46Iwp0)z@UeiZYG6q z=bh6&H`Tj$ca>IOyVh#6CWUv^>22o_2jqU<%{o?yEk>`Kt=^Yz?QiesXeaqSGA@0D z`D4U{nX+2Y@4!}(px}Y-*7fQGb26=D#x}nWuGWPWxcc4gVtrC^ggZ!PiS^R~<0G4b z!{+;i&g|U0Pej$Yt8kU|64kB@>!rIp5ZH~_`B87YAXvZOc;5~~z(wP=7aw+y`<)Wr zCMyVF(~Jn5W9IkD~WE|aIZvf+ki`UVlPuAi7zCCRJ~nd9<4-Z|}d0qcSj zWDM%3Y9!u}y$v8=-3TuDG9MG-pLx^9gK;gXfU)#?(V5hsVSK^Wr_J7Wrf00gh>uTd z==`pCed}46R=_7v*?)MpH7rwf-Y%oZ>7JAKj(!iFmDH1d-J1asG@>C-1{>&##eX($)yB1d za%Pd|t+~r}*X`P)20UMCX@h9A!^o{yq*fQ-cuP-B+x9D#;Yn&{h5`VmmJ5#Um zNg=u9)cMcfC|M5}=5Z*d7>w7{9OTCYFQk98 zOZN~Hl}&j-aS=Q8kXGdT*--g)rm`n2Xos~(OmA*f&UVc)M*UxB$RExhPaH{UzvzAW zaDwo*0)5lb1oP>_$Zw>s;>z!5?vIG%c#dwqnap<88~?PwpXZfJi|Nf(?rtKVuv54< zS>YeF9BardhiD6nNZ$@BYWELg_2%Y?7U*iS5+zWliBCCqf5J>#{oMb-(wOY^wdl9c zK1VY%{NfSqn!Eny>;>QR%?dN#ZFHl@xQY`*#Yo*tFT~0Oe^)v$K9%=jx?8mPuHsd8 zkx~|&uWz!cc)3EvjL!Eu7g-a3{={*f)Zode3tj6O8t$oa1*2k%7oLsz?hZL`53ow; zoe7Vq&yMSfxbgD7X7^)`(t0-QGw}|cd0W(z`3ktfyF2AMOwT#3i#yH&2t$IBhBt&Y|C@twQ7b*!K1?dv2JBw{(o> z=ZlT3sL=Adzj>Um%tZ;RAI^Y@z+*D?$T`c z(QqBKqFEsIj?7ab6XZ@lD5)iXDp~ELt;JK79(LjQx>T~#Ft?B0ZrK>u+j%WxAC&@i zYo-Fy^@E(QmWPaHyt5k_{5~Ah+-i;6HxnKFd+zDD;}co;Tejby!I=Z-}jvmUf;xV@w&MAmnDm0>nC-T%ef)^WClCo@tzT^|~Ybv^}W z#L9np5_$4x?XZkl>`I`#YN$Uab@(GodXRv zyWx+ze$_Q~YB3wUbk2IiUE036onm$Ovi&_Tq4w}aqEAw{PS}1ry4hL0`@6kR+=YFHI(g7sX`9w2M4))U;v@&J5z&Lmz+aWD^j~ zNiQWOulkwklyEhoM7L7n+hDaG!>m1V3{i2)mHkg1a3?F4$~Eb=&z2=ge>u~#;+S+2 zcZQPc*nLe710%|O9mz;tHb&2(I){mTtuMA^V$V%jm$(E+IF@CL#DlMQSILQshw`BI z3+7&0_*xnC;di!Bvv$CafRwQZD&lh0F+;HfPwSS(ym>r4s2cJxcS(b2EL|n3qUC$HyDb?x&{Z#^#WftMq60VvgZw_3D=# zPj?;`GitmS+sGxc6`QQ5cIJ}EPczSXgR)Rm9;-XYzEbUKt&~Y8>%)(ebYzqK{NfKs zz1_DgDOn*t>Ce1saN&plfgM4q)XI*BZPAW+|0*>-#grY*ysn3#l-4epSZSswXQlb+ zX8j6+3Zr{3L}oC#l<_Il&-WWxZKNI=e1AOoP)pN@m8?M?uIbu4$A`) z_>$h-Tif9!SMNx~N=ny#g>wJ6`++ZkZTHd|su}EFp?2NwSzpZK=R4U~BEzd9V)gX) z?uU_sc{0bx2W8as<;-n=mA7z^oGY2x&QtHpNzLx3U1mzLd0u<7dV`+PFe&8eehct> zNjp5xb`194)AKzOtJj#-U&}OXB}|OHy7c?d;#^hd3bwICb>HI5r72Sne;s?{Ybbu> z_a?kEcZiEuuIO&vDvvsM_x9rPStlV94O@&X=X|hmKxT`Nqm~D$))zw_pWC{3qek*c zX=U4{-O3D2hmJ9Y*8P@U6Hb`(`jnua{UcoOqx0vCH$l|rnk!B4sPWtJT8<_@Ze%64 z`k43RgL5GfBqnbkXZkk2aLEuI(JblyMe0u?R!2AWQ+Kk-gRK1(V~?KiT9dsBO-bv) zBLy6fEzwTjixoTbO*9JZw-3F37bX{VC(+Jl`|1yig~rL{&iXqEC(hl?Gjc9=H@Es0 zkG*b08h`b6D#KPBxej|(zAl*oho?77C^jX;-ODB9!bvuFqlHCw@+pUT)z?bjB_ztY zI$S@f%YODldFQ>ar5+r8NzSH8b53mgl3Eh{Ltj6J$8tVrZU(VJv1oGLzSd;zcWycSdNJ7 z!|BOdcjV2 zXizDWxQVas+9%nUkymmAVqV0$hCY>>Txaf&`f8Xq_4b4E>v27eqt6alrS8`r;yYP& zdPaunE~$sx36rNKF}E5wi{E&$8d^6hra!k(Sm}#Def`2gZG5F^NBlgiB*#R*f@LCE zVMB#SPQs~mzNzywBe(HKEuy3%O_h^}*v&m0U0HL(DU3%FqlkyodC&nvPgdHw(`fP) zY|nBY7s{2|J~Mw~O!(RG_o{PIk>4kbXm(Fs5ZHA8ZVd7IdrCWo|`eUI83#5Do(!Q8vUE&?N*=H1qFRn2FF`}Ch_=RCinaCi*`IP zuq*#eoesy0kvU%;w{o{uAVY4E)<=^j@p|=vc~13zqB;>TVK^KZU{JqC+F;V(=Yd=Fv6ocx3g{D z3RRTew$?*pCMM79tbX0Wbhd)^?DM3yo^Op<`lmy3?e|1YXxgT{Y3je{HIU4O579fE zy(Hil(&D*R{E2x%BS1;^6!=|vr3<+$?b%9hw^>gdE+BQN|<{- zytFjK#d{DHHecOmN|iV)_cN`;cl<$qO=NY1zHgxSd!|!6=l3U@ef7m23BCNV$nz9? z#5C%8Y1Mp$j@`1$ue@*USF3e0*k?P&C|e!N<$ef!An&EEBI4ZjrD;2@uVd$mo){<^ z*sps?dM0UhY5#DWZPxNkE`dzQ}PZaufP*QK91XA`7b z#N0g$e9|~O)xT!5UvI`w$aP3ZAHyB=^R-$I&R{&wTGF8Q0Yk%RRR6O?oa^5BY;MD< z;PDgf95gneb*=n)6)7@AVxdI~oHyNhni4Am{1=n-j-Fb+M*roRYDCHhlZ*FW-RVre zV47}uucV(+^mm{kvt8E0g9ESPq!Q7bkJv4Ihs(NWF}w`Uru5dMj}sc26(6-74SH}r z?S4ih{yc?Q|2Z#NeKQWCnIcf<{brP(^7A2-5L zRq8^?=Pi^UUwmU4N;Hm>|6I7}71`aylg9o__M0ksMF{@HS?;E(;h*l`c!mm(o=@3l z;AD1V3zFl)t zh`O_ODh^epYw?iYtZ2rCSnG@Z#YVofPqG+LjFRzM1-BiBjU3O$E(w!Z^o|akIF#0cI= zV`qbZye!^U9oRtsoOZEX$Xr-V8TV646fit9zWr#}QS)p#`YS_sXv4xul(l;Wx&2Fl zWZ9GX`RF>)Q%d=59UlwRtR$#^`=A+uZ5M)bMy%`T2Kn%qaP{-TlUBp&mg%$%N>fU= z`)+;VIASwX%-TTX_|A8fv=6>{o3RxX*c1Dr?h$+C6}| zT)xlij_)nSkbK^Jmhhu7F6NH9W#lq`BGVZvk1l^GeY)8{x$6Du!p-T-y58G6$v>-g zpD&ow&i)km@zrZe;x4D0tM_5;+l+2)56LQj-&U34SG@X)MJze|6i1km}P{nI=91ATkZAq0$w+J_5@>7>Ne3&aiGwIUjrccUhZEyLKM=a=9 zYm%KPAGCEOs0+ku&YzB5Zt{!j;V61YT#+YE9AEoo8>1@Gt<#$kJ2IIao!hO>sFBV3 zL#wZ^MXTFFfAvX@z7X3s`8GpZqf>P}Q=Y-y;?$ROHUnknG)gkdn5gQB&aOBvx*l|Y z?42|Cyxi_S-OWYUgaM81{f~3;JDBYg^{Ex1L&X*m@^7kcet)=Ml>V4cT(BC0P{c$? z%5Zdyr;kRMD35z=d@yBms-}z+BP_u$Y;IoU)9|9QZht^Ilf4~edxuYS@UqX zz40%1=AU+pgPO)yd2HpUjx#xEn@2WY+K%F6Q1cK-O5pX@<`Uk&pDJ_nvsUceL5Za( zZQjA;mj92jcM8rVYS?yT+qU(@wr$(Cor&#al1yyd*2K1L+uHNK-}hJTziJ=ssyUH1Ob#Ld}IuC!|lwKIuQaaE@N?h9Y98wgkl9ECQgM?=*N5zq#(d$$6W!=+= z`el`;O+k+WTmP)Xyr{C~cx7(+Tkx**Gs5sgM>Qzx3#``Nmi3@W zaE#V50#a7y>5$?#MVqP?&&+whtziS_J3c+qd=3sLW1mF??lydCh!@DO4*{x%ty^#R6?rl=Anilkr4hsP@Z%0RJ&-1f?j{G% zm%u%$O07%9nY*MDPzQ#s^xdBPV3M6$J(~kYTRIw;$QTGzseHcfKVyeQ2HJrl<%7H( zmCY;VVgj8Il*Ep`J;9icAb+P~tR1ba_j$!d&DR(-McUTf zgU&tl4FxmlF07QqcDcGD0_=q`_WC6k(b22jjC3J`rzO$>ir#a_503%3^s1A^zmb(( zB3j3RrQkNnGej{to2;t?C5n=QyZHlt_i0d6Vb3QBlaZ)@4>+k+-7WX9gEIRxFlxHs z_-C|CNRo0Y3DkBl)N+$K2BWLhc_SOHGU#1j?`@1nvRoSPq@TpDQuMiN1wY7F$Q?b> zI1FS;p{VdRyH%+(a7c`Cg-WKIlPwp!(!5y_!VG2ftfYJ)z1R}BD!}{sLK{(KdJC-h ztvE32^cyox=dC3QjjY-;>xTMdfeEwj<|rs0%UkAheW{WyJwSK@!_$b6UG+a8&`w&*spBLtmXR_HBOAQ6wUuP^W!Mck+NvqYp zZ{-a+CKW@9f~EDxWK$ID=e+e8)3|-8SdOT$^JV&B?;RARgVw$tav^}y#%(t!aaGjJ zX{%}uB$6ftoHN%`#W;@qL1-QPg4PCIB(?ie1WoCmt9nrfCDNnpGLe-&IDTGjhiv8d z8?3@qjdf7C+(U_a(=Mo77{I;sF^F?!oC+GyqmbXZW!S=){I3)Eq9eKbO5K;fv9PcK zIe0PrnBmuk4@1QjGvV%wDbGVid@Wt>1ZbskOCHt`uFg#F`!=R#@x|j>a&1kNt&!f& z+6o?yUq!Lm#L?f$DN2htZnmIGn3Hw;K$o4{<-V%y_?LRx)+=fmziOEd&84!=nIHY|s!(-h4n+r-Kv zQkvv+cQ7UBEAB8ld_qqRGCa@!sQWQ8bZ$XA4Fraus`J6bewDbuF02i3Q}9{I7Hxb!FZRHO#~mZ257QZ zEh<-4ezl!_9d+*9c#ej5y6T^#P;m^+HjX;N1i5zZPx&r0)H9eSqJz2_ckcx4*6MCA z^$er+9MU|+whd7qBN(GbzSvW4C9j4pby6$c&GMPsf3Zlc^6P%n5Q9C1EzpS;By{&0 z1zS|w;UJnOC?m!!87Q-@rN0GZTG3ZK1E^}BE_|OK1~rq)JN%O;OdJ!N_3STdPBna_ ztj||uvvEX6A|z8>dI$ZYtrCxmd}Z(}U}%%7d&Rn`-CAGVl@!c-Tyc!@jocuSDa6 zptzLWU*D3g*1$ zw_}*dSnO6=Z`iEo3|Q5Q+c=?I+tYmuTZv>!c4VXKcepcevWHKXP``ZNr(9?(B2aar zUwPu9-5$Sqd(ceb?ZeTty9u`kas4`oL08t=Y((J^=gWK7MEu4k4MV}>=^@Jowwvt? zBF9ipcv?_Mfh$6y$A&>dvJ?MUKNFz4V#GO zC}YT_*urL>m`!ZX22p{EvrnKT7{puF-*U!t5?NTto%`j<%9>r(RIumd7gZrmc8(1d z1Qc)P@sgm`!anV6l7U$3D95{4$cpm}G#NNllA&sX=8Ia|@z)3;V!w3ld!**LqRu7M6gAXiHF*+)W; z^pF6dIJJY@TS~Fbd1{|`BW>{sJD#AeAF4$~EWVRr9=nu!W|$(zgEO|&?LX+WD3Cpz z#nf}XCHujs+*ui{^oH71!xQlJvSiT5PQ|ckR+QH8bpFF}ycFirb4>=)tF_|NOzbEi*nhH_w0VQby>4zNOrkD(pdo^0xAwd%A zK{LsU+~W48tC6@%E0iajyk_rWSs{q6qgr2 zp=Bw2S!~pD9#!rl_JHqplHAltRQ}npb%g_SQlyK`(hQct55&jrV@cjgKuF5uBd( zowj89`WY2n6E+8h*Tg5#F}64=5Lar5M}uixJYgqHP0&^xokseC7|nC6zz?`1zR1*T zSlCRv+lB`+=*~t4{Ilx$)&{-736R=m)H6$!k1KHW=OvZ>>J5Q^r|n_vHs*EjMb8sE zGR3kazJ6Xpjf)Ove_($6!{YRbAKqz1-%M;H5i7V)ZlyE+5@dnC;0qtVt zGcTxAe1aopsck<;!twxaya-mU>x^Z03F4|S=83aM-V-Fu%fux0SMD{SV|6k2lW!() zie+7ezVdaZik0v4&*B;36hu1i8q&0Z+S*&VpIx(SSa-S3Ygd~` zo^{LdS$MmcWp8OZF9F?mfAzv?70D5r=a>xf)+M}6Q;a~CN0!+t1k7DUO|+k5H0jw* zmh=AXH6u?bBG1D!#sFq}1Ey*k7O4I#p+~Jut2dk2TX(hZHCsQ!1%UiZibhi-%lKGc z9Ds8_h3)gK0Swk2y=+tOW|*&kkR6zYxXG;CT$H(rxj&vZ3ap$$(k2IM9R3!eWcLx8 zB$irQ8vMw{J56?hs&k6qw;}ZDHBtcs)XXE$mRkTGVyETn%xFT&o_>K|<BNgqrY*HWd?FKEdsUW;;lW%7;D zNmvJtHnc{>$%yZxW$;a}!ry%DmXGB#IoYrq?~x7%f~>MtLgMkbF^CaIsyf(Y}$)xboJgIApKCuqu(r^*Ty; zi{#=8H{hP=6p^E5_M|jOXJ+DV^i8N9Ma^tR+>pTv7=j(I=PfP6lt^ym4A4;>^GQ)n zzwB-h`Vh+CspT-FTG9V}CTL_3WkN5`L6@w4@ zOJ&@e>1p${P>XYmL zy0H3Ahp|0oD}yc){yA!ZBSpKJ;&>h6?;}(SRiZRC>EUaPeMqb?$|8Z;AUi=>S*}h$ zbu3PD3f)83qB}++R%L-6%%yA1rIND3s|IdJ)!#I}WXSsvS1T}{D4G1pe5ofA zwLz+pg1E6S3D;o_KBZQ(^?8)(;$)&>2QqwRNRl2M1oi|sviQ}9 zC~?Y(qz`e4EeTps3IAT3f{Zs)c+Y)tm|q+B^x1@0q1(X=O33xe-u~*_h5Dg+>}fx0 z;|J0mv&}LUL@mFZE7}TdIwj@=#ol4MY;7bpB5;U*y=Ad;4%0rdZZya3_L!hV(i?h2sR-0k&1>p*}8}MU%gsC$`*Hw^k z&6$Kxg=Sjxbg4Xz8ZSA~KB7*MCJ2#fw;sh9;P@>;+~ibZSbs?>rVCR2={Jyol2^F5 zxIs58LI!`gmNv7dAFkiIv8-Y38aRhURP!5w+j3e12G`zOQWcczHli8?JJzvV=lb2+ zY667_50*`~YiH`qw+=7yOrfZ2AP@XlZflfCeLje&`_rHF(YX-?SGWuKqH?`}wmK{8 zlO-dB!C&3U&h6%ijJ<+zRKv7=oa!EWy#8nuNH~E5>T--v5GuaGS6dhjVGfBspL1i4iSnxE19!2 z9+|l*9oYnSu#t3n(t)d*gXunv_n<4p7!VYbViFKGyy+SU&za=y3+1&jrAA`8O~~GF zym)!oeJdm0{f&(BD|LyzFje}dyxfDmr@X&SJLLE_&wvlg33siLzKsOxj-J769a0bc z`$Cz@!_Ruz%uuZ#BrFh>d@W%I2BRuP*i-?OH+W2g+8u$uw4^>X#|V{kLu zC4`~PCQJ2Sr}I^+kV^v*X`n3)g%wjIL`pgj7A+d=vC#sUxQ*5fqXbr1q^YgfcGzCt z^AIRF0fQ5KErn8QTZhA#=H`|i77#-oBE3*+9bZJ zi#M7UP@l$cD<)?##;$_G#X<6FQik%UTDq2{>nGUk}E#f*$1_8uNlzVR}Z6hvV zSHE+S(5H3mlGDVWP3emBJZ$>0Rznv2OZ85O@9S$y-4x7n@^vPsVES%4D4DRbT&ubG zTFnlD4}Q*^(4KPY9JM&8y&`iLjQ^gmC?DM}FS#2D7RDu7dky-@TOo@APL^heRFUeh zY4&-_YA#$z>g8da+A0^NaRp2AnxEP=r5=&KL-<@O^HN*NiZms2bZP)`Dw*dJv8{Ln zdNJYR)Q6Y*W7G0(Zo!7v7)Y!5Cgq<-wjvDVrUFVfayg8h>p1I~sp&O)L6XpBHQkYf zdp1d!HhXSWFb+IBei^X#WG6|BLUV^Ep`PPYyzk4xOI`4FW;T)4|G^^_S;*L;1V$d2 zImCh_e_#i_R-r0+D`zRLhj2=Pac}3JX!XXX4T6byL?975%3yfcrv~r z8w0OIGyH#AIQv{^k<=nz}Uf~VIx6H2P z{JrU`{+_mP>X}NHy@gKY%A#cLit5Vh4~%-|txVDqBqmx4C7opcIvuI%NyrR@n z@=R26X9JV%rqnxG_ENACq*r4ubU#AYWIHVhZ`(+2n&X>*(<$#sq_1~o)VsY*_0~EaevHcJ zV;?RQz&ccwo+TTJ@>-`PSY7nCODkrEZ>z?PlvD8DbDn7@Zz0fiBNs$nA@Mv2+2E15 z)C3UceyGj&8YfrL+EAQ5R_m_|j#2~B{O!JnD>Rub`vttjxQS*H3C2gLCqVZ%LTZmu zqa>P;pylyRQjpSs)4+Y}J#F74gjttV?+-|%e|h^{5JGSqqT~!raKNspBtMy`)VM}n zcR^ZtOYUjT$Zv%|pi6*~4yzkMf6|My=o(c5AbCKW&62$9EH-4>wuz({qwikRuFep9 z5Hs0e33Gfr#Rg8eMnf@af3%vB4+d}9p}eeCI04xEjk~(E#O(YyH8UOGo|f2>@BCeR zTO2|K(lw1$_DIO-j@_L;^Oit2yA36Td;@8U=XNywK`w{N73>oBrF?%~IeW?lnPh&g z9~E|*ObJDJtdNay|k`hgB{zfI?;loh)cur6$0~5?9ZLGc!(e1a`D_db`#HH{F#1G8)YH# zHRVQ`UN=9~Zp5?nr%w})%nY`+)5Ps`M(H(&6~fI zwiu~%8!MX<(&vLL&W80GWe@A-?OJj=R7vKI62HOVNk(OuP2c5HCXA@OfYs~aSbvqg zpUDpKVHy}zCbYWdVGTAVp^8!IjF7cD-P19`AG8aozeL)nX3piE`7@_4k_4XBmr8NC(HGaI{{xCwhfUC_|qdSNZMuvV1JZ(kZiGDlvvJM0r8(Q9gCY7%6CO>*E3)jWTnMOTrA^j`rNj)tRIYAtyf}N8}O7p zMMJF1V*CEod&z}!5FEMJb%_V4;UMfC7;II4R7JZh?m34QrWxYpieBwdCzjulyrO8d~XIf&_v1n z-i$tRZ43b?M-e2ze{$!7ryaG0tj|LpP7vb}5DEJEsdVY$l|F0Vy@pu;A?;-ImBQeQ zAt$BO=NbFGT1)3NHSXscbUt&x7K&xA^oZV8%bA4R!SV3#6Ayfd8)oLfZ~dxZq9eik zH39BQ_Su)Rrbsd`9_h>U85v3$6f$(0cIMJIN4&VSG6*Lj@{|TZY92~C2o4A&>*f)T zyjmmJWfUyfGN*fVYY7aergfL%VMtc>bI^Z|BUi-MXNIyDp;%@4i%u0{?zottDB=_C zhgZeAj;7k9kwR=GH!IYpX9~NVifd*;7ciw%z)MgzjSNV=iNl#fIXN_}Y8Pu}!g7Tn zDgnefkm$DWCv;j=vDodWLXMFr0;#O$XUL@W76Hc9HdCJr2?{pJcp7=o=QQ zB^4%Yz$~mbo6uhO=aCR)hM`PTwn(;PnxKU?E&x7|?4}3cQ%KBJn=|7VJns*uS_|#+ zXa3_H^A~oaf!Lot-)z@3-+sQ}ZcAR7OH*hnZ2}x0ei(fXgFHelNC@`!=oYuh(!v!4 zh*?Mi+q{MqHv_C>8DuD9=Gmr6Tj`>v%ucB+6|3M;#^e}d{Q2e_1xApYQLaxT51VLI zAdaS9PO&cSB<(Q*ye&Tv;KIp(0#Ksh!Yz)SJ^}*`agl+|=!L$>^_f~Q@3}|P`S7%N zC72V4^`yMy>|x^VWeOBvH|u9W+c0mI6gjCP>>>Xv}&MRhVWcC{O1E zJMO8H>!BesmM5rqVFAk}&TXESBd9Uw;FhosZ0PPX(Pj z^~~YPhiTKR7bgZM{)n}erU9X&C)5!e*yB$3F{-fZ;yZ&B+O$IxIVt5GFPMiZOXWuAC1j6U2 z1Dp~1VaTXC8um7 zg+C_3D$$=n&>-MsZQT!NxS>%-pwYfA7DfO&7>P^M9_zQrScf(#2=1xrj~bRLo+63aWqr8f9atXV>>5oB(5D`*yx{H9waDdBuly+=0pcW5ujmgN``K=z@#1+EG^lpYtB z-BntkA(jF^KQ;GDXEb^=We_@S`Ck{kVg&S%in@+KSMM>BvG~HX)ssWJsnImjI|vUg zlZEe1l^VT+J)ES*M45yP%U%?bt-n@vMW%jXV2;e&(g5cuozls?HY_u?Mat~r5R$HG z#!b>iZL?6VFkD%ORYEvOw3A(X++DxV7XRZJeQl7o+e8Q&WPZ(p^N zw+#e0OBQzbUFk#vs|@CRh;S{{jgD-6Ffwm!Cn*pJwa=?4ZeN6`?^LTJC#GVkCKt;l zqmbcPWZqw5t9pyOmlc`x8U@-aI7p+h1%mPFZ@XP^rS_kpzhU|d zF91Qi!#2r{6Knz~|NM7ah$}v{C#UJU{)8hKNeULcqncg!-@+#)dwqfrs36r&CR2Xl z)Td2qBLvk^5!z3Zamcv1)=QSK5Rs!RLY`^~<5 z-`h5cY!hTQe=euWtO%kmlcE@fCHoYGmp}q#J4*V&GdtZ}EDy$E6xI|z?X?x3i@onJ z`Z?m{tExN5Q_3|s++y9y8Qv6OZt|4$nD4ryRZZd&B=TWa#-WGJBkU{?!ukyMe+_!U zBCg9uuF4RdRm}E?<#ckxN)bAZ-oWk;auq*9p`J-!cqR7aNy`%@KJ;?Xv|!!GsZc`2%D6Tfsz6QpB>*9*C-i4%kuS@c za+CkV?vSrc-=y$>&=?I}>tic?3#0JQBR_%m-7zndCoOX%JvTe1*NtL=0|aV7HrpN0 znx^^2UI^rs!j00Lx3IY6mHBBx-w(fFG6Lhx?XvL%5O_b?-MsSUv0XBOS}M@#E;1au zQD;$4#g>;pdMP#h*fPEq+b5njI=iuPS)FG3%;Uj?PP}ABY#c9wx~q?#*nIcH7CkHV zzS>7mlz(l|2aDYpPu#*EuDdoi;QF2kv#ycn(OU~=vP^iKFy{J!n&d3^=TpKK8sBV< zz?FtZC)jN+s3!y!EN7KtWp@!|e>qQRL+TFCG9;BA#jIrW18z8eS6<7EM)09!6G!{n zc|3}qzcevR_xds-ut%98q+d$gOf&FA5!f$XN$s3|l2@fP+rG!r(ZP6b1{*_m^^)Bx zBCbGRJ{*?KLb~A7Pf|7Bxyz?8U_*ow9C*O3#NL0^OWlX@S9pfu%C?VWK(X^?WbmBr z3K*tP`HQX{Ms*=)*p4tC-hRp74I7khI z0te9@XDm`mreasAn=m0ykp_R&7tAIvUld|N+(l$sp?t7w>NWXaw*YxWTeN!F`G}{D zJD{iQw3b}S$!YKOX8bvBD_%EDmn!6QC&-!Fla2o z1p$raYImY+vYa-{y|BDeP~1Ka3qAM|V{&w6V6*$`X!eTsVI?<>Ka!~hYbdn%5_3f` zg*jh%0h$BHrp?o9U13dLw!^HU1^oQ&2m^XV?FLdE$+|JC;HL}54IlDc4p8Htup5U& z?Z|ft3GQMZxt+gdySD6+qQXMw4V}H}uze;~aO&?^bXHMnK&!iFZ^1ZVmt0EHk z_3plX;hOul*jvm?Qm6XzW~izE)6WVhMeuoudt^kC5|SIU-+w^o*OJ%Uo6bEezV17r zE;oy0-pq!c-6gOI71xmN#TO)54@OP&4cHB!>&e_r9uC+(8Zt_?kW|`%jeSD+G2*WM z3_)#nVa-#0#;`Tg4$g7oKZK1-2tkOTUt?%>rDYJiF-Kxn^tmK~T_`l~_jozX@k@q< zIBp6xt~|IX$osSjMMoa5FYpTZEmCMxOxV0-?s(dkMISW_@Oah*8UJ}7U zSIJzv%|9KiDcOyL?O9i_EP-2P6(M2d~UgYYE4lj%_SU&8zSlMsX zN8sL26{=R2yxW|t&SN5mu!D^a^*<1eM~sX8zDJewp8cTGAA89OD!9Eg`kd*wKk)Li zB9U2_ z|5!`^*bi*~ctrpq7ZbC8dX9fAe;9y>k)x#9f9ys7FpBIjfd9PaKV$Sv{~45W{by1# z5wf?iHTzHRU&YnTPW?aNtAE0d|9$8m0Pf!$mPXG1F?3J?L;#`yF@PdK8DIo32ABX$ z0cL>z&JHjKn44Px{(HHb0n8oToBRE{fqF{*VPd#Dp%-m>I8qANaQU7adB&{uHAo; z3Qr<~x%#(8f@bf4qF>qqH!v&%sk;NwViMAF5W>R#iVY2Y5eRgT^96Fss|W#d~s}IWbyE?eaNi^!ZFbXq6Gjr26xVYkZ}_VLz!kV@_<~~A=kPzSRu4Q z7cXPz1*ZvqM1%$%{=+vInY=tc9tLZ2GH!5TMJ+M|YSZG(1XUH1Cz8-efZhd+0g2_o zpYF`3BT)gLA7jY>IG3&c;~N0u3;ps4ZVqJ{T|VO*8d?TBgz~IKP)tsQq*@EM{XwVu zsRe@Q>&*l;G&BAJZ1pz&kTleN@nHX#Z-ChJR9D9any#%G3?!X&FFSob4F{B0J!TLn zXhYfg;+sc1JAh;PNO1cy7YHPUj1F|Gx7Yi`h0UYA%EQCNrKR~(ocIR#^TIB(`X^#- zZS|LJb~e&CcWzrK>F8_s4Z-A3k1nka4~I_e50MJ24(dX$X?oi#OF%=jqa*NG#1GH$ zR>;9&Fx)7Ya?WO&jiq$W_r-} z53wf~u$~Z*g#>0o{E7hnPc)LI7BB_I@H7x(@6v{U$Is-Oa%W zjN#kGP4CX*Hs$2s>E-nUh1VU8NjiE;;^#M(uU_(>6>1vm6NFpiLsLk`2B!uPO|3OA z;LR*LpxmFMHwVb?!f%I4=Gpz7Qj@nqDia%P$lb5Bh?naxiHM6{%HZQ28xh#o9hfNh zn+G_M*-z{MJq&q_gBQf*pBb53kMW=0wV&vtAGgn+n@BRfs_LKTg-_bupAp2S`nu;= zkG~(hot(WlVL@9TVXNOeigL5P7}|@|>xVz@rdfeExFp6l=3hJP+MH6_ZNaiB^jWb} zKWw5u?V%pdHn2Jg4cW;<28am15>rEueqOgdrdQ9ul$^YKD|_|wUQ*w8l2BTP-6;aD z2>zYs0G*yfJqj9n5i+vN%m2c>_(=NmYx5_^4u~bWI{U!~W>+r@v2Sr2d9N1tXdi+x z`pfJcb03&7`bVe>$UO3g#NHjKagy*cr}Wm~?;wbw`giau&}2oxtWVB5;a^}w^&h~# zp9S!@(9KfpcizkS@Q+x)Q`p)eVFG#|+&jQGZThp;<_-1MA8JA1w!5mle2DNf?FG@- zAj9MI9dV%d)14viXV(Xj=>yW2lJy60xa%uH@O*sZaGD$8u^|BSZ$;Al4(YpM{e}3- zuzZYY>WBFe9`(St^z4W8y%(V2@KXBj)3Ei^wxi(iGxD{K_wgdv_#yG}eLf=ax4tKL z=}e)!7isi~(3o>)Fnc?-&_1Nlx?=QPtcwTkFS6I ztKH}L39p%N38oeg@A!Z|54W6v#cmd_AiN*7^8oe1)uFk&FN=elkqbYE@8F;BSdhR? zp<$?K7x!VpVEW2nof}#)s7)-7VQ_z?Ys->ZW^a1#mUiBPK8iVYU&PNVPue8b#n_ex zav>MeF46maw?$Rhk76#N;-j&TH6ndC>r!wdBb3g7{gFgTIYMM!;=+#GnwRL{R`Flx zrl_9bbY?BVu!vF448z?zwJAPw24nY@r<-x(_TXuF`z~XwCXc05TfYXd$MFhdv~-!V zEW}ATxgT9T7Bez83{JIB9mpE)9-;V0<}Tm#*Dq|D5F2wUi_dN4vpvx~*V{xBI8F;y zRP_r!#u_*u^u@sI8}bvuOGMvY;DhYS1R>*S=HtY^lM*9ikvBnuf$C8ftIKCKO;Y8g z=kh^qnycJ(A1`sP2hK3ngL%OyQ=hvrZD&RsGH&98gum3MDaUOMlzn=%Q6YC`q57L{ z0@f6APPF?bu5J#VvP){d-j6Bqdi%^%4yqQ8z+ENyt-^PEdT%q*6BQ3n? zfq{KXBFq#IJA4|u>v@*S{^ii;QRBrA^E6Z@w!UBTkuEX4XBE}np_c`2{yYJT(AE97 z+B%@@G#A#l;9NL8R12p=Wnb}qgF_C8;?5bEWzxzvtRrQB*Dp8T1yVO>o;OGG>M#s$ zFm&Z8!y#pjcSdi4>{3}YP-rAliPxq6Qij2#fi1rVj0@f8@Oz_7Jo*hnq?so zPFsesl-C=A$sdRJAdk3WA}FyY5W{uB7r!7J_J;G)i?}p-cSz-cJfK0>!#lA&0@t04 zHZcb+g&Z2ebotYnVnOl*>*t7zBbCR)V}aCy9X-q^Fc(XY+L(6zwrwwU(zyrbbzOEV zG>OpPl8`rP7sEs@Z-m{+k!E<(zVA=lUn&JFda`mHzpE{IkfM_#RSEnfcJuZrR6!pO zp4GB2bLV0u47TG7ew^UMz}Z6O?1a!7Gi=)j`?x9Ja;&4$Q9t@C20HOP<9k!n!C*RRc?RJM=ipRGLsS zotb5q?IsZR2U~@er@2dk^tffHgA)s|oZ#B{!=fl)d-l`r10&-2t6r7PiP6K@6O4?8 zp6g{@OZt@535-bo+aHi>x9?X+DuY8g+8Df}1sFsw6bjsfh3;DSofjbt9t^H7GPNvx zZJ+C&Q1umQ$}S?Um{&<&(%WPsC{v*@ui|nIpxWSHh2TJ)?_}U_i-BXp|}gx*6qyW(q=@9C6O+M%re|qUIlO8NC+un4~nAElOs(Fb6`yo zq2Rkq?}*NrcFHilNcRv~>eC1op-UfWUrY+H3sAn@5G6OHm|500-tRQMLD<=xA{0A54>C1< zjo!#fc=7i{Fp$l`K!1~$6Y%>cTf3y(QDj!Q&zg&D^2US1%lQ`~I}$Ti?KtTLE^l%l z`d~&210ahA`Kk(b@LsQ$)jvAYxMM@8;SEsY1)1$i;kl2XouMHLj)vI?);&}8CwfUV z%Y5K-wHA{2k+ukcm;`+v1vT@ja8NYy*WbTL@&e%=?e&6Uy@a7hACo$o=K>T)h`aNV z;;2pJV}?R+Rj%>poN(2~rkR6B(YkO+vH2w6hqQZkT^HiffbX3X>hQ8DL@Px-Ls?S# zkqT{f_JInJ=RCL5x@hf^S09WY0Ao%|iS^w<*HM&1?KaOk_3{be*mBDE-_g=<$3Yre zy_W^G0r+N^X1g9i^ke?KX~iqeLRgfl_R(vNjxm76VImQZkZ_Ys=7&blIxWm5I84lSmR?d-s3*-`LS!Jh6W(RrXcU1 zbd83Kt4iFv(p2%?IVEz)s%zc?tSAqrQ*3@hp}f3XSDf4NJH`+4!6F_zx?(=|vahTq zWj3eC2&5%Pa~j(+$s`g(!ZTVCbJt-E4PPqdWpec0&c~2Oth9cL-!XC$cBacUn2+NE7DY{LrAnpN|^8yP51(#Y2k^ zoj0uC-b0#uTI9;jU|zKq;CNNNHU$s;QKMEIDy1UcrziiM0>cuZ;``%ww}m=t6ywFx zIO{h>gP0f+|Jkpm2%>j?%^M`Ya{U-0^NltXN2;j1*LdS7)V!J3arUufu0d$GMDs#1 zt4`d>5vKyzTF)O|@Zfg#yoYrzk+v?pWtZr!DwDw^ zTgsIqP&!v%UJaUByjYs2>`hqqECsxerL2)`7EwhE)&mY^}5V^C_+xq!u^4S`5K_|-2`c5n~97?S|z2ZcJUNhnRCalKmXd%x6w_guE{ z+u7KTXAJTQoY=Uu@uaK~djU89bLCTm>}F#NEoJe5=5MyCinuD&9~;8Xpf1C`T#)s} zm37>jwQ;uF{R#AJe}xfVy@K~bw>nIM-{C3qx+f$D?oxoyT2x0MMKZ{)$OgM4nG`mN zBTdXjgW4pfY(bHod%`+UP@(ArrM6~d z3AP*)3aenz(&`hh@#rXPxnwvFEct$MEf>f8$@l5yd=0smA6vyjE&R4wL#*bay^?q< zWZwM@lPhJ45iaHMCd96dt1~L{U8IT#+?Mpfb(eg2QfFASus^c|pzrX4^pPQ|1g%{9 zSg%DeWukcdnVv3NJBbcafboUQr@)2vX4r2zbha9uKMx-?r$hmve= zWEW*U+oYds_Q;=NGZ`6e`L7N+A^)JsC&r^EZ-|#q7l+0!eU162o+$L*xWn+YZf)4J5_><){y`A*Wcnj~ z6-*p3{xz{?lS1;wFQDZYsnv|k0Slz)^{~0Q6oc80!4IuHusU&UkVWVTc=P}*6(9F*{(s=|4`WNd(-x31_(_T*!d9G0L z$z=x#+exkcKFsQ+SMQPuAFhbgpmO<4m09t7FPe(6@mg;r?Q@G~3It#B3eflqO0tq{ z_1wqol!Y*~es5Ltz&QAjM781PV&uo8t)lZW1DC7y#Q@S^*dY5-yN`mQb_pUwgmO-N zC{54M$j7<#>V%e2~|`D9av=+cqR4Aq=|~z z^FqP?ROc$_9iyH*ykHBxQ}t*oiNyEBK_eNvW&Js6Uzf);KZovxq7+O&hZ3w_{$6B6 z*c*d83Q4it#UdE{(?QVBMi<~rPvRRBw2U1m-mxLnSeR!a7N);C^l^JyY$kyut;~Zi zH})|tnwkNnTn`VYDlHbLi!EF3YD|ucUV)B zmw+gwz1ABX6#4#Mu&8ys({@Jq`$6OcFs!dR8i9b>@MTTjqdTu>;({(Rwf+dfC))+= zZ=i$LBXaImxlmA1%?!>6LPMvZBQ(T;_-7C1D-&AU2iT8?9xw6*(3-Pncvm`}Hwbe` zl71`Akv;0%1jgrb93W5dRPm5^V@PAw+4tTYKadzIvOqy-5h5R3@o++E;24J=7)Obz z=P>6v?$LW0_z!H|H({2kDRYgXuDBub}o{o zn}%#Eesi)cIpJtz(b$w?WLj2fv4XMZ(f-^)?ha4jxpu*sS=n@48`TMW>yn_*X}q`qllX>9&OU~VrRyvH1K>ZE?7T>Ig1 zMwO}#jj{9zGx>Obo=ilCTV)2W?T^G+&$z)E?ep1AIr%m z{|-UaTzW}PNYG25@Q&{H|J~dy%>=Om8xyLh$H!fteBNlr}qk_{cp zuhnUDDQ}dZ)|Do*f$HB6TVNpTSKxjzoP0|qwcr>Je-z>0Hup{YLnM9+(j z6D2jszh0xioa%>Hj{m|4vBfj()EZ6Hi*=ljQhQPRo@sSDmNtbzOW!ohAX28~HW5r@ zxueYdh!rX&N)k^X0i21Hd9@OK$y9(XKlXh3$k^`@#e zE+$|8^n#knSGvezKfKFrcR}SW=fy3N!Mr_&jOLi2s)RIIvtBpKRBW@p;bwq5`Dq!s z=*0z_WiILPkMz|KV15q;FCX})CQa0l-trvhZW!g6I1h;mMV;a|iQuA3r1oeElle<* z;P-!w9YNz#(Xv7FHX5Rr>(IY5%ubJeS3W~WLoHm_ZV-Gw5F1fySkzqBjNfNu#fMb4=6t)f*Sykw-cwB83JNHbN+m{_1 zPspZ_-z#r^5M2SZfcoHEQIGjC(i8IZ-(0(vC#Lu4;hpN5)MT$0vV~vKnldijKjxha zXO4KbtexqSNb~u?BxEJ|{EIX3z|<2-Dk{n|94|1{(e%M?ETikygv*2VZe5wSuz_6v zMe!>%$o)-yBe(R&aQ{WG7|8qIB;$Kc173{PH%F<$vnXD`_sVngIhU}5+?n9qxd_GX=^t^Ip5tlO6&9Le6wvbvq`tf^1 z6re77rq45VG8`hNpbiz9S#BM{Ct_9p_bu|CLdJ1YM9#K?x1N9T3$R z^qWEP+kq+_i4F@5y}gi+@sKb?_ujecPPaPBv?>cDJBrC~(T5NEp^!umFvu-8Uovs_ zuJC^%&zSI-!ZzEg)c8Qp=1|IO^szdr3E*LLhnx545O5ODQL>Snq_Y)UtK=$ds+wQz zbWYK-IHf!mWW30Kyq$m)LpI^rP8Zk{-c85BdkAaof|NX@v({9tT3n3l%QmigHBQav zC~}lD3A8^7qDWCq81<`&LJRMpmRB{vym*)^qa zzEBcUD{$G23;_ap=-_FIXaM;``k>8VVWK6lFiZPah5cZFMb0E!4>oZMhA}O9+)-Zy zCJ|Z@(H-Yw?t?HmGr6V0Dq&A*OcY#ZNYjBf)r~c+| z*0T4*$Q{E*$F!j?RJw9zg*&)T8ev@GklU6IA_VMF%n(&21ipThEYD;b?I=Zu+%sCg zk4d+su#fM?^N60!%LW2Vg?zd9BEywh zebu}Kd4LZQ8lxHA_pZIkT+AG;7!qZROvHZ}JC|tCbA=dkTT!m*ypXuh!AdKZ<0K*) zHhM_A23+@ppB>=>R7_5nvDwd-E6*6#9`J-K+;0KkT!UYT&N7e@e-5{3>*@Q2Bh+$A z$Btxi_D@d}fLU=d^6xA{P@2C~;VPRy6hd8D5qficDa zL+&6R(=!&$&v<1AJ#AmRVzA1;BSfxU8+Z#^0~A`7j;46MdrXzBdf(WNPC|+On`gNP>+hAojbXSw0+cy#UGxcy$@^~oa+=uULI5y4MOb>aJGs5i!_2A zG5D8^YmOIT7RQ+Gx9XAk9qt6tEJ#-xhD}uwSYu|RFywoR8a2Jtu! zSH>=0luc@=Kca)I)h9rUAdt6lgXB>^BfOS$m z@S>Tew$0qJqNRIbecO=F5{bTlwU08uWYcv#!_Ta@B_AnB_^zq++0r(}47=RJBumT+ ztdlrkW3W`A3VsA&5j~MKH`U2H0-`6*E|wNHCJK69SGm|FMULt4a-qiZ_BM8&oIp+hv9WWwkt6HDa<`mKUEYmLW^!nIBKKVux!Mw(ujW?~29wp%OV z4ABH&yC?K&eqD%${-ET z;uqDX{mM&$uF;QpZr1PFf+Uu_^v8pwZlbpYch3Ym;-ybc5Z~T#uJ%~JJ+Hi@)v=9W zjiSVvltVz+yoXm-P%V5y!AGnZw7dc@_+IL-S+}5tH`6L5WLQ2wE+0_4ue{W+8$siL zQSDGRfd(c=vPsdBD*h_BTUfl9x#?Ji?x8ED*RYWORHXY{odY|Gujf-Z>1BTIDJ#uj zvu@$`mxF?1Af03HVJ!`ymU5{sSFQbQ)D;a+&LoJ&XlRjY(_ zPyP_%UbBa{J&V_$pw5I7DgVGy2XV721)(Q;4F8;#y2pi=EPkkSqQP(!dW@mZ>B~9= zc&-eObSPYQNe4HHWm065S5V-QL`<965aYlU(F4#zr05-(Ri$UoOo#D3Ak!qw&ghfl z;Tw&2{;@F{dfp#ASL8PJ9EncpT%qpvIY@lbU7k@-bFzZ9L#QyMZ{4K% z?Uzi!qqS@~ zW;&BBSalJoLfB?7nfyd+4ZaYEqj2;6IRs|rcF>4frvddw#`)3-H7|L1>(J5RrkUAcaYzWR$q~ zc_WTE)JqcqQYwr)I3MkUwtb7Zsmfqn!P=O=T!WQ*^9b-fa(dL&{_Q3U(0yJg3KPypiJx&+WeTydMDf{@KM4fy7_PpRABtKcLxq-_q@ zP@`k2gzL1#v^jR_{}e|;?F9N9=Qlv1;uynf*!I=*BN+`w+|3z}_0&70EOp&}4I>OP zNbb)xM=#c048t$)0-g;vQD@`Xfnll9)jmDl?b{tq%9Li`yDmE1AE|*TuM<80O|Gc) z+kO06Hk9#6{j70C)*WnP>gL2y+Wmtbby?58QrDOUN{c3oG|he#meGTB@FLx+8eZx9 zQHV;oEwrZj9z3)#0FU~8m(1VvqFWZ*L;8Z;ZE+E2+L{Y#gJ>i*E;r-*LSfVl9y*cB z_i{yMv33bZ@ULw?&NFIKu0WVWwely1;y&wzb>Dn{XK2eu5sF_5X*9g_J3*l?VJK2) z6BP=ru|1JHUoHmEF^^rt7*%zOQWTfIk^BzwMVv7PNxP2XN>Pc_bu{Ziim}N8&lw1` zAk2@PVSk3U4#6)v)cwY+ohXinkL{F6-b(NffvMl8NP@7ueMNh=3~Yct zD0mZ%(iLqW@922X3T1d$w7|OedT{NmM2S4gnm&$2L>X?nc)F3T- zk1^22df&q==+tVAr4k*^0)0qk=PWW{HM~|qhL^pe>!e58E0HAP#5+90FbwOOktKR3 zKDE!P#Os_G){_Flo}sEwiVbwhTKcRMTr{ck_3I2=;W3#j?c$k1pA5- z;y{-itJoxGXs3!ZI2ghUu5Ff~VD$I`4b*im0$&s7ZU!&Cdaiad_&-Ar$Jw9Na3W{i zFoR?5p&p3=rl@lT2jX_#r;p{Yg)FPve$R_6ZJ^Q_@wp|mqhPs%-}C%;U{8igt>?#A z`U06G>Yi)9&PI)+2fT(43IXTy&bHYV<8*fBPy)o>A?!%H;SBG0SAXlw0UM}z!g3(V z)5)iZCdso!XvXT{OtNydR??y|8OWj}6d42uaPZ-|beSyI8$)Svx^P=2H3Q*%wL^MN zMm}5r#&bh#Fj5ZIUnDClpl+gjNNf-%s-$IOp+XPHn+6K!N#8=5DtHx!u-(>maXbF; z=?>5;y6(Dn_X%zyMVi2u@9Hx|&f>PPKI0<#IRR*g$ChNZ^NnRBYs#IC7;+5>$ zJ5|}W&5hzkCKcpQ+@9qKIlY4^?n*%W!cvVZj1FSmjnthldiy1%HLy*Gd}T@qPsFgm*<_IRG`@HjsX zMziVpM`>2I&w&ed{(xzKROsS1}N#A`EElhz^3TNHt36?Kc+Db5TxWW0F zUUEGOt!aeLqP%3?9@bcMhmP^283W|h%=dA#gXHdt3$Abth`t}%(#ODg9E23b3fr0Q z=$SfA?Lnw5ecIIlgS-0uzpS!)>5iYwxTiNz8D6Ua-b6;xGWQ7)^&ptGhEMgXdz~g= zF-xrXN;nU_W8o9pemmZU>*+z%qXXEM&f*Cg)i+MTi45Q!sck&P$z19b0jDM>^vzkV z5abzBzA^f4(3WwZDEx=xECQcZ%&xoM1p^1$!9iBZ~pnVLbe}CMfkY} zDdJ1fG_H%`DMANS@-_b|o%7>zEI6b` zRQt5TsE{Y3#2g@37aMoo5MRD^%Eu^!@MQoc?DSnr;kRPO^6Ue>&_PlC-Ux-R&lJ5X z?*`%_{25YxU4K9_I#=4~F)xv7F*(wNu1(%?o2Q>HFI_7@71Jrou_prjs0GhsX@=Mv zhOnr?O_oWUxK+>@(|y2o;_KLS@$PAkQLD;t->M2ayR}!T!PWyBnuFdWdo^4rEs4+0 zu|(H0FN+HLFOh_N8ExO(wwG$V%tGV9^XB>%ilvr{%>|6Ca6?=7^A{j-iiS+|24d$5 z)YRQ*x%vp35)jRNGt0D!Eg!*WDkK_Uf?E7Oj;%3}wAh&%w2-L!t0q z$iFm-L!IqHj7iWv}N{p+adUCS{n?8RRMTCNHeDl`RfuV#*(fX;og%XR~Z zg$0IQaUpi9H_mB^%IIJFhcf1b5nZ<2bNqhu6T$4tXHueV*pG=yKO{RZH4zx)#6u`ylzypB~J|j?6v#ZNbjl&6$)FkbtcUi0w z1$l>d)Hq@jn`iIUa(b#|0$N9mdz_ANswTg8mzEAI)feRy@>?r4>0?@2%HyDYVHLXA zM^M@>=?pdZn+wem=*0FuZJJI^Xz%lU_TRP1G9yJ8F+0js9Asl~co}~9B{zf~Kfv^L zlM73C*_l5_} zi9>xn(5Mir8Ea^~xneY0LN)JD?#G9|50{P0kX)Fo2I6aM*VXwtH&i zP0Zjm?}DQ9bk{1YfkRCx*h5)iI68KEwel~J>2Wpz_HVGR_ZSw%T@5(6RL%s zyP6hy$W$KXscdK0b$R0$0)PO%6!t~;vCx`fi9l@qFuHxkz7Cn>RoD{8H1p&NY z#)Pt3t34^X%HqS1cEp<_7RYm)7989?!!u+fbgtb;?PO;Y+R=u^nrU=>{r=HBq`xl=E?L2JVG#9n<=e` zWo1w#c;EKnF!6jK3>M5Qt6(2VY;T5iCbeplh_6ws;UiY_*fln4h+`aC#j-u3+@rmD zip$yJ!lY@tDj0USyPMWNsv9_+(xqD2EC(b;KWGYlHYjH@19I?aIg_IPqZDXHp>DlV zE0U{9!uf#2NL1c)Nj@^;oG9-qqZ2GsaK_YGwu2GcH%z|-`w{|S=iU2bin%%f3_xa| z-K3v=VPh(F?wpRkG7dUw z(%UqQ#2j7_DvVX42n4WEl}rgxbSU1|*p^2v!`q9*ZLs|m061@fo!>a?UvrR7_es&l zal2dIEjK0zU@t4sT6t7Y>EW?y$wv`FC6BTE@_l619f!1D{Q{W(56*?M>yx( z7`vS3z`2Q?;nEOGrWbLqj^n`HKs%u_NzUN(XoLNnDI}OOMk|owo?!)w?cDXPZwE0v zxm-6qq|#A>fK6?4Z*fUQ4VUYa>rR#)6VbKkYxt%d4b1?zh~Hv6%LHqJiH{COqf>7qj#k>XA|&Nig=}J~|UuXXmLGJ}Vy+b3{+x zq(CvVgbg=BRGO#T(43RAcOp-R*dI2^SuL%GYgAW5C)s|iP&7?CW%F~5T zHudcYg-oE2EeGSglhPOe96+j`lpG7(>=2z|j+yh)jJO*o=ArF$=`K-ZUBR>Q-sm6@ z^;~hYZ4_95L=q4{yYPwsKXRLvOA-70s z6~JzmI)~?=umjFe6Ynt~rSx*}Y@cU6dD%hGO z$b@)dAlN6@<%k`BWDM{4S{$x~EOX-+oSi3VmPuekU880n{EofYZn7m}lgsPX7|UUY z8uf7f!BM#Q5r(Lt?&++mYWCG~B-J?C5cSDsYopki2GX6j??7r1I^R{@kau0{OFi15 zY>k?^l)}gMHE&rpEtfTzV?u8`S1BxJ18cj7y%(NPJ@eT;w(KFRH-)6$afXN%F~ss( zu?@OztM)7@Y6b#UJet|Fx!9`zP8Kgln{G=ipkanidbnlFmXn*$oSgsN#B-5FO`|BL z*B`1sHml?HWcVD8vHC>x(j3Ver6Gk82PM+KbVtN|bu-PjlzEq&`7Kq;S4vpPi=7t+ z#RkcvoO+s3C+gU{{&7n`jY>Pt_I#}$zYHp_G+C0Oh)j*x4+^W28wUq*Q#HEjxrB>VA8d0s_6tGV1)IEJ%jgGEkr?0RL(3^~HGZ%$JSS(_V z5iQI5gypb|tT>{y{i7vdIF3rEisaPa3XZl0K%c>%d`O@U3Rc4=RFHCel7)kWFe-Nz zOx=a0BtR*}sGV-Hf}2DJKXF1^dCk@+1>T-wpAE*L4G5m@{@1oV^+;XQAnfw)D!R!1$^SH;>5 zErB6I8yC+*!Rk~w32PbEJF+$7$#EF_@U3Z-S@!f#PRJF7{bZk6=n9Zc(4bUy761Gs z{84P0G+j-x@w+m*m=AsDb4E|lbQu_u{Tx>BoZOZNUX6tswC2Tq-q&>U4b)A9AI!=C zCj|tQ=?VB2OXZ6|u}?k+TKvF!#*2%>#ZqlY;4B4;i@3oRep_S^KsxxA<%Q4Ffjv ziYlZiC>rl$Gw@wrh;Mk|K`Z@Mvj=XhRWR{`W4-1mo*gD}UM%So@!*PKy1~OTUVz!O z4+q@_szlORpF-iT+K5xQaCq^b&3`NRO_bVEql0;7rt@h;hc_V4+=5JVWPi3W=_64m zHOo_7hD`;FjTtw24+-`Pe0d|G9V151;KTd7 z^u7HZz^Q)^xe=r@;UL0@pg$3?g@ZDJV7l!Q!wd!JAxZJ|9C zds)-t^aI9)3ee6FjM}`=q1@82=*D+?-F>|D;?t6y%Qoe`qo?W@41f!pNbn|v6X8pw zK?9VQStZ;2tZ2W$!{8cVk{<;TU14D3Rc4M z=)=KgyA?aw(5obrite66ipT)@mS79Ky{z3Mq_l=(bmlE;-vQxZ_fMLeBqsp%z*;B7% z8$|XGOVdIE64S)=9ec3kTAD^93dCXU8c;X6;u-h#T#U%mYI`YD#qbaDqn`~7i_9`w zG!Sja*USf@iP5sjlAkY6Aae!OK)P|)2c!ID8p8C-Ul*T>%JO)fpL@Hd9}3_qoVHmf z&igm((Bob8HwDGKfFvjAs4k$X9Gs{e&{w?a1$7FajE|;vZH>`DFB(;mBZrrm?stW) zQy9p;F%~dZ4p=`l9Du({S-0 zSY+N)Bj`G|64~cK_~NHEx8h%^8cMDH>WfAus8pw z#{WAkx3&1^%Kx8rxyOI%%l|`@|Ifah?SH7Tw27^mv-!UQF|+-%^8f9N@t>;a_)mE` z8#^1@f7Rvq|H^G)?QG(R{~vtc*+kgH$j;d0pJIn{a&|N^uz_;lh;ajF*4Ei%oevbQ zn-@(+FcH1&5sAUnfnmZJfhlq;Y(oH<=b9HG^NhjwgeVLZhAu?zmB@YJz5T6w_PMNP zG1GI~{Op|6HCsz>d3Ha-7pE#`MB1Mi9EC;#CpVwKiU8!t2h>Ff&-0Iw!8?Hp`=KD! z_W}~>_!|##|4T2=FVJ6WoVYEu>=46wAd2fzymkXO&17tRg=vIib8^us7zI0P7} z?}h=AKMpM~M3_$tVhtruMu#%BGK1PPttSN##zN*VCoLWP*~Y~`gBTg85rhaJQ(uL% zgxFKWf&n)tq&b*htNRPpPhfF+aX}0R;_2>w7l@)nrk>~t-n1LU8o-AueG<=+r#Pkx90L?IAJjgb1!X_*#a@U%pB%u`$v?LeY_9pU(++@9_AOYb$T352zoZFQVN6gbN0)tBX8_8}T5#^v+Et^5T#eAoYVt0iT1``RD0? z@X+hIQ1&7ngFfEB$_{qJ{o~*P0yMgSs`FdvLHhaT=MBrJ@i26}QKpdfp#)!X@c^DK z-@Qy?ZRsG80AD{wzubHRB*8-CSeV;?^uO9K*w>we;8X!GnL06;cj>K_Ywx0dsoz-P`{*(Xjtu|B?OM=Qbx;==BF`@2%{4 znqLs#>Ir`L*8{+}>+AR9M=klc=K1%Nf5O)O&5mW%?)$e0jB8*|*AFvaYkeA(2Q5?l z$sYe_a|z*NlzftCKmK>6qBC%QkRYr+yj(d;{}#-GCgISJ z%-Cj=B?l*bE?tpglC>U;5{HNPiM)+1y0AMPM-^i(O@Zu@Zto?jhPu)Ld+PVl)1p~d z2OM2Di9*@)!t2F3^!7bn4M>xb@;4q->#^l0#@)HclL?!*ALl18q~l-9kt=zlNe5SC zl7$%}zQ;3_`|4||96Y$J_rfLxl4@CZ70!NSD+D7nW$xirs}v3yC%n~^u>BXIMjyF@ zio+y{#(xiRX-m3xh%Z+|P$(bi)c3qRIWM}@%f~L~g~o- zB}J4nG&CLKL4Afr@@-KVSF~z_oAe}VpI?Jxp6RwS0jQE8t3v~a70xQ_huhx%=f+Ko zF-J?0NHX6Co@p}sd5hgIiDMj{ZZcvWL=|$OXG`5M=R^X0J*p7dQo1-#kha|k zQncLWR>J)Pd@7h@^(ssR`k9OoYw*QM3d#D;Z2j+_DBSKKsjs-cN}k)7Z2FNP2_xKIXqQARn- zk`i%ZAgX~N2LlNnE_ozDMp%M0(=N*spz7yGpe?0C9?EXncMHL~r;HVLPnqALLJVv@ z$!T=nD$}6{pko83eLQ+H2kyFt=osF#Znv-c5G|n}h;gu6bNGGbzlv%j;;vr3Y%1V! zbqp_MoODS?vhE(!y=`uR1_Odd23@b;gq^{?3r_C=^R19N+P

    TW z_IDONo{|>HAW1G>TyRtpbmwk{?E;Qe^keeoFsDM3S=2db6)SXNcKE5%&&Ar#_N zpb@o8hS`1wgDDbLa&s+bs8dLKx3^4*zmN|i^7+?GCYx*0-1L2GVTM3%-hPWrrhz0e zbXNHB3HfPmGwCS)c;aGu`*;sb-s8nk=U{GPS59ihrvy=D!4Vx`q}533<6z$ck`Pyq z#Wp|O#O4)elSw*QD!!Er{iJ0~8m2>w=uzx@uM&gU0r$C!=YYmjU1aUBHf`trIflpm zFq{>9Y%Ab4N$mgk2oo{wij86SPzFIw|MoSMh>+=?vK%06Ri5?N6y32 zPWFhl#BhsY+gB&zX;_uy28Xzn@#4NH&UCg_=suUja2QPKb-V!m%U6KxcfYDXI(>KVeZLk1dpU8 zJ(yC4l)g7U9lQo+6a{OuE#k*r-jT#E>0I?o6F>I7yPufUqKPKv}ds~3-?2-x{@=kJ>}nO93O zI3+2XM938mPr#0cVU!2=Wwm_oC}TP=y|_@ywlY%`>@9xa$lSI=tkviJnbecM0g6D; z#gnR7xopbk>jjl(OpGP8cT&dDJ^}*|cYn&W;+mV3&0>yf)w#>nwHu1yokd8ym zQAEeQj_R{r_lrFHT8M}S83BAw2~OKeB5i}Q1uX)2R?d&}r0rzF4H>KEf;v|b}({Pj53@@LXZ!rbM&_B91^_?a$7^_jgH z_D&VwOkJ-?ckMq0-)0KKW|}6YyN3ro2heX%gbj1Kpnk|b734y1tAZb=i8QY5bMHOC zbUYV^l|Rp`f6{L!GWTHZr zoJeOTZ>=xYHk|0I*rr{Y?@X3*1y^kuJ3YGuir-S?3uMz24JJ&d@LXC^AIqx2430Mw zxhP8Ewks}5ddx7a%H&Pkvbe{q+$Hm?zRF9aZnQP@uchGsl#Cc}$!-uw4xA^8 zJTo>TdPw1Sw;2$~;fGv{;q(+?rngoV%qxM9sMp!{!D53t zHYX@;Z65KdeOE|7NY41K;ryCh*ITJZc-|E5k=47tbg`vkV>v}>cYd6|SMWCm>(jj> z(Y-IP3MMF`@7?wsDi;HW<_vO~T(l=k={JY>LsPax4pbFHZ{$NzksGQkw&_C{BRM

    ?-Y#xg4rj7}S3taUTj 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

    {LABC35aZ+t^w!fb%kfniC0^^)fHUEz8(f& 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 Cetk@ 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

  • i2b?T9#LvJv9?RO*%Rvvxixb05uLuTWg^B3R>On#sPew zp87Tb?Ngbeof;1?YZa&MAoUQLkl-#kIH%yhcGe@z-Ze#~U{^ngoQo7xTJCxT#b8=l zwnd;=ZU!x5J}!?ouJXpjt?~|rWg!uL2OoZo+e?hC;G&l3+p6zKd_{)C|Ew=npRQ#F2LMiu<*RLtFz48ElKE_n5g^$|jE)zPM0aqr7~K-keb~&P zSl;X~0^!H6ULisNAqwl{12^)_RTR1O^cYyjmiP*vaHuCcmL3L|TPs~L<40{QvH06K zoAZABEEgxjBr`Gb&3QB`!L3o|_+z!8Wy?0UV!WP?LK)NcALR2L^1M7PBKgMi+#50| z-oj7^8y6rq%GL~}pS#ieHt#cI%Iy{{0QVntP3?k*QOl*03AQ3~@$xN0V&I^gdhOyM z^`Q$+d26F!MM%JuW47TFDP>^OXo7X_vYS<#?)uJeg@)* zsSUp9Z~+>4ZGUYM_kNSdpHk;_?K+|E!)3HTve;F3pmp#@h_`ib1}|(2qTBSy*}{8q z7D_xQFUkQcFgIQ!ig~@jr9;}?h@={pCytY>h~vxBRlS7^G6OQ<&NsOdI0C?l`HC`K zy9xl%5E5gu8R$ca7Hs}nf7v$Va@a457bWIfSbxlTFE?|O?wW7_EPXM}|0ul?a*HEy zQVm((=j+^yuD)j-ZD4nJ_ngWA-x>R8ll((u`tn4!09p~p)D>oVGpj8J_hb@PoG&ul z^%9&W9ObV(^?UWMMXV`UoB1&CCJ7sr&|BO97k!_>yg1H79eK}P8lMQ~dloRK7N*G? zV@#nQ4TBhBZOdzp2q8KP;beKvG`**}!1G1-fG5?K+kh^=)A$l)Yb-QX9J;tt0|dEV zOX2b?m3#4`vs`K8cr{JxM!B-#oZ+`$c9;8efrnE@1*koOA@)5@9rx@kU?wzixJoyN z2IR>bG{^X@r`mh-pU*0!@=NZX)A?LDz91+{x*D4`FOkO%pO(FKm-@B42%!<0wZJrH z^2hLfc;vg=5%*$tl{Z7C!VZ0h3@~gwEQyQ&>%_?(g`V-LP!=$^;Dh3eLN&~W8lgM8 z&beHA*UdM>)8Z^%;5r$+1q(U|GrETsMc&ZL4fOjxt{BFX9=DDgL#)L~e78h+ze6D?7+Msx zTf05K;d$&Mibz=EXPCvR1O)E#BEd+>Z(>r}QQ+RggS@jY$<5y2v2RubF2>G=qi@Z- zsek~UdmHNNr5gag9Q;=S@c=`Sy{Da3YBx&T1*3A`6Db446qyyo-l)5*3T|Y7q23Y4 zLUS{K1j(Cf@#8^tNcRL5Tm3}L?k8};9xA2i$>HnNnOIi8V;15S5hBpcalG2NU5ieJ z9PGdoVRs3NB&U!PA`=14{k&BtYHY%WR;_zk`GPxH&imIz)(X=qUgfy-gnyMbsZK;x z@z^(F-68|Q$m7|ZDo!~;)g;@O^Y^pDw1)U@n3R=_hEUYSu+e|#3yZZTL=PSdGy6xM zRgEy*D_M4@v6_Jh4jO5Y;01r_*ln#pQ{kA}G9-w0E!(j1%c*<2!;*=aJ4hTKuD_Lu8E0jKd4)n}t_;!MZ= z1WG(~H3%TxZ2K*0*a06i!YxG`icvWL`|X}f3xqKud3PHJy7P_oZM#(^X)cvcbAY1s zXz~xUTcYNAauA3m4Er`;bpz3Iwyk)7i1Nao$3#O$sGRp1kg7IDDoFMK@ZRB(;TIzwnOI+*=52kajYeZH%^9I?*QcGct!;q1p}{^a-OMunr~e z^milcB)jI^3L4=21NKu)6s%sU3RZ;B?JB>oFr7KZB3q1CYEg==u{xn?hZbhn1#I9 zr+FEREuAVfM5u#WQwOKfL?E$q!4}S+1I2;a+ghv!WYEoPCjJ#y^w{t0`Yd+NnsDqw z;*e#ikZZQ7eF5NtQ#Pt?Y6t#fh!6O!ZvkK0fT!Ey>OgFYUaft92SA0}MJB z9kF@Y_9%fb5Bp9sRdSNUQSK3dHFFL#VeJaoAT2}+w@ZoYGZpK&AVVe6T;=62UvUml z5+_eo5Sh&>`Ab(oKjT`BBs~`M$}$bhYBgL~bH7B0`cHGk7f?RXLmvI;h-Gh7DeT-K zT5p1|3RFyW7j=-9uTUnrch7;KQl$x+pjj;2joNlSS5Ta=057bKswSbVu@YhAaP+2~ zsTwLLGzfV9&=|InMI;84%AQ{{teRN}t(N9g1DX`&K*3MOD7t*y0Ce|h`@wvJVHb&iBBET;V z2`$lFT=lG%njKcD{2o=|>XU&q(@TQlK{ZZ-25rhZH#7nnZYV469!nx@Opx)Uvw-+e z`b0aMbo6bRwwKU50~`Jnm@9z^y~Hu$3YPHpRA9ZXIz?6vaD;jE7G@(-5c+daNb35MT}zYZZhbJ-7?TxLot?(40( zo$#P3O_)<8GZM|rX2jMbw{kcJLFs4$JEkmXz>9SQ*<~(3MzlexI_oYM8&jQK?tgL% zGw%5Q=hOe~jq^xGQh!M2v)+~YV}H{3R!f0yzJOA{{*I%y04YsF&z~j(%08C$JD}LU zQZQPwxJWe%)APw9$65*~UrbeaZR=#iqKOHj??fx#MgcE>tMRGq;HiSbzJ zzQn>^$`065BsUhCYFU(jnXD5Df=v8Tt3~X@B+YBtdU@dg2GU!-i6n36-w`8aCX0ad zeTf|SI|IpoV)n}CmnclgMyL#qQojK|f_5vOz;|5`Q;NFP%DXM2Kn@DsSgguBJwsXU zCPLT|5HX%J{!yrNkbKD;S(~~#71DTG53i~-i$UUZmWR}b5#Pka=Ls{>wF||X{EM%V z)ebdcPPZXlcE`(W;=t|^(0ooV^~X1V6^E3)GSdv>gXll6()ziA6XUd1_8cdBCk*M; zos>wa_5;E{<~*7Dx|z>_YnbW|kGFn-y}2hu3FfCrr_UgM;~bW~;lK zFsk_M1s04nn2~0{4bIjl7JepQ7UO3to$XAo9E^>#CZ-3soIjM^1Ow))N2`z+kM{$V zn$b@~4EO5wWo$sxrdwdW(kb9;p4Wv$oL*`|GU@BL^htVvQ)Y=xL(8Tt-vK3b7d0{H ztXrA-KIsbJVOw`m?bXz89(xI&{?Gm>t?V|D>XJ=pJ{VpR=zX~VY9w+i~gF9~gxUQ?T!Uu@V@>`T$Q3KRzH5bVnt;1x6#_Z|! zB!1*}CVuHm*D<9}f}6I%qvW*8@F~`gvB>04m+p(;pqfCZ51_u=>-EncgIZ*?|wUl+5USEv1JB_Pz*|r z)s>FPhrR3vUyMfwZDG^GC!MIy6+r1ZWO^(!1(Ej=FTLdYln2UO&PM~c4X3B)uV^-Z& z2G*C;c$IqOErMDZi3r2Tw$hgBPEYG`;7&|1cp`Q&81(MGqr>%SCUc~OoV!{l;I6MWvm>GZkLgvZ!{4vD;Fdv;}Hpm(%DSzjH06OR7U8qUW(yP%?DX6yWx$P@{+7$0HsV-!$@9@et zxf6~kUyGEIGMsQ9ALMo>aIcplZf|IXfA>>A)7ZY9Ur{!=Oo0JNb6PR9KK1C?wNsrV zFQ%j#Z|TKo+1U;0I=w%TTk^2v${D(XYBpkzp$GdZjb~6iYid!As(wC*Q2!M^>jcTY zW8Xt*zhm5`f$*ZppDoJgQ56*fSFSBJN@3;i6K+O66_2Two$v?LUT zefdY_96O944Rx~f7s>s(cR2Nghk(yF9BYTa=2Tlx!rL9AH4vQE3RCbgrqlCW4CKEi+R10$+E7!E@#p4zCmsy4rUr2OeI7(4 zv0!Ql3d@iNfO7-}!@U{>yA3;?LG6+4SI-*2W3^r{FzAt#v?%W1vyrYI{knbxj)3ad3DWo{fJOWp{KlB2h8 z*@}KBF1YCdKUOB?BWs>f7W}I#;;tYK74uk*fT&)-7nRA>^Rp_?R?7fO7zT zFohX<@ANLVDF0XNCe~`Oij-RS@MN!3=#1ZB8Y~|WbZWE-VMHAKkLvmxeULeQ0cy@xi zjz1^?S`-7jU4bJm^Z1{>`8cqKw7jNs--WzqEfa$$&x!?1RsC+01=h=XTUT7{_mD30$gNJ5eu z;t|_BA{HyC6;rm=%!QK`SUxh1tu-@@e1&ko9ap;2NBe(ZE7ottS3F<;7bQ(c8nS=Li7NzA!#HhoT74&);-dtXyUq4 zrxVC;k=7-N*6x=*v5WK}`H~?t)k9{BIJX#vQhn23o+14cFvJ$xD@nVVU^bbT5vJ`_ zZWeJ*Xl7~Pt*Z0t;E3nuP}Ms0m=Hmd%y<4x%Yal|2(ku%dhdv0y2AMukz24P0Ye|% z-P6{}GsIVZ8B6p@z>jM{a&2ftjK7}+mcG-%Nye@MCH`+Z-|5)txr(mcZ;05LIeE>( z054JbOCfxi7Rq@-(ZL1b^) zul0uuCD}lk9I*inrA0leS(qj=j9ply9|R!LO3}v%@xmF7gIG^Xf%S*<1qh(`)@Hcp zrRYTeeqJyIFha;3M_2;;ElOK85xJ>+M@jM{;k&m%?Gd@aID(l>_{N~LQE3X*c8*`j zhnH};dFi>qal~67!ZGRNahDC!n=LOLH;@V)r?N(1GRb~CBw+=NyPXcKM?g-C7-fg2 zX(m4`*isTGqDmM~1WEUV_Apq^@Okm5gaY{t2=@YGd<26F=?vwCiFSEEyKvU-u%d8FQa6M|P&EdVEhO-8oZcc_BAEn%XxbxaTj>&qB1B+FRcd*n@Y4~X`?&9}V$XRywu})O%^CNM%ZA7VGKl?1dX!!;B~$;*a7|k3bJ6~PT(zYA za2E5&v!?cccB*uXpJx0=!XjO2+9u*zwg!R+U%E_QsnCs0uR9Ih>f)Av3ondoUS#fM z#Kn|6nFN+bAVX;@7xU;`_;*9OTZDJhLK1&i!+)AknOheUu_dqWnco(IILihpYc90Q z%{b3H4uL(8^aryC{8gwbUn^6toZD-MvT{?l?7n;=yX`^FvpjY>ockJmeV9#D(c zsjJ%@2i>6yW+#aFx_={8w4L!B z-I-Fn0s`9P6Zsh^`31u7Dq-msNur#=#2Uk6VO^mm*k|=Qj8QP(wtr(j`&kBeW0IPb zZrJVf3OVOq;#KnctM6-fC^_rEoIc`4i6XSq4z@bqpuAvhTKTH%kZ@^Zw`F_L9jJ}7lf_?UhohkT?a?Z%0TAd zq$%NIvU;pB6`e^#N-pReOiTn+_5%?}_eve9B|lN~H%41M;X1tXgndP30#}9)lxmvH zKn`0fv)1jE%!s|LWPeAG!{2CThH-5+BV$lfdM&y_RB=?Cv;@j6E+6wxb=ES&KiS;!P)e)6ZFogcP}*F`-l<&6nYW*~901MquD zyP-GD2d;tWkWMSom%r!FpSX?<-Sp~IKxb}}FbP)kisS)u1SF7yLwl3lXcZ6#5W!NX z)46yD554?3@*8;V&*skG3t=U~JVF63vidY<(PEv|oX&}8Rs9Z>)SHVxsJ|zRdJN+T zPrV%Kq-v>*cuwPYrO9z5P&YtmrY9S2yw{2OUx~_Ab#YW<=L_82ozqM?!ybo{!8xM=+w%G}UK$aE)dd^3M$2~i{TRDg zkN6I)ZpE`PpuD-*-bxh4>#C;i!j?I&GZs6ltbV@08GByXy|2C}iRtVL4hhT9umD-P z_Qr@9DFmw0*47`gGkxrG6W@JnUhk+HI;9y?y<4{@`B&YiBTu1^sa>ofN}XOY&W+M* zCX7ZAv;Q)ju_x8h=H}S^w3w?*_TK||Rsn8EpY#MKB;cGDPr2+>KZxk&wZ*Z`4ltSnRb*Oy7e! zmnN!4pv8v4%iM0bHVV(ujl+XA1)s4Srr)&jCv5yF1;W>605*i*T+gwRK|)Gory2Cn zi0JASbt;Yqw&fqFIzb^{T#B|h*Lr(BUA0A+Z(}zHlMAPm?NRIiVVzewV@4S*`X}S? zmfZD13)@zBeStnJK*|nJpIU`1nAKQ9!Knm7Xm~uE3f!) ztLe1#V2*3_r>Eb7Zd|&hUASyT6gmzi>ielby#Zw%TNN-1-@61A1k|@}!JYZpXy&j8 zI`AoyOcwWX6Z>!sWOa*WkSa0$EI!NQC!=4yRj(yJa$?v;+!edW!XXuRt94Gly-8aL zT2p62$)})gBfxud*^kqzd^@iHjLbSZTYtk)9ENLm0%anI?+$W zhXep$hH4@5QGFs51#yqN#s-5&BKzp7C(A!uf@_xPKdX`w@;1nMMQJj+l85-p-CVI| z6m&3&NpIzRwwur@1}k4teK%vlXvZw;J`&j`$~Mr|A1e8# zJipPIyeY~~l;L2nmaiL7w(h4&pa4{7nQrGGrD#RvHO$`~uo#W;pB5XipM*bIG}L&X zJP#V?!l+~FXqp}Bx<9jj`WNzdNtkoqhQ{zDu}Px0#-EkFw2yy&O8Z9C@ad(liCHrBp7@Yu_u3%EACo-K~dV6k$UKNW@p+s=i$mEC`zdWrr{I=?u%5?dNoXe>|XO+(dxgkp|f+vc+sxnIYiVuXM>A4JB z=(XW98Rgv+ZvGs$xn!5yZ${n;4jI;r08+uX4W&cqfIGiSH!em1I>5{eX#W+zjrJvXR zm)2TUNrT7ig<12rv@J-HZMWlh*f$!aW*dDrv>{>|1*u<@@?EM>`7I63-|{Q5qVcccwoGJd@rvpy2!0 zj16nm9UC!I@#EW>Y{LBK91#*MD5_gU!Jy+Z z4O|dlZlRd>tV$`@Lo4Vog$MP1+Ic!Gr4C9!XXYWQ`FBOEs4+Td z)?pNpMav*cUW^5W**Uz@?P@J@dsBh_*4(XL8Y9BGCtW`dgi zO1C^tY@OSrRB{E))OST~Im`d@m70n!r&f)u;zVJlSzl(q1i6Ys%d0e{VjkO5C7L>g zJNjlS@h07|;*dQ)8+CUvwIgbXKiwJ?-ziF=hh<|f`0745;R6-FKEIqBXaO)~3%G+` z{B6*xXum3b3Uma~lu6s{(knw~K5Bl{IWJxgEX&DxQv;VW;g z_dGrq`P^$amGGNL^x#3&hlfE%i%0bd4gnAaX zi>d%$dRZILMyJgLdm0?*FYy4)FPYa1ld-oi2rB)*pL|0?Dw$qGtl#^S#8gZwLQRHH84P*&y?_f0B(&Sp9{2?72 z76zvE5-U#sBw&D=9~|>1L_j2S2#$hADu{~uR;_~dwe9ggDbe4ZM*GOpGn_-3q|Csh4zeM}daB9j!D5sa69 zeT>h}-&!b$ljwV9&{@lT=b2jgI_}H+7t~s3s2#35y~;EZseI{1@F~|sjpqWu_MA42 zRcH2fX8M_+kMRj{Nba(`^fS8#5d2rD3yLD8%m1iyQ7tnqO z$+^g=-!$lO*(wS!p7r~_xpk7(2=dz~Ocf|@E;=OL zTB>wq)bL?NA*{?sB6*eUK|7Y=|{&M1D&B7M*1-Qx2_y-@Dx%q_iB&2eSbE+Q8QW552_~`hsSl6)RPt z9SWJ6_x{N^eD#~>;D0?0%;1!q1-mwOq%DOE(RVF2jn|mWYC~e8Pju5n6N{HsXXBGw zlKm`F9AZ(Ohen42jiX|yrcV(3?#-p40_+LuThBS~bRl{dCNk@@lT|~_hfq5r0<0wN zSIuyZt)wzAE7I*0n8WjavaqwWU&D_~w6wCLe*bYdipNV~(b@2)@c@i39LOP6QEo(U4qL(=i9a(c1_AyrS70OA~lyzC$dj zkMcXmp(#tpwQzvs;S(+vAon-xV;P9OVfEiXlB+{DBkbnOLwa~e9?Y|?Sr;Ma))_dP zi1|nwB+A=6g^fW#DQwIx(e_~xfh7KT#R^RcLh6uyPe<~oQ~_%s{1`5XWKKt*3fJn$%jT0cD_v{T7NBVF<|XThMDXIhBIoDp$4 zml-|UT)GD3ah9*@cjkC}7U6EEf`wWIul>o)+P%MwYRQ&kC1bus_yWqP^Nj9C@--#A z1yGbaP1z5>)jA>a<)*tn9LC-akkOr3=`Q3@I@Ty^z!RZVzf~HgHB+KE;k&cs0LC=P-n{UWc^sE2F}NLtty1rxPc~ViXVd68qSF=yD4bxOO%x*nBuk}3 zq^RkkirJ&c_`~*evY_C>^h4^YRB7hhANPIsR1C?!F&z?`4?G(Ih?9S7e zo-GT=zPtFT^f+hPvLb8-;5U5L@~(7>?nFoY1HbCC-yr+1oE2Qnedf~SCPxxAtHV+} zSBqZ8u@|m*Uhv0dc_WJ_K{}O;SH}4Gi7Ga&&J>H}CQ3}49KMuq-P16{qAd~#9;Fp6 zB>b?rJ-_%;*`ENmo09Sb*_z6R8w##wg}zBPk)Rt=Xt(U*n=2yL$eSv$vfZ5kA5-k+ ztV{7A4fV2JVPzZR^E7RmDhwv^mL?jasAX zt3n@u`lJ=Z<+t%_H+z;CNFdgicTskfzeXI$?zl-R$XcR8JEwdqUHTQT3%bA)LzVKi z9L@LE5ar-`bDW6tu$;8*SUE(n-}dSKB{Gw5FlaO1d61~_V63POEOT|xb&vaH(*f4& z!SKC=5PzXbxDIDjp~R2$yd7p0AlL`{p6y~@qgfC;q@P=1<^MT+2_{HEffbGgU6BMQ zj2%2U8+eA(L)#m8c#^^%G^12F~wf&Oz2toU2LSB@;XocFF;rNi<|MT zl^N4Q^1baYtWm;S5hNG?QQTPs89}<}ePE2ApBN9-%_&$G0x7Ke}>#s&{Dh#|r z>8^rv_rSRL1Ek8;xX7yzDBa8PiTxkHNG4>U+LC7Q@H;We$osKqU&cp6ga1iazPSl;v&n?-39aSF-5& ziVbID6X-x0L7#Tp;G@i@_f~_|7ab?ktQepbSm;$wL>?Xybz+_FBK>B#pktGKcm+)h z^SYkRplLg84<$H-e7W7tVK$_GCmh;tLPiaq4jm0^tM&=b>dX#oem-sSjW>_Jih-;V zfQqR>g=s!@N9^tedOx1ceJ;JqNOiQT>qBs|bKKAV zVILX<75xZ9Cg5LgSLd)Bx;7df|<{FTC;h zh@enAi+xFB=(){h$1b%NXUhOOmcJDHc3B{(uz(=FKL2<^mo}k7glteP5_R$KpVI{ryaWcTWQ;*GnsZ&* znMoD~-*?c*_s6h@N;(dJr$r%OjUkC%8bADfxH0R0IXu}igL}Yvy4Y_dgKPpItQk9B zZ0fZ5zKbl7xm^AOh!+`H{Pvc4L+6)=W`y2gIgz@qcOySCXpKMUsv8QOlyl8xndvB> zSo+uiwm;s!qtUUf(70AgY)i^5`h zVnSCIv|F?ut8nD$|0dlk1nEDEgnTr)~1u;F^+E6?t5|g)Ho;d|qhhZTE?n4F6f6Kl%^M*G8 zY3=^}0gPy-nVqpu{#cW$EKl=*i!tjlcZDr>Vud0p7SKA>G5Wl-4WiQ5vJ|mVW1>#K zWTzfx?ceDw=qUHn@yE88w1fv%n=!O$fMu$s62>KmaY}S^ldh>kZ8FTKAY4(DcJ1ZVKUZc}>DD!Iy#h-*;gMwCqFsvjgnK`(=S#S88|W3K?)t4f3lJZ|({ZqaJf6V7w0~ zuY9&ucdDAsWZQ}3ojE5ovcz+a9<1R}-NgRKJEpCkZ174ld$SH1(^gav&!485@~AWD zC{IL7?MNN!vf^l*w-vGT_X2B1MYI61jd}v_mS^pi^eqrm%_8CDa1mP|bE)aWK#7RT8}FA7DiAZy z7NH-T4xnA?PrW>*vQ!EA!<6W(q*5?TqP#5?f*^Lmm`PJKFofqgM)#$KMnhgaJXkAH z=Ln6kB^XEf-@8oA3^RsE;uVY$h1|GlPRCGA$}oSKE#%8{>sC`3H`LL7 zwpuT2>}j!Nei>_MpBuXbE0=n1z7)(V%!JQ|9zYg=FP#Uqa^O;0ZrySlaG3X!wn!O@ zFOK@@@I1|6bWWC$L6O=gjC=ff{2OdlRd^FUjg{|h&Pyvq@&3U)Z$S)K?mjW}K@tl6 ze5;i=7jll?oLWK^;Qm&evZ||-+eFVGv)q(JWROyctrA`S5k8s9!Y}uGf0U;9&_S$) z)?k=O>$|$3N9+xuHIXzA^lp?O z_*GZ1r-`sEYh&--md>5U0{*xRgko?36@<}c?oT(;P=#P zDD?4z3`rfsU-uL6WL!)_#;%I#M{TgMi3|Q&gb-inE6v z1Af=8Fb@D|4%nxeEg~7GYX`6B8{GJdb?KnX2;Q!q4BZ@3a(CQr17ORs?qzCv4FHOt zDcDIvb}emKz5rFHEuO9x#c6}=n(eXf_x*{&FGGi2sWiXo<_yG{S zFv5mxl^W)unQ1qX1EYpkqm++Y*5(MiCq|w>lx|?+ zaU~u}$l5B4r6a)3F3O4h)&Oyo8D{;Up!7PN!YZejA8#_Atx7H32{Ag2Xs9+~_bJcV zvOSTrrf){@?jtVWo5>L5>rt*km+pNXRIyhJa8SH$o?MAhV>nTqOn5#&KVOV$*ozHl zqX%^UGM8AvMOkYnj#do4^ zvzb=bR~k$3ef*zA5=jZ>4TVn@SG(ttVyYLGlP{3e`k-KuJhyI=#Y=Nvo~v5xNX<#+KoBf5mX?N z$qP90W=mY{G)J+h?&m&Ty&TM1guHSxejqM}sx)ukhiV{|zC?}T{S46H=@8i+AE$e0_P0}blz;kL)`%PNCHt^Lp|Y$M zRbkS={qNWLcX^B+jZ0W4ai3wk3g=R@frPaeQ?6rMai}yR`B7t|HiEEAw^Yn-v%(Zz zM5Akw(vD*o@>&af)C7+fb&(_y!C^wHjo!h3EwJn)U=0s(XZwt{W zOAhXdD|kq&Y#;dg-8^r(j{t@ZyN_YHmBeu6#c)R9=ZfMOWx?T|pM@dtR39#_UYHob zy+cOd;#m6+MjoMNb;ywxRDcw;Go539sUwC7$?{8f!8-w0kxxl(kY^Z65fGO!5V50a z@ZEb%!J}(O1LpO17X~6Qc0R85FTvWN1}F8(ftg|y+nY}I;Q7cKmE@Yv&lVA7>fesT zk#!N=ol;26m)b%JBt7g>(?AGdPP0p}>+ds(r6v@G(&5;l7c?nPbJvWf{c6*WC`pb% zq{{GPJbMvDZ;n5)dR+rbUgS>pDMC*BH z-o8yQt#^uu>FB=|JoWBycF1k%FSf;giy?tA@no6fx_L*EI=G;1$z4DFEyJqm$pjQ< zz_8!3Yh}`?OJP0jO{$7)$m*T0EK8FG2p0YUr!=AUcsjKa1XNnIpmbx-0vBDKW4H|= zFk}9Mjy|A;ZsP;IpLSk4>?zg30z-w?O`@gYlm0{bYlqvgUz^L?(bL#9pY?mDN#vHI;q7`RAymHe2 zx8}q*Gks8<3{U|Fe1Yb}{aUwg?5V7fMCy>LoZWTBxy4)jXUUw@McWLNd|DfCNr|Y| zs26&SY=~uV-$6Sy%IoTUR;GN96<^~qv{sM>L*$7OK~{~~2II9ts&gipn9xpZ6X_Cf z53keevmw~ZuvO@2cr^v8UIR23u-3SH?}KBWvv~Q)xo@j~F|J~nCB&+XYZ%aw1)DBi zF^?oAa}81D{Sw8<5Xl5ybGAJB^#!2eb2YL0Pl8gli$kulY>K<)7hVg@{ed-Q6|2KO ztqs742c~ctwRZS@$cFo{l^}90SK@NTAfQmuqFnHB5`L9^M7Ex`mjasAsB!~<Mki!L(ejdKy_VAH1d%Dnq92+Y4bxefJgNh{*`s~e zliX2H%G50xhC(ar-Hzns4_Qb{zB7juVAhxty-}nY26j0ZKs?3zM^?7b#1dTcsC`3r z(?(1CTVX-z{cvk=PGT~IU6@`A#88m+X zV+;uV@zZR75QN5rs%b4Vb9z!rFht1lWmxbXek10eGHxQ!nZC|`9WI7 zW8I`V33~dMOBD&Ggfu{b$uIWC84U*arURH%la(QfkML!8A=n8N_A8MSZuNwlKWV>w zDkeDo2)n(Z^`g-O!CkufZ&-1Q^AkvwIwCjRVag%!{MK&lj1?iG08Br?0*7KTu&=27 zRLh;lc}2IL4YA&%)UG_Oa(zQ8YuCrhQK7nHbLE;{nW6fPO>_g5L!5OPVng;yS9;6s z5J^im#+zjCyVI_~7I`9;(VMk4Fy<5Fvtr?@#%1*JfHF={4-;@M2Uc@3l|Y3u-h$#! zxHFpV(J|20T;MrJ-{SEB8}hJ6zf#nEaRKVwT$r|`Qx0fUku7FG#h&6sH^SQ!%D`yS|c>(BIArXbKL`zsqk ziPUupW_~?O)EnY=eo2ekps$Bhubr9*(g~jH^klqiJ0x;L@ zXxM%zb>yI_o+*dYfEQ%ZQQH8#^!6F^{N%Ye4TMdPQ!cNG1TW?!u;M-%S}&{tJHRL0 zL7Dauvka*?HT#1b7zqmpXd<_39#<6b5|FR$bzR(YLd{9bWImov;*uFWBACg6a+sfG zf5ox`r97#WV%;qPZYSIm=Ia+zDX)UgwqK%q&lLs?z)OxqYSxfIHLFSN5i*G7$e-( z*~9Vh&|T5J(h-M}*0I)z7P{nvfG2mo%xX6)k4l;RTbCnvol@{5f-xKC-8WG~PH`}X z3-59Uk}GkhR%)-br;b{}sR_JsP$<;M z9UGRLm)j`rB~w>k99`9OOSwCmV7n#pfs|%=Um%%^3NK$Q!L~%i$lugT5;dnIx8uR& zf#>fYr8K)=yF(tYAk5k0~FV z(hr9-(!vO2K5EBkB;)z3%9Z+3%%*-UlfIyJy(XL-Ze~b2SgXlqxY<~29pkPD5#1!1 zy)xCFQx}A+Ngqp>iNQdnu_ppYK>VnjcL_jxOJcdM%}8%gs9_&5k+Iel)~Be} zJJDRvoC@$wl=5f`aZ_Xf(A{T*DiGzm-S&&y6vS$d#OMoFR*bcYz^w!n`EBNEfPR)> z7n6tmmtPR;#(-%))b)=wHJh^NLiA)9%&=`L3KkrBt?f~@A&tO_v=Tz6kT@1%H6}Yo z5dx60YVdmU{a)1($lvB|OF{+y0LbE4YE;LOV`+X$6z@cgmR>9=-}wZBnSz2AfW$fn zo$W|ViYZ2qVO+TVyoHu}`1f}|A=O6Bt%#~3j27rWaQ8f=mV3AO*nN*W!D^`4DH?-= z>5!>Xhayi@v^XbX$f$B08j{%dM;a2NSUVz5+(6pP5XrlB?5LsP3y@T1cpQX z4frS+tliJ4Oto{4FIgLRP-n%)yd(RJHI~rxZe05o^&Dg!tY?elMyi9uo>-gkvWz|W z7O5E)eEh1!b}WruyFY6G?S$zbv+H~0G^IcWi6dxS8tc9hgAO053QMQfZZt5JLguc4 z7(Byr zqxs`17)F8O@TiH@#T`w89r|a$%U`e}uI_?}yO=L-ob01W_v`rilfDXObLs?ocqsp{ zPD0jsl~c2ivK-R;puPU{1${8P!6Xel?w&P#7W;en z54^q%o4l`RqC-qn0u-!4WB2;B}~67z*Vt_+0rtzj|LD1%!0c-^9~!vphXu zp#(O2`U&m>d#J`F4w6BJ(*csopX$`zg;$3X#%^(tOkIpvH_Hj$SbBF)Z4=*W2ChmP z+>)nO{y4w7zfYkYTWvPJa>Ag@L5IQ)QWKFj@c{1*#wT+X1e$RtN|&Jy(Jq`nN-vyZ zvmBJ-ZdgEm$kU&08yKpXk`}Kg9jgS;SL}=Lk$u`D@}%Z-|56xCt?TJTaM9;spphD0 zZEmPE(3JHdp*J-&T8Rr6+2j-WAwtts))9AAOrnlhG0(i`8$}iwh^WK}}vUWpmvX94^{%9mn9nS_ku4srXW%|4Y;M#Co9UY3JRR+(L zA7z(RM{6OtU|G!y^$JucKvmt1L za^9m9T0ShWL4(%5BHW9D-V*WUDBhL3`=4@it=OB8A`5Xzo?lV?4l|x;s~&Pu~KH zZ*sqsHm%;YC+3RZ@3jRCe{kdZhAqHgp3dis&>a#mhiOxk5bZe4G_LSTp;4o1$U&od z(jNcEi#<_)SVez4xQ?EOJ$4nSH2+xyO)w_ld0{`gJ44~AAbjoDM2R{xo#dEn|nm9b9ZUWWfqqk__!JO|Ez|f9(VwWCzN3sQ0BXVd7ekd zq#%nPxX=qP({n6~lC)*Z!JLD0mmxLr#mXKFz3&U}o{(|O4aYD zwc;rXZ~F+nWfrP>mKlDTmr=rlYO>06Hh>tBF-MSSsL01CbT4_y;DZ>hKRrhG#`kSK z5Nz}X*6VtS48Krrfr>QR7JmPrWs-c`*e(^G%_VX@&xJh40oQfxwi;N9iZv+v&UB;M zt)2haFPza59m%0pVn3%);&ccv8e97RsR}sh?WzUq=bVWg4TQ&hryXTGy`w9}3v zjn*X4bF_f10vvrOyw}|Qdl-cI)YGtHm&-|?>mHom(|u}XD$ny*_xL5`$7^pMp348A z{YxOznAM;123VtOjX__*q!7vyfBY!-0<{XVNs&N1VJp`YWT)-HtG7ADbRu_{r=#)( zNWe{e+*9rB`f%2S!wZ1m&MT_BRN@vW9)oP{I7$*Y$>22H#6lU}A2$xFpm<`&2(eS- zEespM&0k7r05Jay&AS)W$hCF8!dCkn@7eJBYGE}a$aWU$y@XCN=A#@v!D8HSq z%iLPdo2$x^$*uqXu-Yg+Q|G(_jGTds8BfZNfpAWVQW8#+1!ywsK=J(V5N_4G=Olzx((PGb0avLlI@bWGydx5*R& z4)649F9sOvA-f#%Kv04awjrdwySfR0fBp)mwU;Fm4VrFP#kreTpcGiR1Fj&?C zJ!eO4+^<`n(+qH7&nur#s-6DCazL5QpmGS>if*1FmkKP)1eE9_^}x43u<Pdpc;}MNZ#DI13FkjUg+wuy^JCU($29*W~gWoMh zI_R0TK$c1Mf0!_jk_YSF+EYg4qnno;W|n75_#2-?$kI1=D_-PXekU;$TKVptaV7V4 z`Z#jv+HZDQv=NvPB6DdfLc9U)R!KRgFex?!wCa{DLdbbB0UL?xyZVTUx7QD8mmNDX zC>X8U`>U#MfIO`)2FlJ9eaH@P2H}=wgr8cuH0vzftSK;r(^mw7Qj>%H6KB{Xnb$DF z3k^erTg-~%Blq!Ety?5YaiKa+C5t!ll}l86ijfyU^y;g2mlg0KPnV zKqx*kkwRbxpb2&-tVpfxhszcMx_vcrI|go2kI^h&4K}iKWTGXNZ2!z|hSkR||@YX`CiVzk_<s0`1Kskm?R=&7Xw@*hUve!3GIr9c|>w!7dB z%crQ=JPtOI239C#EafHiv(AGUtS}mP-XZtqx#L7If68c!CJ=o0oIAILphjN_vy?O$ zq7;&3%+!*m)Z6vnYg*^{iWken)+ z24DJV3G28y6hiusbhgKJCmx0T8;mNRriMt2FT=^8et}`d9s*`O|xbMVw^C{YXD?xQR7&=NIar$2X@I| z`GZi%DlLl=S=EsliVokdwERWkC$hicLHfnc@{7@o^{&rQ-z!S#Ab>&W*JakQ#U7b~ z4PtZRF-h|i;jQsRUQbktwG`4iBfc;8d*JH95yg>LV&3LT5X-j8<`0G*~oX3)*^t%biW3w`Y~FGO`VOi zd_WFH&OGMSzH)OwI$+9)n7tkaJn`mTcX@mA#eV<|SLKl5*N8APsv!CvYw;894IO=9 zBU5so9k0$9MfghxK9UYbIklDmSD0Q1nnBL>e*E)6sa2!3Me%sp=Qo}E*M$8kI`4P& zmxX{*sMhQ#xXdf5U!eQ7UBH~y;LD-;wdBATp(%*Tbb!ER2>{(06saZ<++o8W^knq< zbBkGTl>fYEfE3fGQF^r{eQur*XHhFx#WU}L=IA6fkmt~)Ku$I2g!GWGOCy{}gp|gv zJLRel$P=na4H#sy*3c!YZ6f>(E>RC%jm*gwC0983;H;jwQXLk(jyZ@)=z)i}?I&x; zSo4VbbN#5SZ7=*eiZU)Xb^XDJBC8-b)ss(>Nz1t8uTW0v*=w^Af(r8wX{WA{^qLl3 zsp(`Kxg&?`CacIPC-PbaC_lv_`Mm95uE!80jtazA_TpD@whym>P)|+=q9` zx>}wwq`5SRx*-*hN4UJ;)BM_#(}JfI)N~VA+?Vt4@JWzfxHDIU@o%U4hQ~(gZlfeH znv;2#M+joBP=oYdkFW^5Xc^k;!r9My%)yRKsl-Qe!3sLCUnztEQaW*Z;T1W?sl(z% znLxG;Mz*+wUQ3%=2bMir@)c{VMP|j6W;$=MXfL`OO6_HZZ8jIb@-RpRj99jo3X=1r zTwZi1@7-)pHTJzUYd%L#Eo1#OvOw>%&%n0`2+YlTju`)B3K`2$pw!E45_&|k9HUbL zh8nY6-|0GDk5$hxBqtSD1tJ;OoUE>!J1RvMH@*%Z;@;RC1HZ6X14aP4>-t;y&PLqZ zi;!LGsTC5ciN5I@e8&?#B;0}iYF-~+L)v`)TE@#=sl=Bp`2isUzS0i(xDBI^Hptn+ zdO;PHBBYy4+=r#x+0+$dUz~@ODDfAcf6#|3>5a-sr4G?JxS(&oAn^}l)zX60X| zf5^sxhff|=&JHTMd2qxYZ?laAJ!q{+gfGPZh$SdL?NMj)B+O%-poBLqBHP40pR>fqX0O|72ZJSKJcdkZqndXF*;{ z4g{OWvg}4}BXcgNyIwkM$xq@}u*(f3I{n2-V~l<4?0)$81-`a1_ida!|6OgPLhO`k zP6vG;p2>VXO0fjRd@Xt8Ehc0-Zl;Y5R7@+e`@A1KV8xtSFeu|qK!3QP;91-}5OX+O zE^k{>dMMFcb(*+XW)-@{7fkBz`s8^dI2xD?z$cuf4Kap%l4upIV?EVsO0s#*!YEu- z3h5$PS%OB_%sdGwDl?3?auI-ENprmc???lW-F390Z+9nLIO0|KRs1s?P_>+p_6M+l zQ#R4T1Ic_cUeb z)~S=sr{h8fu6jLTV*DR4|E@wAyk+$VIV1;4T|=CDI8+@eR}-;|uNnhb9S&kVdbPIz z?T8)u%~ip0z*}4m?UOg+`h@(jMlEHNhND4=yx9PjE!43bEAwlm{!pZ8h0WuKPNQ;g z;ORt_?7AohtvfB+n5jZTz(vfDF`$HZyoLq50?Clh>f0J?e+RbLrFYBhb;M%!>GR83@jClddwU)l z)=a~t2|OGFczc{J+nZvX`hqqp{P_ zr<2E>x)_F!3Lk9=g3oZpq7xS2polPWEsBC(dI&=Lb$2Skbzsf5>;#4lEFneE8>T=7aTfK zuW!2)f3L!eYDniLlO#lrJ?65TI_Ps(v+G30RO1y(CGu&LQtV>3P=F^(s5W`>82kCA z6s((O$-GJQ@DxN*E=9IrM2K6L&vkL~kvo`1(V6ZfPybzHG!4uZ94xfztzpDi>6b*@ z6L5^}Pu~Ej?KI20W?cNofx82V1~#DdA|Nqv{VRLmVWEw-S{FXOKk;Ny958kN4Krjd zWh{61MM3Yg&E#nlFUkXrr4A09HzHdxD6NY4LFPo>_{ek|s#K%U)BMyj0|7j%b$bLj zIHUv1=4q_p(}V9ly0hwId!1g9()uM0oK+(erF0xoq7wI#!QK+74hW>ogrV7B9^cvI zZg?u6#VBSstJ3E!^MY2{nrBo8fBV}2L4J?ODH<)OhYNtCZKT5ZQi6ew8OS{?fso^w zj7&(bQ8tDtv`LuK4H{3E<5@x4m}C;p2~}=TCr@hX5}Y7@$Q3-3^>&@5O#3ToHq92I zi~=a_7qVjveoGi&xl-4KshFaOBG2h#!0^xO0^i7o@4K@rD4m^Hj z>5>ox83Wy8uWptsk<5Hh9vjDmF)Xml!2#^?AX0VD(4uKg9zh9(TZ@Tk;gp;veyTC# z1s1Dz7o0-{V@a(D%Ba4ll#cYt^YYnE#d=V=n@`Hy1(B12F?%pI*tWF+Jg0KP@*?tM zAI5^=F4GJX3Z9DS@-z^M@j-r-s5{`lddQ0b)*;f-KD%jf)SqGIV^wyKDU2Ar$McJ< zp|Xw7Z{RE-LD(iS1#V@YVlZ=1?M(chMqc}!weSzOnzYz(`a7B-$^3U4Hy83w^lo_@4ZzYSg~&6i4}{ zU|91U0W1sbnwL&9s@UEe$a2N?RQJCDu*Jc3PS}SvWw=Ru8Z|J{V1T)HNcA`=@psRU z26$m82;Ys&scut8}T<96afz&9gY0#R56n~B^NJ^(p zV}(6={s7;004#8>SuZam4wgsPU#rrMt3o+;hT+V}iRnHlm56a%Ft34BQB0y|@Er@g zZ2#K=Xsydd5K2_gO4O!Sk!yHWLD?xqx7waF_puiXYvyCX^HsDowJQ;~WAvBDpjk2tkq43f=;&A%k-7<8G7mL9mOLlDzvsc1s+Ahj z4~}4_9cAKJhl|-%Y6W&`%fHM=1QyEJ#>mmh!C2oK_8(Rdh18 zR>5bXqZP5Wagx!uHm2nl5EK#?rWCYwb}%<~AY!1CF?OXAu(dM!PZbe!D`N(H2IhYb z6#i47YHV(5=7i5m_s@luzNsTVBLl6pzMHDKk&_udD-#>7kg=nov5gZxH3J>{e_99# z*t%&_GqL=qsN#Dxckl)7C${3%Hmfywnzv^b8qvPTE-z{eSuNG_mlm4Ur-^YJQ{!9Ab z)PL*zzxn?^^ndyJ|FZt?+W!0g-}?WP|3A|Ic-H^o{_pF5@c;MuKPCT@`@ePnkH7!B z#&?7dBGHHm3i^m!6rPiG}uGOgI@k{KxP+84DR3+8P=EuX6f-!NA1K zz{B&u!Ve1Yx?H}I(IcKEJ7sU(C>v#JHEK*}mqrh}NP7?K_DMqD;o6|F0C#YY1h5!O zsaW=i6AjFjqLQx^a-4T%-et;!?1+@NEZTCW2tNe69JFMroQi)VbKICKG!9i9bTY5) z2zQbRJ*|-fNC=LGCpkQDL=33r7CLpHH@NS9krZ{`$dvr>(CF|K8`sk(qa(7jrMR&z zrQAW>lbK-HB&7faC)~O^o{B9JY?Lh5RpN_YX*nHYx(s&%hzl`|y|RR&p#Q^A;X*8T z91m7|VB2E?bQnnnpn}S05?(U?q*@%HnApv)`F2B^Jw|ir|;zRN{z$sC^71S zy46$3Q?fF1(MzolgD(sMuBq7;=T=qpe#h~Sn-fj;VID?NV%=*95o|B29v4pkxUQoBvQ{E4QO0wk8%J=)5L?7cF(zt+n z*Y!d2v7}c72Hib@EBiMkyz?#O?M2$E3~GaDC{#Rk=kq&O7r_#?O@C|{)955CO?aHT}mAZNt@Q4^?rn(tqf|XW2~H zHFt95<|$Lwe9)cRFg+e;dBu40<|-uHQ-*Pc*3m}`Co(BaRKYvU1#(4Zm#)@XQ@868 zu^ASwnm-<_E<^*T>!;_2->14d#hV;rXzrXLto;fv4=oe@Kf(yfQGlO8z}A*CP#^xY zo_=U0xub^5_%-yQ{-c~1jEYkEKC;UITj`P{GT7jyDzAjEUCCo-B~`z{g)h;Y_>K~J zVp>4Wbi^evML+oYhQd(F#61=2kCnrODnuwv*0hmD;Cmwr zdLU$atjfVn)%H|NFX80#B6 zyGWcaTTr(#YaqIvQC&>9-U@1{#iwc`^9xA!Wp{58KeO)*p0T`WbJRT8h8Q$s2QreG zGDsKw%bBZOu;^m@=%X#24)b)+o;QylDOYh|%Y38oZq9q{u*Q0#qWSnTlV&QvY;r8U z&Z8anWXeQGP78scc96cxSt)41n1pwhj8O=bZ9r1;ez5A0vOXc3CGhI6mf@aN3U?&< zrSQOR;@awygP0u(UQMq9VsM#XGKmbYw>|Re=st2BIG$m z1EOB)#)?*R$L$WwF1)eO5WW&|BIv~H zjWw6#vQFU^>S+7dQNv8MHbHIc2}+gNCuC@x9fz2^_yV>Gn1IYm_0?n~iGiVK zW@r(upz=e@Enh-yWGN5prf5->nK$l?^<2<+%Ebk8fMQ-+qP#n8fm}$R!0@qjjQ0xT zGED^%sVVXM$SDwru#wRQjO@QT_*Ef%{+=|$XMJTASAfg==D?khwS)ndFXt1O1@u~H zCaYBx0|Dk+iwV+5K>N>&4y2bZe+JS}q~=|5m#0By-ES zV%)ptXaSK7Pc%48+i&{A+GxDdpBK!&3%g3o<_dY9;56ZD7$Zr4*w>D;HoRZmfN&9j z13VNsWHes=M4Z$dxlb-`y%O&vY5m{yb5jkd)iScfu+bwICQ5iZRYH~wL2k+e;H9jI zxDp-m;{^gD56)S0uI-Ss5Wm5lv!RFOmSf4?2?J~lRxcKwU*R-KG|_b?+lBN6ApgFW zCVAsjmlKzs6gI(I{CNgb%#Ozaa~{sXCaUV@S|~%P-7jLtOJ0S6cL9;6pQK$6)mHB%+nr zXcRoFs~GM{w)3gW^Hw~v=JxO}!7Hh+fcUHT)Hak-5Y%-cX$YLN4%_ablAWB%lYG7e zG2W=D#v=A&?k#!hp_Et9k>Xhz5~Lh!KkyHT1?;U%8n zd`A!c9W3mJ#!d5dYTWpfQirt?2TU2N^6&RPnbOMvQq7!nC>aatgyVbkT;BX4C_jkNJ>y~99(08Cdg+R%Q&#~}0bC^J4cpE7K%stisACz|R z-)WR-#G&z}@`@%%;*3tTSz;<`%@xehQjfKCPF?_aZL`X1Ca#^n5I%7!gx5RL1y-Dq zO3IKe{lZ(&E-#)vJxvmTWh(h1{?VSJp9o8LY2c8b$+308tTe2ukk=(nht(y}9>sL@ z8Wf&(pDf>0B`2?f_7QqSIbzTQoA%v+(KayN7+hq>Y*JT`EpJ25O7F@GE7}uN|5^&i zp0nrvIPxl6uru$CI*etlcGvOM-{?MPo@8{DX3(<>#4D4TX4U=DC!EHcn|_JJdGz7i~a-#eLrF)9mc$33YXVv8fILiR!4q zxL}J%Y6e;Nin@nUJXJR# zxE(xsT5L)kJ#y`B*KTU;2bh|~0OQPG$g+8L&g z&gbAIVN_+^}j(JDKKt3#nqjE(bGyD?7ntBM*HmH7m{{%U3m?qt`Kz6UJf{#b`K zdo8v|%T3n;&`5sXLRxS3tsmO+UFvajX$IZ<(c2w~>@od-G*%!K**MPnTbO^#H)A2& z1_oJQ67{GaF>f0v83a&=d}=HXuST>|uK@>yB~Gl^eNBeCio|l^rLEw&S@UO@a{)f; z#djaqXN&1cOy9M&==%o*6HI-j=s#dZWBd3hS-|2 z-7|xl_W~L@Eg+5!ev2uo&2EX4pXWwD_Neu*hu3+A$G|Dc;PKfTIP*?Jndp@sg}T?P zv*>XCA9r2$1M3-EJ11Wx!y8c(f&6MM}K< z_Q56GM>1|JDsM;vYn;49Gx9nl;}LKgHi zdTLRLlt$|YFlt`-(-vWHq(NuCO0r{_1a>r)3R7ps4f;NrhC ziSeq+nwIAR(WNVGJC#|l%$n@qmIJWPi7>yU6(i*tFJ0CTXM5U5!wbA<}5g5imIdtACi&qZW$Mb8=Yae3BWvct2m z45aE4QHLz~eM$=0>iV8#f#xC#IcBnLiW@zIQ%c6AAe)`~H49{f+#(vF<*qXy*xC)h z1ueaBp(O1E5{18&9H@uTsE?gx_RnR%`4Het$R9$PqTx)Aj7nBAD%z7Sb=W_?M}@o;r4W+_Ny&#sI1o7`BVJ&Tm}RH$_vDRLi4Q@ z(6d{?Oq$&^GYO_@X3*RU1(`5+XY<>WzapDDdF%iLe772$rABsjbG0Ij9Av^v;A=?{ zE^z7AlyXFck_Vu|D}pT%DBdQ}cxGu*a~mv-9xSF1mgUj>K~qsY*YX3+>>F9Y4*8OU zkB%}U*fOj|Ha>!!kD`SeG>7})Hoxgx8lx?AcrL2g=b?|SGWd<_?0yaG5D*y8&>;xa z%!Ry*5b9lfc6)gj+FM2uplB1tTw9p;?dZ~~!FJxz7F%u#J@^ao$os6{SG4G!VU$mx z5`b%P_ODV{z9m)o77uAgNGU2k>ml%FoJo7#l`d_3>p@O1ynkXvf8v@!`k=~^QipLY z`5BK`Rt@)7)Hv$R%wcn#CXk*Kn1}ollL)XLq$y3fH6p``5&WRcojAxo+p5b}+cHg= zTPwZc3=d;w2#S5?!kFX;4>WS`@eaKqrK6B*wMwwZ7c_aLy!+Hg(?($7Vly^Cgv0N| z4H>NVU-v4Z&JM4wyque?=o7q3zs-!u`m4(B*eH4jW#$}s9t?}(<;d?COR8tdtNQq> zmJbZ-Pe8z^H9^s~J=hD32C~@h2PrP5V%+thD9O*H7NGu2yn;N{!BgmY^>C}ivI7;t zlplKxowN5Aw_(mIn`^lj!;YNVj@6l>NROCuP482CEjiE)3aA;CKv-B2|B0O@(CH@4 z7gTd>=32pSe;OumwOY+s6uhL#M%Jth@iwe1-jq{_OqxP!^bakHcoTd^9bUQ_yBD^ zlpLk~!nld_mWhNT)dMLiz<|Ek52u{`AG5P4+C((1|%Vo zzS2gZzt^Z8B}hSgHLYZh3b75qQm&iv`C7IjmU%k(6w`Ph#KC`WKN_bo+a^hu#uA~i z5Pz4+dKeEAViky%1;s45vTfDT1Dxy)5*3rK1TJB!-8@*6h?uMv5GWI4rDif(g4~r+ zl8-8xd^^rr-IENYef}1=^mG6y%Op<>AAKz5CFlV1aAX^R{xz!;R6H0-gLkaj0zZ3v zSU*Gu`G?To0R1&8SKmTT_%~L$I<)J=15$^EI%a8r!bPZ@FN5#dEG0C2S=!%$8?xC)Y@R zX}}Uj>Py?$M*wW4WLB3ms22fa;xTHRC|&p~9e(waU3kW~$B)$?SU3NZw$P8-4&Q-# zhn+1x6sihjgOM9&8G$RF%$+}?+VjH)^UY4HW=Q@E!EV}v?*ruhLlfUl`Si@FUZQlc-bYsk&`^9@!qsLq}435K+1`nSS zP$ZX!Ui9nt(Pz!S*B-6@Tmp-VdNrqGb@C*Tr9&W2qzh|B%`CnpIcGTbF_#j9MTlff zEOS%{6O_7@Rl95f%)u>11wtLE>0ClJ7abEiguBribMvyqXv39)ekr1nzw2-^TqKCmYW+x_gY3FSM(Q>)g7RIp_u_r~cx zz|W??K(SLJ!%`OGbjc&$j|Q4tBgH06C&71fO9gS3CQLZvGaG-3ezAMX^W}C3x`VVy zy<7b33gg`uL_fo|Jb(0_h%P-$39)L{RP;yVgjABt!?D%00gOl0S5%JSB*p+$@dF=q zVQNVf0y3@a)gr}(^V5n@fzS|yzdoQ$AIuMd!RtA20qjW6l}b2cs#T6hPFn@$=MHAJ z5pKX!n`0%T3+-vO>}ed}PVyBX4t*)}5_&HIgFmv0j#SUyNlKq9kZgvheF|XYf-=ymzl)+ee;?4LPwA2W(AFpri0SJY)88)SA2xQGg$aYvo+{PtuO;_j&lZ%3%AWn2(4ZnF5b zJhLE(<&0Zaww#h}EH`Xhp{B!?TtR9N?9S!J#QUn;)GDZ!CeSFmQ@Aa^0gfuQQ4P3l zQooRRKf5yq`|Rq5boeRfGIF6GUC7xw0*CLULwCFNUkP%v(^Xb|alFF~6%%frjf~0b zKiIg@ngr}?#<(AUS6WrjZfOyZS;@;*)Od3t4qf|xw{+};houD0ng1mNlJ2vtzVy6v zy>U<-YhrxME-R#C4ACQLFWt7$J{EZ2z=DlxOg;tSj#I&+_O4_8+lmfz#s&@ zwGNLGEMN*{XU$1Z0b*{c>S0#BVyc@Uj@)?PyU$lv^9u!ZeX~A#&B#i8vVgHW8wTM>Cl98u zUTvV)yv@t0(FLM1p7T5AwS@~cAY(lEHhFG`8%!5GOHBq7E=2@*DUfh|m5|s=xF?~@nt{Uf5mh+6zx|}TM&1gtS0t^hrv>2L zKV8W)-yj&+Bo?b44?%(}_sO7cHdo&9;9Wt~1azfcm7C>pc0f5&zJNR9@!LilIIYYs z!BofpPck8UB4=s88niVk+?3F)goh3beC+WHY>GDfi6Ts|%IL;QtLuPZ%P1Ib5Oo;y z5#l)R6EKIH5&hgy$ML$D$JP(rM9I1H~cByg;4!+{N>o zCh@Gf0s#Mvu*xElA1@A>HzlV^^~7OB4NDG*Kr`@^2c$v6yO`?aPwyCQOox&p{kR$q z){eRj1lkjGd<%}wn3jw}RKWO=_^l^*TSyFRLyaXARel`vWbb}5aU&*+gnW|H3Tl+= zxwhCPs$#P>*$Z9E>YS>a2&*;$(abyKaYS;O$g^5=TFx8i&xSS4&;zh-7F$;k)Xq?4 zh2YqaMqV@{POV{8R?ZZ0x`CFIgOL@bk2Z=_=K|yPyjTvUwJj?aeRFE4+CUCA+z*Ty z!qQsd6pEoHN}cOJ;Cnzaqjs!Y%vHfK_&w#`AHSUz;^3U=1yE+q6Z=el_XPFy6luJy z!Ww{oyV>{!=2E1GZRBHFao)M&`sGO|j=1a2pC8jFIDX6}> z$cfa4bz+kyXH3KT&#ew>eUVkQ_8fyw0;-u36(`{>$wMBlf7JmH2~qoS7s9!*Rj{gP zZXv6}3CFf{nnJi>zvrv#CTQDWKjoG7KYVWIP`vRDHh*WkAIq}iAiA4V(j84V0%-eC zvHEmN(HD(Byk|!dDQykZWXSob9b6&6F`rbuU_#&Z9GC)nKpyb&`=3~mAS*r~5Elzw zSAYp=cP9`CBm@g^=KlQvk`0r8Pvz#YEb(P7_^T3xSIaU=>x;u_T3+-P~S)b5v1W^?mcad_u z*M{al<+c=;{Klc zy>O|eTj$Y4^OoCcX1I#joJ+njVYd$2ljZuFi=7PL_&MY{XZ^z)W(mALlDF!lo+28x z#59#mOrwg6czRn?R(5l&?*WBn0hdPd5B|k;AYA61oHF?PDiGc+i@8&0I01U6!0d8L zYqMkA*j~c8N%e*bNz*Ch$RmLOh2prnCtjO;PpDV7Zj$#mw+#{$tNZLyb$}v-%m(O& z2roalfu)`a$AWsM{$n(_#i~5*(l~8c&|X@OhLX`sUORj+>dFDBaT^Xedj8a8y_JQuBPVoJT2wIRZg6M zwdS9@TD-h*IoFeEk0F?Dcn>zuV*MON9-itCt#%CdkT!h(`Ltk5oH1*&vsb!{M_`eo z+^Ot|sQ^r2u{_}4kBy!Qvfe-}7;&oIu>S1`|7xM*MlFauw99q|V ziEaHh?9|_74}g$vv;eAWKPf_ zV+Ps&j-gQ3jiBX>R`aHIV85KcoT_rcZQJh zH*t*^7r0sP>M`|lKsak!E~`@(BM$&mUuN5PnsY_M+%XvCXTckLc_=!+r+M%`k+Yzg z?1B~<8i;5SxvT!XYan^O)?mEO1ywr_E1jlpPT^B~nGGstmrfgB^nF~Y^p`XZ&SD~o zx+zVd2!GZlSC47lQwV6zekJMhrN?t=p52wH4h~Qlbi3r_Eqgb-vuWbB9Fe_z4NjI7 zU({k!bh`sUU1`p93|RlrA7^rb$?_e?<0z1f2XbdDl^IwQ%=My@OGXEUKZaSx1iak) z%k^7_^C8|C6V~h^Tpk5n=p13AfBfx6YfCr+f~+ZG2XTgIM1~Ls(*3ZBXjOfn&ooG_ zsGeo$zXQUCNff`FAVO~YHa`+a9A68S4d4mBbRYfpeFT8U1OZ%48TU0Q&PHq#sS>|C ztUNd5<$ZU4%Kn+|1sV+wr*&a29>~p5oAr&k?w!x!?SO}H`&bV9`%WCEV=T|+UBtL$v~NcSi_JrRsxx5 zGYmM|?y8vqD2*v$2t)K^Kq7H6r6hO4iH0TWw&eZPWJ1u3I~i`*P%y#=N2wzQEKI$X z6Ug29HR?xA@XOgpd)CXUp!J{{( z)@o;~&cj<|F^l_Vl=m3aUFg!^Wm?m%H?*Slf~3#fhrV^*#qMF0<}*F5@$WY!o|Yb_ z;%$7RrM5f=Ei~9iCahkbs=p&P=^fK)SY(VRPJB#AUXk?gMt0&i*|Np6Ecg1+ACg|u zF1*z(LXIj8$mOR-v^;@H=I*8EOUb~+#6 zhe;ub6pRzfT4~9j(|_#*w?HJOuX|YD3A8YzC`gM2aER&+K5-#8m{h8~P1aN~Ra-Rd zWTBZMrmj59QyB_05St>`IF{`7wy!1Hq`V(WgRn=!F1=)D0;3mM)iUQ22`FDB^Rgly z1O82(er8HxW($pQa+S8ha_GS3dfkkj?~Y@fueDdH4s4F0w%pL=JKUGg#qt1p*XId! z@w*s;yg`sC&XThW0rM|*QKQzPAvy1X$iUkg6%=h9u!~(v$Be+PGh?}U)&|VF+``6m zyvo*+KEgSTxV0!*(L?NUAqo}ZtvkN6`Q7`S{1(fMP41Wz9#SwPOOq%#V8UZJA<`=4 z(k;Qun(1V8S|cH)^r5It8;iqMC`(xcez>Z~;oO6a6kq>0v9ao4er@4lmV+twC;1En zdge7a6KJ%n1jSmwbHHB@YxSG_K(4Ox&M^Jux+Js~M*{N;XuqJ$o)uf4-;^eX`R|Xc z+4wnl^6ck{wBfTLNvAYgcIOSQ5spfx7)NrWn6o?!DZ9p*Er~EkV|ue!?qo2kbDhwQ z2w82&3t$>_3rhck{)G${t7!ODI0A2m~p)mb#=4Uh1@xam{OmZgb%RLR)AdCzU zWGg6yGA#)jTl9PZD&|Bfgy3CLBj!{_VZ}q(PQ*z+TaKj_;9x|QCPFrvG;bH}W%Qi4 z@$1w!SHBnH-EKE!V;7t^)aXFzs3z@tBj18L-L7BgUg~;9z7D40rt=^|}CYi}~4H)0InHb}>>n{joRX zW)un%zS#C5e)%b*F_9na+N7o_+GsOkhhl1md;gkJR?0z8$#qnk^BoHpanJzOmOUU z7uA*99I7lhj&oFroX{f99RbBKg!=KNns zPYlb_D0S~K0Ewx<8$;GTf;U3cyT@ru7Rg$1mL;MY(R!bBg6{_&+= zob|TaI2wfrq<7TTH+iyRJs6z zgU7qpPD0fkkSQ$(x9gQwi)RZ_>QOL*)F@z*uF+Gea>A4?-A5Uh(E=rYzge z=JhVo$&4DX_Rh$FE!;CDas*6;=54C4);{lCNic0sg*U?_sweJIQEXs0w(8u8;6I+r zN8bL5mfV!Xq`Tbaui{(L4M&C{7aMJOfaiOwOMQBovJCq?j^ZhfW6}E~mXI&lq)w*z zB~-bP1}gG$4`~BfL8BtVb=4Y3UHu;g;bK6Qt@mGhqh4?$L>6hWdbd?fTqy|X7rN?z z7*4+5fH<%Iq|LcqV;Ad;^hu~z*?&Kvx+7;MaC4+F`Va_}Xp^YvL0s4G)FPAJV%Il! z94c~~jd~?r;-?*Gf8{-yk5w9IR{_aNe`}p=303;}lyXAE0FdW6}K@5*RWmX0wGB=0K7P6U?Su;q9K)u%v4e>ZFmdDmp zum{*E-1O+}x)(?#yE@_!YtZNoyd>sH5#H;( zOB87bx8q%?T2X4TH6}lS`y#>U@OC7@LYbfAZz<+H2d4+hV8*mQIV_V^<)P^a#@~u@ zv^b2-#mNBDO;G(5-l#~V`3 z;a7yov^%c%Q+v%<&J^i5agO8Y*WogjxOR90(_n?v?-HufQO0R2Fb--dFOp)6B;s=` zj}D7D4Oz`-%7jgv%5)T6TY54y*M&F#+@M4Zzq-ItjjH4m!>>o|J(gR4aYLtm0*QH$ zb+g5)=Y=8uzPt|e6SG>M2oUe^Vv~#hJ%3f?og|$7)DOIs&m+;C-Xw<7^O#u}Q{80V zV-Y)1`&wqJDQ59kK3^SfIaNmW%w5UU)rn9|ui`nR7VciD%X=p5QKlX1yPi+h@~ z6(6k8;?IQ>8OeC`u@$R-L+Gf954M00iiL2g>6O1Bb!ds6YGLUWMV$`=U zme?tucQ$P262(+ZE)|pjgLP{k?UxF16glb_F^-9<=$OqscKN}N24Wi(kXEm(*NX## z-9?l=o>P4xxkk*f+)BtatHKbbp^)OV1!)SzTlu0grBJ6SNa~NHrlSkMJX%Rk4iX}2rQH!ZfI;>ln}K{l zjd-GwuB-bV9`1OZFocgP(pVn756QXxdJsVh_5eh8dbFT{dLTXCC>N1}boB|vgRloi zl^GGwv=>UkJRHTyjy?(r$i3`7VZ|D_@8B1#q4rxXkGTvYv24nu!40@=Ft}LOWl}0> z1V%Y5R}9n%eR9sz+UchiWi`ET`xL=bXZp>%AS630+*Hr?{w69o?QwrqES7Q0lP%@YxdF<$}^>r&7etY$&x5c=7^$yTnu$^ zs*}qw34TcrI5sm6?)rAlRBuPb?qb31&@Xarv}1Si8I+}=o`h;5JNh1%2Ys)oi&5r0 zJm%(~vXp6mh#}pSgfo|F!iY~=Kd|&Cswf7{(Zx4WfkYEcPFK7_Or9oSxCT-cxRI6r8Zf&1i9U5VBd`62?s3_OaMk@)MhMVQZcEShoOFxxRdKoU@m z0>!9gGUJ1wl4LEKl^XLmi$WE@?YSg1+6MLxISf3>s7#>D4L1>BG_c0H&vMO&M4W_~ zP|0{Zjf1edr!|oLuavx*y|8;cj0$oC-M2>~b@^cD#@nB*l*|=hAKZ|jUwI)Z9>cA- zST@Cz3*TEIy=bTO!TO?#sm8a`i?nBBB--4iV6jEDSehm3g0s;hsTBPDO*ydHGRvb6 zk=IRBjb??5vF$7q>KfcjtbOU4kA=ZnTJJmB0UQl2tD4gxFVI(!%@}5eGj#Xt$Nk4@ z-nEH^eJLKAnHM2AzW5`|ESI`x8XvbbAK6dvVA~%fypEmq%hh=~e;B=vPEnV-7Sb;R zQ&V}fPG$1l^V3SaASB<@Dv)Nd>M*Ixn@t&kqX>)bdboj;o?p&=oGXQsExoWK+287a z%3NdNm<`koq`t47XU_N*Rq*}t)oNAn+&*ikI{YH;C{S^kUw2t=SlpUI^TU0Tun-2b zK|nf}7&f_zi-<0Ev(e&LMHf~uECqmhy4KmeQEXb84BNoQdaw;)jK`wEc6z zhGVEGb4pN6!)f3<1^>8d^|PCdRfBm}lm>Fo+CQxy>_(hD&Z)y+p2jI{XSenvm=GID z?NAI1ysSXE?#W+(5%!59SS^6DHo`b3E?JoBiS?+a2jmM1I{fVr1{qpHIHqZBA>@-K zbHP;*yyiBV;Bsxm!Nt7#v+F7_>B=IB8&>m>aX=n7rK+q~{d7ym}tClRtR(qVC^i+U&yxsri^^O)n&cqeoY=Flgh;U&y2AGoj8kkLxnX)>Psm|cFFC(Zbx1RH^Euat zuC>}BP}uwee;Vfpu%+O`dhXuHls8-v2$qX&*^R(LF-sV9VC=g}cn9@uSgH6eBq(Nohx2lLl(LhQ z3gu90~2!Ml%A|27HIUfYleov+gJ52L-h`7(koA9>^22qby9dZ&Ok>)>$ zW=>)mZg?ou?37xbSH=#+h#Ti)40A+yQ?Vn6J%70uA-*b_jTp|Y=Li%UgtLqZb_V=X zn2VomNE*a8D3d$wj71@H&Gc|3h4hC(;Juc4U!w2KsAb*)+anub^7mM?hu?H~n%dwb zthMl4fj^R(=I{ko5>A6{Uqz;c79jXNQS^WnPW8)>@5fFvl3qLbctI&rl`y{5e_%7M zrbi)jswVOm1Zv07$%(A)+^t6?Ab{CC+29qAs5}%4n;#>})*swv;ZVoEwj`Sa2S|m8 zM!pUc0NIjinENK>312JZ3@%jSH`BtoVIc9m>@)1`-q>^WVI;T4tR1xm^RY3ZqtWV zk?2Ed2>eQTgJbXt-=(S6Ii&s;4te;BgthWfo`&tb)0~cCkcbW+w;X_nReO_>kUWBQ z2W5Nu97$5^lM^Oq1PJ9s-M9$UWu`d1mNRe7$RDc>`O5BvcV9C=7ls{@9IAi z4s9YKP)mPZk#htbyRpEKgiohi(vkb4B@Fy}`O3|S%w!t&)!5)qJN4o!t?KlDVO^8Q z$^DUB4)4suw8!#3YVM`F4Aq~r{B{)1SA||R8xK}z##=5}G91r-`VxbjbG#E`bg@CtG z_7~d;E_A(#_-6cZ5BxM9(B>8r!cGgJ9%kv^x2nd45p!Tqgg`9j7ba0dj|%t}+-lse zIY`<+hAn2FKC8*9SthsM;}#W^hp!(p%O1U)?ni4H4v5ss*IaP0xjCPg)9->0pD(QS zGZiXT5PTUAChsSck87=WJXd!r$WuVJrld|$pP*16)!w!@>PbVb1F@M!BH_P2ew~*@ zm+Z4Ia6~%)sV&^nN0A=uJ*HtZ2Mqupy#Ss^+YgBrmmtP8qhAIPI+oQl_qf&ig#j05 z9Lq^>NX5<#OB`OQPEM&Au*70`iKp|3!%8($X6JsjsAXXxR+W?5v2!VN;W@BDvE5%= zjuwufo!3Iss`w><2Q`Qe*-^|mfh7oZ>H4z4QRtO}IWJ2W!>6S&X9fk*x|em(hF@## zoW3gxD9f_{ZdrJvF8$4an3~2lMBztaU_^Hz2sDY#Kq`N`)~ghBLJkkDhZROfy1ALV z97G2#9Z62CmYZd39faP^BrXE)vx7G(4b1jWJCud#2dYZ~4QT=_1! zhuRptWb`y-cS(7?-*n`%2E=01lE@!fbXSYRbU0vI2>a>{glFy9#gHfR=7e=aUOgro z3J?Py=F)P13F!RD(wMiuF~hSOr=48(=wnqNRDl-w?<#1rl!9&z=~x$Ysj|^qBY(qE zMPO)H!MbPw*~NkiyMCz*T30(!!D8qBUC@xMh z%CyGOt~b%BM*mJ(wAJ<6c_fvc;Ibsa|uB==*GqnwbQf3O(^3W|cOEZ!B zPo-)ons#&rV`T@?=)|g$w>0{D!;7jHn~Efl8EXL`E&AXKNa+D)4EQ4H$X6|sgZ~q? z&H2Ca+y8IW_P?O?{{puEL3jTjz&6YO5!hy9<@|48n~{U#-xU7=wwV|SXn(%>fwh0$ zjQ_8|Hsk+4z&7(g*z*sf{tvMIzX4=s#{YcYt1!A`*ZZ%=)2 zROmkk;r|>Yb$@>IUzlFu=iGmD^8a3u|2PBuFT|UPjqwND{~v_+e>2^#!(PcFhPV9X z}7a3_U)^=)Jpp_;pxtbG`3`3ZS(?#DZwE zcT^{tVpq!1#xDYBDyA|g4UZ=g#b*~Dr#ffwD;@e`j#q*P&3;YVJ|0itkEk*Ahz}z$ z(pZ+>n^Rr3Jad2hKe|4-=BS2+ z%A#L#95X42kP}73TaMN4)5Emn0Vha9b9&8civ{0nX!*k@fd+*c1lK=NIrg_S3#aLp zAcD5&hNj9c0>BwgQzTojd*)7Fk{Cr`Npy@!-b8z@bCa5RX+`J80jjbNeTx@>+SbaM z8DnglL)=X--fr4RWaEv@6gZ7v`~(IUYI5lhV_*6!FZU7%&Wwy~QZw2ij!pqXD^ygE z^zi~^Ushd(7M3jf4UbGo$0Yz8wt`h;9TJ;tV>z^j>84Eb`EE=rf>5vAHlq{7^iosn zn5gLk;WZn=A?TL}t22+s%mlErcO~$f_9Jt^bNSC|tX&>*hg-33)@@-kl&bSkl#Ek)VL z*G>2UCW2Ox$9rkX$qbm+9^OsbCvEAlVX)HErx?HYH(FKtskdh$*T4U~dyrITyDjM- zvf~yts5V_JG*s@!vkY1w-aEvV$b_O5rBPVY#~)!!>aHkq=^a&a=BRidY9^kQ;HUGc z`9v@hV~X5o2+XpAdj1t%f5!YY6+u=HDY>w#?kg=PZGM|FESII&HN4-jG{LeO5Tk*9 zklB@OV=uUT8M;s2K1VU8UYc@DsBh^dOCXj4T(YY;-ja8UM>cks>;6FA?Cu+X3to1$ zp-G~zU<8Xa_1-fKglzV+A=O^z6GYQ?9?l88pSxmIXEHaon5$Td+O$*cO-1n^hGh=G zm_?rEplw7RpQdaN&d{{y#JLM+mNTr|>n26Z5nl8a8_LAdhd4TjoY?UqkwA(&EY&GP z)-Cx;idJlLxgaO`etwaEcMjfag7|ZheOm!NJnlEy4Ej^Mp-N2{8XLhD-6O0ExkiDb!uWDYpQV5Hw zC6+W-8l2unovTJGr2;cug$ddaL#ia`-34ir+>$&;&k^J9r=q1^satrXiTJ}<^)Nbl z$%GXL-dfgAtNAQv@7QgDLZ1|1OLF#Wj@CEx7Rey=&d{oq&fM9l6D{KL=E<-hN5pMO zbGdM`IXowUfiuOa<27&W!^}X)UQ#w3MA2I6HLIG$aU}0hrAC&^zk0IcLsW$8#eVnA zn=d347Vpc7-#T+(Jif*6YMiL?reS7@PYmZCoq-|9)j17ef{naXniunelB)|7&dI~FZElxaS^6uZDh`(;ARSnGMOtQFgjWAN0tEWECZI1 zs;2s-DpDDap(wB*CV#CBfSc%Axyt0{?Bm_PUt)_fpff*sCarkMW+8UU5e*eDL>ns5 z1^xLN9d*4A{UQhr^6)*pH6eh6decr0N;eTM0bU=3kJr@+Ef8oV6$U$Mj3{z?c!lWR zjzSuf=?SxiGaUob?KOT&^|6HB(R`i&vEV9jsg_PKME?%6J3qb{YPpk@pZ^&;gFOCzeu?_QMTIO8Cy@1`?^($ViTBx%Y&xg;I2VSAWLse@-TekyidYtfbmMH z>1AG9_|}l0XWGVnJdw1o5d52cvHrIpRn^YveAzMgd7jV~CG5n(snq+I@-c3SGpxNL zZqp8G6iDY2e*^_440JfN6b4xkr8o8L_9W~pD@BlK4EH93*zMU&TLUT;s6dAN>C2#uO# zjV8B5C0+D=zTVENLh4cr&z_8&0Brm=B_?01oogWpM!rr~{%53Y0XtlJ!I*V=rZAPJ zz0W$>az@KRcaVpVxq7}GU&HB|STt!3S_~ul^%q7ZNNzjG=@X4!H9g@Zt+-3 zr#eG_OYP5I97G6?($f<|=E!`7A$aNiz{JBhDpb{A)N8H8T2Y>u&PR z$)%Nt;rhj?_e5-T5m!dbY=;QJP2RBaMA{K(@`vP@)^*cdLNUIYb5fI-zWRo(V=S`n z=2__1Y4*Y)(OAE8erBc9`7B>=cktbw;Itoyj)zh59Dvzg)Wt^DHi#{OEgwz@x*4op zy5Q%G{8u{r-&PCz0cSa}UxB3@PG{HtDRZZS=wVS!m$zF&98Gv94Y*aBnKWzkkt^E2 zb~i&WKN1^jS?O(9aV!f8X9LGE$udjT(x|dRY%fuGds=SrOmGO6mXkPJ3NGrnuEg;? z+F&c6$D}^+@cx=4!z@#SBL4a)5`udvG6zXa?sQl+cwtnyJiuJCjA2)|eVl4*BBGLP zw0nc$lILvv&|p2O7y!w0)8qXn>k#&d`?bt;8j<#-c$nO98D8Ny!3X!edqSdoc**O6 z+3u?Khr1qRPgLYNd3)0CN+_l9yEIIE($GC`24FV0Ub1YyW=k)A)lw zN3qhTM|f6jcBi$hu+>=?(jUn%oFsJZEUx$kvSD16DNyIU_St) zbm*hi8md9Q>0tS~=|RtdJ7a)JTUhB{Ko z+tx3;$-ianyAFL)g3t_2;Pi7_02KXx$rSp?>T|?MyYabj0nL^RO|h7rW%Y3s+vl;i zkxxZGl4P4#eA98YdPev?s^}scU@R^V8xzThy$eBSzSE+`OA)M(t4bf!Bu6pA^I5#f z^4-@6Jn1?4vQqQvBSmhtqAP-6 zaj`K{HCb5p@YXQ$)&F6V^RFQOj{sG6HFEin-IJ5;e;E$3akBsTO#Kfv`r|m|;$-=+gh+75RTDZFT}ihJV#F-_PqmTKIp7b^3oNJpZI% zXJVw|;3Qz;V5VbX`;pB5wFlz>T|zZdoa9Tok_sN`AC|4lv3zW5YlEW#&Y z*||TP@}T6%nxIfJqy^$GR(Nt!x`yiCUh75*t{@%;zG|%PjH@5>X>|^LI^aJu_w3cH zr9)vLtv-fo$GpP;Dh<|^73LH83Y-AUhWfi24lf5 zYfgGZ53oi;v!!SU48@vO<2SpC119%H2paLr?fV0L^t^0ePbBPdm-bb@m~fbThjf^XiPT`9zQ^)LAL&(5Vy74s*Msk_#G2Ft*JRQV#+9(B{(dD0mqec<$+(hk z_b@d+#w$3JLXhubSh*IGL=LS4I>OS${Y6EyVbRE(^n$-z-X5l3X-Jy%Hpv%{&IDR! z=g@Y96i#VWr5HS&%{~hBuV=ZNfOvGw7hR z6B!)aBv=|C2k6j_@k4q8QwG9>KCxakkugRegEV@P@YTt=hT2rLx>S&MN>-ArT>RGgS1 zyIOmOa>F9a+3PiFm6ZJJ@&$V5@8tf=r>}y8gV;X-* zLO$+=z~MfO*=f5%--OVXVy7;LsR?8`h9UF8jXmnXSsSZQW;?~aJ=VXqMlC8p6uE+A zRo3K8nG+Jr*ijlfox^*JuB{+rbuJkC8jOjir`LY{^3iHzt0mSPfVrl2O&^C;lVppR zLVGL^>~d4&i*;W9+1}scgEn@(*J%eFzlE>2%?`P6~kdMZr2*^))&@fRb03FJIV=*xXx(xt+U7dedAp8PzyARy z#`d&ff2e~&Y7;?+7M{{#Ju)+9Yu2rqI1%%B+y$Qa=~@8ot32%d#aq0~QfD!}f8vR9*yCv5aAFG(%PC^0M}B0ig3-rMy_q@x<0E5ayzOLo4L(~Vt$4QjMJin&kdGf zs1l|ls`zuTPq5j4h0C&K8v|sBNHj&xSe*Zq zrKLL@o_dI#mk5p0g~ap$zr+2Ir=M#7TvXW18Prgj$vgiq*Q^gc3QWEHDcK+SC|a*+ zr~Zp1fZfWAH*6ks`;PWc+vHqZHY&}+hrdMdF2pm1aOud@CC@9Pc>M-$wcL*67{bYO z+~>Y)uuY!`q*@`5P_X!gh@BhPj-2A>*a?l=MSvY-H}!6Glbs~vgM#=M27#1cdW$GB zux~(}bPRyGv60QS_v91sxBC+}YDC*5tzc^?Emjk7mk1L=zg&Jx*e8L(rI0EZ_-Z{E zf!>rtSSg49pBS_87#JNQu6yAtU=z#9On2_5)lsuAEyL`TqBCd$p#Mda`Z}cepDlg!mF*)VMhV#8OgB0`YQk6od zYm&Xq3I~f4AAp9x@tjINx(~2*OuwYOhllSc5FYd+ajwW@Z7IK-Cy?2pr=~mzXOG~X zL&Pt}x_~K3RhW6WqF`TiyLG9gxmxNTd_LZuL z$&ADyft`Uegeatg3oPtm3^-Q%813?t#4RQ`ireVImdhJh(JEn+Y9arRXLsc_Q9GsqdSzmJFm#8Py=S9-T>z6vU27NVWS|;2N@!2loB! zDBER7o8}`Rj&-p3tS&GlsuI4Aw`{(^9KrZK3Q!eW8)^x=RCM3Q!qV4-g_QYBh~dk* z*zo6bDwIxb5F`T`Q^Td6(`JL(bk$irJoe!QMEl(SSbQVue zlwc{a-o(iJXqyjbT#BRiF1e56BnR(%FmV84Ei z^C)R~Le=le)R?fJ-MfW@Q`B2=Fmd)S=z+;nt;=CPx@?s1h-`!lx&(&gGj`GtGt z6XSN|Lj1k!Ex}(vI*Rw)^HsY@K`i*U2?ct*&((#>nV79iKEeg)E59#hb-_QoX~(bQ zIZQB~lf4t!S)pB_)X5A$LOG{;(a*=*5 zlZp;7e||@i@dx$eF!WY5oKUHo1LB*34NNu$vL!ox#7hU~6_2@8&nj1pZx9c9+vEE| znlstNRsC4#|II0{)L0A*+3-s&NX;IzfK&4T4()~kM`9)}w4hFjWj8!9JDFf;xxKl> znJ4Q+GP1R5^?rvBE#5MX%qgMVgMDtV^c2^quugsjddMD>kwpv>2@9frFTj!)PD?!S zWx+ObS6Y*|?l+2s3@?h6Y3GM~P7Ad8%emR~Bsw+zL$?qVwJ_grqLX4g+%g4Ko};@z zhS7)ktDkZ0uy$0sIlV8A)rLQ7@?QxJ&=9Z$(;}+^7Rx*dHM9Lm)a+sRBbV-*x&%&j z5aGseJGXbNvgLHV(~O1^u~mImKxZ&;?=NfzK-NEMznO!%Y+vMqp_mVIaRts+wb{~d zT;gAa>@l2F*$W8ir_C%>?HzqF?_&IoT=JBCV!&WN_+Ae4BXlXuSrJq8CpO5>@-0oT zRkl2D-B%&#lO$+zt1P2Vf9OuhuyC?5hBG!1>K8p4lRWax==`CX=XPL_w7;mcpWm1Y z>&hi`IvTsaM-_F2bNVut68sPM?N>lp@e(79f}mmy5g4z!k-_A>GiF66BzF98n}CSC2`-kt1aMDxFfu1#J5kk|nzOJvSz(-!FOe+3Yd?=w6XF?1_nggG zo+P|vJo;J&)n%SOHAL*(Trok^zp2_h+i<~b431(djUc~0qO|dC@#peuWgNqKqJdnr}x(}w&X?uKv#=jib z#So3#T`jLjoidE3-YepLHqe7V=)neM33Mwk2>_L@kXde(8&j}&4i6{1Q;Cl=5FIRK zJjdI1vuVR$XfA_+1~(Wipg10%wW6IGX7baM@oHUL_uihe%&`>WtwLRebudXejdSOn z7ObH?SG;&Z)0wz$8;S9?Z6y#q%ez}8sLp0L)&*X7Ggd>P^M>8$**<3m6mQy;61TCK z7-)haiz&UzC*Z2ggAb9@^OW2G3jqh_50Dpg@pK8tRV)JlXDk7{%U9X7AU5JZXuNpHQ>8GuBc z6NixW(zl);B_!SRWL6jsZokIzU7IAn1dph`mgYDeOX;X?z!u1}62~qN;Gzl%(-YLQ$EzCEjA;>B zb5{dQjH_gM&=ZVQ|8!G_ED~)p(FF}B8t+D8SFO<3=>?{v4mA3iItvLfu@#qpvzwpz z?wfN+XgOEFk~b64+_(Y}5uTDTSp_|qvjzsJkT)6@c$}QVA;{fOxAwJtRvqCkn2mIj z8@*N+hF{P0SBwSpnuD0y$&2C0zN7`q4SVt3u1{$V7Tk0LF-ks-$yR~VN)ae>OThzK zUViq_Ld0x*tk~Jr>|{@2%Mri!W|zrOUl^@XZ4ZtkuFF9ddf) zCB@ta;zsFfHCrzku*UpdPQ_1Oavz+qni;sFfw!j0bstvRMh)oTn>H-ogMBiWHmV_= zpEj=6Z-HX30$7w;jc?RfpV%CY&VzeMfA=_wRLPS%SkbW^A#P5nt77hX? zGr`_6;#~vDX-hyK7UpkHnhcu6qrz`j)l-dz=U+7opuXYqSmT8m(&#wt zwJ#H^7soL;9Z{u{=Y7e%AY?#t)g{;V77@I5oti<;5|r#+#}a;6UYnZTVI^|*!j z$z&-}Y}4;R1C-d+#NU+L=R~QSIQpsqglTd$1qb8FE=W8~dCd0%#M`wrEL@KH&&ZXk zaOTBDwHBi46zn-QEd~rAXT9|wVY_?v8 z+Hes?$pw&uI4K?O%hDL&SJ0^}vZI;|mKaIvlLvTR zzzGI6PN^Qp$=egN~^)^*B6pr0&u5Z zy5>(HC38k1s3MoS@IJLdqt!BRqNWJ2_Km?WZ?)K*KN{N}uV(LfaR$`w*kmrf(ZrS+ zPO%dAsKqGtJD^}8ic`~Dbl2RPj#-nak;GGX1ZU?r}5X`f+6@^2BctUsGp?Lx;W% z1xM8N>TKd0(1G|*61~rUpE@E`ZxUT4N(pv!A>%!k%e=1r+xS!^69;V?vxu^GEV#|A z_7n=t`5X4M!Tl`OtzmGA9pT0kbF^kaB!c)uz>+fFxal4T0b++x&g)c)5_5`Aw7c*? zQN`vLmkZ4qvfUq&GjZ45Ppw)fJF28!f=I(ZsouO#%j+cR3#UnxyX0f0-cnFVRaAE% zs_*_R73ZgH`tzoWxsvvSG-o%(o*QAcDmMpw4IOEGIgfX(A=|NxFGXqnByBi* zCX94D;xidF2kd4l z@^O;H;og5v%|yrz%UE_E3)z~F_30w~(=?Z|X-}>AcR#ha8-XW{QZX2RJJdZvyCdq*SKX&33xyYMcNo91383feSjN|jEdQQp9)Ykk0TOC$bRW40L zMRQ^HMY~HqI*j8gj2cl`Jd#@uiaZG0_IYy##x=Sca&f6ikf0_(A$Jve0Efp%O4ei_ zuwJTfYsB?nl(6Ss7(7{mq1Z1OZ6v#EfcmUM%+M33pNl!}Ya_ryy8@prot>+(3ux_f~6m=#@A7tcdpgg?zuxj(x+i4=LuBMFkJCi_nBE`vkYBr<^XB2-e zMQ?b^p2tlp0$jRpx+A5L;-fAXNEfR2J|gBE-M`@MwhQy-fjXF+fyXa#tlofBD^;uE zMnjRpVvbojt0;&Cq;pSEoTp-@AF2IZ^*6V_E&_p5^(yoKF53EJ+@kRzA8(A9A7FtQ>vd|W;jy~V zrayJrBNdQo+w9+6jI5spEZo?)9x-e|ZG_CfpPn4xgFScP!S4BrRdeX_4SJ#8xAjTp z@-^g*MF&i(c9)!2*NmY56*Sv*YUbmg@)3j!@~o~ox8ZKd2&XdQmXNkQv4}0M!`1qr zqHwRz*E;@o=2v5K$@`5+25j3JwCS(x$TGwHMDMxiSzfB{v$D2ph8m}N23}2Hwopul zdtDnrakd$PZ&ka7b{u)U6uzWulSO6+QY81?%V-28YqXs~nq_r-)rW!;!Q z0u-XP>@5YS!HzC3 z`p6}?C({f`WgYXv3^VLDI8gk4nb_ zuCKTh?`Ts~8qXjwEA^Dv%Ex`4$nUG>&?u{qaYIA|H~IH}Ci(p((*0fX`@eSeF*E#w ztMBj2Y5wP2eVi-=%zyXc{TGklA64=H(Hj4+Tz!B3|L=ME{yK;M>g8i(WBw=V>3`~) zKs;GQiw0oJiIvmEKdT+Hxo3p1zOnqjGN$-y45rLN#rfKd=G6dneBIR=_%woxd=TLR z%N;wj*61e?#jZE^ahCvw?pM9c#AD5=;j^~5oU%8r#vSjgi-ibHlT{!#A{xA`Q;_Z; zufuR4gdp7YPKv1IR61wF8xvJ1AgCKh6z$? zurL8tlx(>e7l4oFBbgY0MGLjN6&wvMiBcQrJFz`3<+0sbtdD{LW@Q5ejV<{SpHLpa z>D`TdXHC>h{MA#Gv7FfH&dd*FNF79@LizEvB@G*587VazvGEu8Fa18%H_%3X_>Y`M z^cd|3#5UWVvhD4dE4@&NM~G9u%!-7NG;;u^R=3XV@EOdYaWUR;pgH1rD7qBI^xJ3d zXI`2T6dEok0(|J)RnApo zpD>LW<$J-%v3z z6=NRYDSaYaly@fbXGTKC#qA%xx@!(DE<;{^D<TfD+}wTwCHg{>^6cfz}zU$aQqJ_rh#NO&ZBc% z`Of+};jZ6_!o)XMIsvjKX42eG?yE@nO_%^riaS!g6g8nno2w|SSqj7LrRqH<{TnkL zHRy||Lv`CP{_%u`0N?2xlz=8e0Fm1Q3e=2UQWA~f<#Y0Qpus}x`ml_kfCVDsBsYwlXC9)-1+MQqe;!uFGnrU5-EDWs1e2(QTD z_TA;ucFp;<&jBBejkOVmQj`NdMa<2}{8<8h%8kWb#in*;hE{PzTM3={kL(l*?XyN@ zqp0P@zHC@+%mLW$af`0sEaHSb&bq2v5#R&dNI9TA=q=|0Z6W8Tb=wP0qLBul;O(Vj{VT_}p*;xDcogh7@Ee29bAv(1g45+GADX2;J#jP=1dIg*WRNnT zx~a*K5nx-0Ek3->!jxPq+H>_|a>XRSw0`QAGMh#*g**$K0y3wU%z#7}={XzHL#6J_ zX&F_`k8L+dy(p|Fw(@uEyLy3KW;26Ic;71#P~P7gh>~jnlChRi#R9%Hf-0p9H6NOC zshh8>OUj+rq7@)KMUfFul z=MzA;+S?N>fnCwetND+xhI`c<4$*J2PLDPn2CN`Pljg~rPZsGqw0kHIvVu9y!T{~6 zuL`gBFB0rsvFJ1GIs*^k@TebIlKkhNMm8ZoitE}1@Dq_PsSo%jkK$R4LqMs{D$l`L zO`q7_T%DR=7gqr!sGZ&}Li6IA{Fh=U!9MJjX!~0q^EU~oqEem+9&PACS08C#&+SY$ zz{$#q6+;ach2f|9v(7D)`O~IO!^Zl@rLhm8V-UT8+O^{DNtumfVoxq)J@%M|7y`4^ z$Wu-{cMq4@6h?*OeUi6ChDcDheO74PjW*faOrBh|r?xvee9~*^mNKo8uGmu?&ly7b zNKF>4X3%);bkD;iiZoTiMyc3YRGB{THm3GR6IUb$ud&MI2!Ou5!}P`|6V2XvGNx7h z%V?B-(sH|YULFkClzJH=JXj_nxb2nzg}Z!5lHs8@_;~9yz!EjE9FO>esCYfcC*T~) zlU}O~toKkucMD8-y_&fq;br9+t(N6fHwa9TU4tv--V% z4k7%8mt?oq_NTd(qBeU9!`N8DlbFDkF`93)2wL1Fn{2#NK`&VJ(`e7URLek#uo#ce zp?x1v1H=%q<%C>?ixBU#%E{aI7FS`=H+`CbRo4gNPC}}$Q62-BavkK@Vi32g19q?- zW~?4oV2F4M&bHQ$V=Xuv%&l`GlH9zOvx#2F(yrUtCrX8;U%>kDoLkN#%AS9F*~rII z9wOlevOn8YNv4Yxxf$bpvG-gm!#78w(o^@6KdWsRjl0` z9Lthm=Pjn1CU5?U%TJl|)vKRw8QuDieI%l;#6 z_K!&P|A$Q3U#IY2aVQ(pzs8{y8J~(5;0ZLh$DRgS4&ke;@#Ns~Z>+&tA^XeiaE@ta zn)TSZkUpFB@u}l{I@1e;Z59c8%6BI{zOXVe=O-iWwqp{nvAp_}v&fZs&g{ptCr2sz zb!G?AocM_o`Kr%Y5P%_3KI_ZDx`R=CJ?Qb_;ta$EmFe`DTMhWC^-KQty`A86(+cv z;4{$GvpBe6MJ;C^G^@NDGYzt-oZ~1Owj36_9D*iMgX7*46%K2w~UGIRB2!vsavUL{-Dmf)~zcBe%Jk( zAoKK|kO-s!h`_`{WY@WSO>vg6)g+x3yo*vnOuOXh z5&G!5c7bYT*YIsFcFJI%1%BH5vq8p!B-vG-JW^H2d7BSKcs-QIxNq3$IOQs z^2C%PDrd_3U#UEyefPBUUi*w-N$`Z+2s?;-T%CndS#FGS(e-W?%TM}EDIZRkF z6$iB6We>cbB6s$v-$oJN4%21S`@%OCAbeC|y92trXM*k1m=a9GwF9-a)#h1w;htLG zq4sw#)#&>}@F=@%Eq#!?@%EJwq1@=5rNoet+J@+%3!3K*$7LoqeLweXdy`-qML_Nn z2Aze;24$o(Zbc@_!%2%hEm}{&Z^L|?RZF+QEM4?E&<;l`JCR?KCvTmxIDd<7dU_>< zxtS~JN;DB#bIi>6$ZHY6{`toJGL4AfzP)F*+>V`qQpWB2V5LPzMH<^bIfb@&X*x@jZe`;#DvP=kcBUO%ab#@S^; z2!H~N<=fX{P}4JjXIb%M~Xg?^YcOG0;Isn>nZb+?g!yj`V)CO1a0q* zF*9d%wLC<^j=M*_sqExw$%{?p;nbhw(DW z*Z1RJqK)NZ*y#Dazbzs#pZBvDO2Co>uM(1AhCqufg!F?Zz2(NH?eT_2s)0{>&j6!Pm4dYn6nE{|vMRL-<2dL)7vMxxU2i`~)L#%+= z^yZauaW&*v_6&*CX-4Zn@Rz#))e)cbawi8#KF{Q5zsM)`?44)Q2@^O@5$uL&#-F3v z45yUDp_)@hTOkBL)_`hK1a?~VNT&#LYmHRXYCqenqk4kZgrdd{JfXIEn}j-1sFW(p z$!GvGpHWOjAGaa;>oXwfl?@_xVSFBZN^9SlsHqM>yj6NVzxr1rifo+LGaiHw)H{Y~ z%+bUjlqgq=_OW9F2*0QyfmUf+l@%q!1ESSvNPgy%o6lC1jmxqmE|+znxn-<3CKP>$ zIDT5mZfVHi4DjMkp9VtrG!RPojOXx-k=q5ehp!Vt2(fGTd1Et=FUoS@zaEs13g4($ zX!?%Bqwr%OiY{CVv$GLD-<(QIX$psfL;DV&cW=X-e8}zovM!m%bzjwonjaRwv*e=(EaE^lfFcf2)=!;loA25EyvVyFb8^_5mZ z5_^z`RUflGWsCI!3P&Yq>C(I}w(m;a(?36QxV+%Rf2hP?nrO9NLOdD9 zztH^tBmoi$`C}ecmo0T8X4bei#;e5gRZIay*Sa>HnXgrcf1mSX-^J&?pDOQc4{p9P zg^deLy~1@SPVKInDn^iCf_^3XeJmcA`#bRB&=rew+@-4^cE1G5bt|RaMoW}0dAv{%3tcUyF-yyCR^eL@n*UDp7M0n1y%U5mpVda}#HdT=f z9><)Z^H+%~jp0j9TN)^+rLRFurjdI{b_<=;$)*^XZ;6Kfjlk^ zj%k8_P;2O$nsWu$yhVMneV(n5%qsUZlGB{w7M{!;QlOz+0^S;ERCVCAB}%3=kbb(x z8;#4-ieIk?kU40kx(Cgx*omMR!IHBdcBWB?o`Bn8<`xfL?+yPw0aZ)$z}|FHG%4vB zmSTzZ?P>Pt)1=~|%X*gP7{p>`R-xub#>iiAK4tFojFvy zYqYOZeXiQyB}kdMf;`7&21y4G;X;#jN3;I+*U3il|{ zx#08gw7{(~HtRXI4vM=5L&w-&aBy&qhHm{$=i&C9q(Tot^6=}&+SQd801UIn?2w=_ zj_owX0RD@z@wc|ic+$Ka4rBiaJogAkpvG>e5@{TRbo^nu#hprFON%&>B{lLgE;+*K zY-N0MO#tGbu39MsGKuq?S76d$?kc@I`2hx`&g{Ysh2D+U`w*?$Kvptew1_3w3;X`96?G*Q za;T3Bc=v(yoW?InhF~f*h)A&Wtp>9rBy$adCGrlgSwzF#Ih*+FFgj1&c`Osj6HgtA zJ?v`mnSpwkDug+)B(O>qol*YXBM4eCir0($R_R8CEjn8TKofFfua)9PIk`6o+ZA3l zBY7y}k+vRs;`dRq_p1n{)6Wg|Yq-Wuqb-YT)i7O6Yzek&bD4>!j#G&>Vy-1GO>mKSsTZTQ z=76=8PJi~5qmeS}Q5cPLqiX?lphL+T^P9@RkHuV;zSkI9O_U$+sK-Yn8|;?j$I)eE zBP4*am+Qc>-K=|1-#BpuY#LzCn&~@H35S7dIAv49AmwOj6=MZ`&iB6_15gH0aiwDq zN>VKAkwDzP<9m)GtECHG#J^=x>yN7Aq$)$6>*#$Vf|R%A1kP74L~gS_)bx31uI&Ze zX7wTFkBMj*)e0q?zGK>HYmym0BIuV#Jqs{)$w%wAQ_K{aWW2~)tlHCjalcgA;XJ!~AT+g2!&zlk*%f8+03hx*CrdbM^_1s=_4gDMY@ z3}{8m^6I_38}yO?t9(ehETstc5CgJ)w#) zy%^`8eDB}*mw#7B|J#B5SN?*L`CoV9VEA&N`bStFyDwH!FZRo+o>zX7WSCef1MuMh zyFDR@AmQSXE(CLam%ppRL3)lXbDYJt*4})+t5}X&QHVAEX>eUk7lR?G;lN-Ae#B=c zn&=sbBHtI4_!t`3dotCs@RSR5QV!c}zNYZo~AgrtI7L&o?ST0OYJ2`o@@0IaQ$4T z&Z)=GB7p};VV2ZR=}}YpeJAK{S)jadQ)fb^G73xz^$E5y(5|p3idjp97mQ1%Je1x(X*&iQ#6?F zW)v_4eYp%g)K9}@9#Q-@zQgZ55-W~A`An=mSf(G`8zsd*g7zfZ>QxHVT_`iM=nrLv zWfWphNquAGNJX1`Z)${Yd^KP%5B7-gb;I+;@4 zJ`nUIiflOzYP{~7#ti{5V7DX6Zzt6PZksW*dJ%0H&-ry#2102ua~1U4F)JtwK7&xf zQjS{=-&u$BinnebY^iZ`y}rsE025y|N4w4({W6HtF1Lj0w?Lq9a zjQ{Yy)nvCgbwzJWrTLKlKGKq?0aGQe1wgxQaBSOV%{GxkFB5M1;Zi?_>WAzP32E>W^^-rt z%rld-&4&2I$or$Eziz7U0L^1y`jCcLdo^fefBaiRLUGkhX2Wo$KQKkX@w{dh zd!J2EM9QQnclxgrh@y=Yg7xmwyxW>ZbyXnzdT$5g?y*%DU>L4saeaw#%cF;C@0U*y z*^pgz1_W>m*n2XW#N?@ORlh9AYh6wHnYsyd_e!%2R|uOB6L%6}xy!8wx2+Mz0PT0G zGOo-GoH`}mdvmtC7Sq`nvL`hF6h|4N>3(?r3P`2ii>WOMCHKSrh}Y5*hQzG;3W>7! z^cY`0wNMf`gav|=tBuR(!k6W2i)TXz+__8qBl*^ipVAUUhmGC#QzD6#Y|U_51p*%;{x9(61KkJ>m<|gaOc!S`&I3?X9dCU8DbI?&H zgoLP6nqAwG29QpMC67U%D{3meUTE^vY1f&6zq0S2!!+29*4nt?{m|%vwh9FzXQ){&9fe=Z8)W~63DRoJzmWVCGZiGKhd@?|F?06p zQwFTvZlx_Pz~BgT)K!LJD7 z^~r6f8kPaGoEZg@Ph@m;I_y^)x2xMT&fYN4(vqN;cGarY#vd8Fn2I4(Vn13Yg{PKU z38BIY{f#izxQc3xbK`{w%a4F8m`BtZFUo{`%s+1SJL6js7HL>Tb`u+?>8w*psX$8s zkzoQwkl7z8zEk%+F-*cBuAl6vb8IaqDK7&COMSWNu#}Ye8=HkMv z{k_g7&#xtG0Zb544J5o)InO5<#=vu(mm%x|gnuX4ZKC))DJke^FS) z1l#Oxop;@ro3}vSS7E|&0*=8fmb=@R>@NXBG!l`qu-Op!=K`TrkEDSZlW5R$XnHmr zM>RLapZ$rdTp!dRR`_k?kqh3?^9Z@EV^A#Wyyfh^vY0?&dMf@$k$@WwI?;q^V6yj|%&UM6K1;6@Mt)v+l zk;J5p5ua1$L6m5rmcUUbaYBYlZh6ucLTX7nqi#^wkiTJ#Tw7i0cd3}Rud9bOm9x0W zd>jvyQXiX^i;S6$PNT~xZO<*D;THf9Sb6ZI)dx-op-2DO1o+qV^xx~{jEsLe8ULkV z&dJXCmw)kZ*p`i%;V<9dzaf}2voZe-+p_=l_y=rjH8^vge33CkazWy4WAWU0wn8RJ zLm3V+P})&dBFYY%=tu#-4=Ky!5~qRX^Z6E^2p>K;k^oAni+kMF%e0N6r|xPT?7 z%;W)RW4{bDZ;efCX8#h@cQ$5z<-+j_ltO*fF|}|fCXsmBoRCx{ts1Wvm(bQKctZZg z4~NK?wKDfMy@-KSL`d4SFOi%}>v-QWyam$i0IkGpwDNS~xrS;WSAUG@pVY$vCq<63 zL}M5%qPDgsz8;;JEq=Ya3j=RRz2(!cMzDcKdvEP^xjR3q6j64It7TJTxwgNJJRzSx zaR(1C9@h&^Lms<`eQIOX&Os-C-LO|bob-|spn=S-vuSb{37K^*qAQU86dM=~@&zGl z=1)|9sR0o*$)a_3MCGMl&yJvAB5j0tuJxMc4OcvWx{$!KT^VGo_;{BacVK=n-W|=D zZHBYMBN&qOBCoG|+Tw+Xvlq{>Hd4HX3{v~8<#*^v&II27Nq{}Igt9yHXBQfmzLtK?6s60WEGE9wBN1&I_$_ed^?Dvzl7Q>i0g+ccX0RLd$O z>z&n;h$81b*vv0FOoUF*?L1;ts69*8wHa%z`0sleXGL^rLpqC9NqdSH`rCP;%xa!& zYT-f33cqBUAPior1ja_ym&i$y-4a6(3{lOo1QAlKr-7`~x9at@LroF~mu^GUx!m1>~Y=dX#sRq1`-w9QKo{#RgC~H^tM&ESxdyD?$u!uRbrJSG1 z-OV1JCGz`LN?arTST6-#Jn!7?@W2ku>Do?O53VW!lHl^{VDw=x@L;{{xFdklT$iZS zLzJP=tkaBeB2CR|dwwn>6#`C*l(dyDUVN*V#I?w3bTqsCup-Rwfv`TiKcd%p(z*Ls zd_3PjbPDuO+wHp<(PQmG^eF)r$VPS1SbXjoBeVNu*RdKH9`}Pl^VF^J&)2J+2m+reU(>FBV}?YN_!lO z#1I)Bvuqk15Dh7fIzg87%ONE{+N(IF1OC~&`ky(4e^&X%$ingeHoh?YN8=kK69@ah z7+*LD{>(yuZU&`)(fP*A&Oyh>Nx;g=`G@HLhw;V7)!)I0k^iKOufE>t@j7X-FK%%Z z09cYQUsM$UH6R0uiI!)=m$LF$u8LDdaRd@8pdg(Y7ax{l9jbS6MM$@3!Yj>Z3$6vK zR38z>L_3qc;Ld7DR?$)c0_2m!N}+edXJ}&vdqmkM0?lu>B2sOR!bUHjgwKAbIK|Kg z2-+6avUR_i$-jM%w=k3EEDDIf1aWr!&b0e1FdPf@U%teaXe!10>xo^QgpFYig~HkIbcI1V_M&l_pJ!n z!9GFpCr?oN5;kd;7Iinb(v1%JurO+)t0{>vodzm*G1jZ8j6^GdJwyZF)~1G1H)03o z&0ugWB?xdlw9Bf}=sm3^tL*D2E zcE6`jrR=^(utORVGoHvvYsUX#?j4&%3%4xYw5`3WSttFmVESJMZCi)JZX9c5K1bGHqcEse?Gw-E%M7x5 zDtIg3C2?{>a%_->7r4--oJKUN9_(r{_imH_^SyBlGtOj$7S{I{C|OC?%q%f zjGRWRAi}Wf#2}$2mfcN>I0_h*7}N;bv7bLPr)2c$VWdIk5_@QuHQ~GnWZPv)sdNJ1 z0vehLd}AaeR^&uH#ADWgH0J)jMhpx&rg&D9h@`{XfO0JH+vj7u4TSqnx0U97l3*)H znsfZaT)dyp`duUV8O{thP_pOVmrlhcc$APP@|_RkpYYRHO3j!cFs32glB;)y2K`bD zy#U!c)A}sE+ze$$S}Z4b^v+eC;mVj`-(ZDX`D~6miEs7h5ycP8xat87kkL%kZ^Ekl z&}%~1KphD3-W#eFIeBt-%IllZX(=$f2<*)kd*DLK%Xkl^{tdF7E@o8Tu`TF&+DtYg zp;%n*j}}o?KwpnR#4SQMUnG(qZT7va9nTE5nyj z9%zh9zy)v~JLJPq;wUz4>`{N{+3&|Dl!?MaWAh81m!hQ&%D{ zWKBxZLey!-j~EZSX(I%!LrX#y+>9kCD8v6Pes8;~!K9)r?%!rRRe|@24OSP{09;wdBEj2m7_CUR%ODs8{27a^me30RF z`grciu~|N%i$F#J&9ki_y42DmTX%@mNsju&Y2QiNP9i4}3?7O3CNx_+Q*1I4C8iMO z!uCCnI!)qNpT(v5w!B+uxwvqWP!dn$QlIIp*}}7=sk!{+IR&m9pjcjvG>8FOz$m{o z&_#kd!_S`r*1b%>Z(JF8F7(Q*RdQ{}-K3Z9JpbGMLu(~pIHU1>J3hh>lwX=k0^jLo zEpr_ILRh=Y>0Ueu?u#+;U^5C6V-tK7Xp4G>qMF^i4#$0~08l4w8hBWK9)bZ>e)@Sm zRUQ)Ic*<07I$-czy-6uPGPYLcOWNH!mjqspo@r!eMzW9?ajNuQxvMtbFgc zgGsx9Yi)h4)J`CsDYKyh%uAoPFRydb@=GYI5<`eSIa5-EGmRmTkV|A6w_JqO*(0m^^^3Arv6-S#!ORW? z0?}xi=A(arpc%edq91(oQk{K6gB~`88D|1=@?WdymRKe(2XO6!K`+ z3koY~>BOot;<3#vB|vr%y}hJjc+IFNeX9%f*9xI6l1H2AV|G?g_ft9!+7c?PoOObi z0=Tx@LxTCAH~;D<^lt<3e^xLu{gYt)H!G& zGSM^r$0rm)=f#+2@<*m-yJze7wbVP=129yc)xU%jUWakXtQb$LU1!!mfO4gs-1WIis5SIcaVQwrd6PtLx%wlxNgvP=e^ybCR_O^y6y#GF>LBQVJ=4x< z1?7S)uUSaHPLpZkSzwY8HBIgYQSyd?L_3Wa^2(^;HZIVP_{3vK!tA7@aeVznGom*3 zU529{GWiS}4x*$+&wWlQ%f~34NRx;CRNB>+4))^c%{s$wOlLnZp-qyy@xt3eYczm{ z%c$HFG;|}^bvW@3#pAvNG$|ye_EwJSgQ(4@Xazuu{iGksDekZ^f?%5ojjLCpz9-Q3 z;R9rG;^mPK9)rfH21G(p&3nFi?T&PTI!{{yn-2pDFk@Y{7<-qwgBdQbmFHk^{c+Hv zWH)4%<6>VQkq78Ng=oLi6+K?TD*@mTOVQ8>=qFrY$?x4Mf9IJU@aMTzPJ|45xCyQD zM|G)L?#y`)zDV^NZc>1y@ND?H?Qp9@Zsz12620-?HPg2#=DUY_SBzi~xzv^yE$9uJ zE2Nfh*ms;MJv6^G0V)jfFb>V1Hy^s!-E0z&T>*_N!lZI}ph_GeO2mk|#S35M@Iu>v)jol2f;tJXG_=|53NY}>OGvKFbNH7olV zmi(+X4BaX2%cs-wOFZN-X<1#)f^2VUHGIK{x?%~Q%%U;Rmj3W%xHr=!xK6Ka~wrH9Z;o#@p2IIDAS z7^L0a((|9|wAR1095Ts9-S%ERV(iL>6m0Po4+m^K>KM>#$4er3)nXH2r}UoeLU)0q zLOJu?w6Mzg(-=raGexXk{|$?Qrz#+3C<`9^8;{rp9sJ?cNERj%AN-PqYrTI_FW_ODEe8b(647Oh~9tPS^mQBP} zJX*S^=x^^+*$4ky%J<&om1#b}+-`I788<*|r;EdId88uDhDxe#00O!jJLlWsP(i=o z=BZr~NPr9)G!?jA(0Frzyni|O36$@M3l)jeA@Y})$H`$AoQc2^d9E@5ADDKl^LyAG zacb4>#sl~a3@y7;AiSctFA#^H8*Nxj#x>e*t!;dmAu~^ z{TH)0w;8{M$p}g3F_z2wuY=w;U@aaf)l7rr%ku|Dr8GmGIEd?Lw%ylnA7I)rHID^7>){b$GXbf9dAuwk|MNRd48IPXY5KyoUod4!XRiiOp6@*w@6pxMQvy z#g1E#Wc7-JNBhmIxeAK&16g91hAypbCitN_G9y1-X3N`6wDIO zs){i53U23;i+|Ylx87be;mLSra)Ts+*v$Do^rE1@EH_md%Ibqz3g<4rQO+ zFBetId`-&h(!<*H@Z_>h4OXj7bTkC^kW)?dgm;#9d8y({qhdATvos_bX}+}b$KL9z z9+>8si1L@~L`7~TxAU_2=Fbbe0lV@%p)O=#{@M$&Fb^-)q0@XcI&>>(0(EVE zS9r2>cwe~>tgT<|NCN;NrO7EnFN8Y{YMjH$Prg^@V{(qZ|-u?(%(5qJ1pv|X=#gWaGkhK2rOBk;5JOTd!<~`j+_D zI9Jx>fe5`4rJewo??h*a^%i_J|7RGU=^*!q1aRNa&V*y~EcW`;C_AF2Yy{r3ABfQF zh;|{)o(yy>Q*~K_$kfYBW?G0b*20|xLh03jtPGreHWKn1dv>61nj)eQov^`Be|&QW z57Oe{keYc3ugeVv+i0I!j?wO$+%w8Ulii!fM&uvlD?nIAHhys$HRzbL=CX zG8R}rJKgcuxAgnNLf`!hpq7F(%auY6mZxy!La|md&1NkCP%{BV9J9$NoN>`~&AK8b z+B@Tdo}ns)v!sGPk0;JCrN?BR81Gl2oY`HeYE9^G^~CM#CV0OIe=asKE*}5|o~Jww zUBwk~v*i7XDM|l3WnC}N`T0|$Hz3Bq$fmqZGR}((H}mgp8cPs0bj8sxz}$WA40NpA z)qGF}$K$cxN+UPw?&O`3xynBYgxG*n0Q{EN8$kmQaGf&X)VVv8(V}9p%QnwlMp!9a z&CGip387mwG&jD*e8D~L|QuqN4qq{>B2T=}E?0%!W)Zn5x(~sg@4BIS85X>uH;pmrsu3nZ* z1CW_Hi&hRb7_3@ylR`kJH{@>y0lRb9OM~;;+G;;Qzfz7jRzH;X(RQTp_odPnpg=on z4cTLS38bU1&lDlxL4<4dwr-Ncb=#YBFQm!-Ft7}+(N0p0Q#sF5ZDh!hfk}!I@e!~>3|5{wfw>C#IIdibV@whz7!5APAtG%^a{iH z6DNUnl&3el@RWj|jTWau>uUsX3#9P4i+TfB`w@Se)V*Q(Q`FlVV8y|%J#ju6vdb;> z^MRa}-qv~NoXKy8-uAv)sbqfN(VJWwi@13%1-HJK&>Qm>WUQpZg2rG_ zP*jo#@zwW!HP-BA<#$AS73>HXG8?@ynP2)4^ z!Yc-g7(Z9Jg9`20ss}UXGS${YqI1(*1=gSx3|mr~3QFT|q^+(jhn*dB)UN#z@kv}1 zv7iYcd;ds}U}0_1{kcSt?>Zk+CAYh<0hd!T2Yl2e6H)B>TPviHu**Gyfw zR+1hZ!ZCzT-0QE@lr?}wU{M-;v%x+<2fe%~NGu-Ndd8q5%p_-pk~&vd9lT_6b>I{w zcnAq^22WcZa9ipegyHn&rAWn6_t)i=WyDtWT6g#74wdKc~<{(@QMrZUYfs^tdy^Y@pb-xAzc@-9fXO z8Mn-emugi^jP;_9I7d4EH#?y0+nS|<+UX=IwM=)bg)tk6TV#icxF}>wW(8H-fLbNJ>jX~_KZfwrme16_)6!2t-&m2_dN@MM z>~;FevL9D`(~2Pf+TTn}aWQ36hEmki&=0p`+l0lA+Tj{b*j_Ho^n_ISbSv2e=9BQV zj!~kFfnOs?&|<0=IiKJvt-IEhtIZuu$AN>|Xwzz33fsN?>o3<)XG<6oikJ=?yw{YJ zveV{-!SB?5%0bFXkAN_Z6aj5blfE7_?M%OLt*X>@OZ05gxQ!3~)Gm_$u(|`lq=x=# zx_%V6uQSObO8cqS$zIMc3}Z@Ls*X@-@yY9X(x5z5erBb&t1N0PI4#C8h^f*2Y{=ot z?6DL=eVuG84g3519RT|Bf*{1(O@*isYTXqc`smC)++Fi%nb|*&%@8$y%XvzpW|b=W z6)(QI?jc+dP(BbVYj>n?!hCV!YCvdA#04vky8sBQnhX@07#!c{T(Lwc+LAh^_=s5^@ERkIT7eOMKj{<6Q#)g0j^-;El{}VRZc*wcU~KJgwdo1^8EpEef0m z!X4AAjZ^|#Vr_|%ndg%+2G?W`YMiJ~x{~P+sLUa7uJf z$Hon{$zSr!M3BV1t^b6j_SOBMoJnpJP=x`>?q!F*u$X%ELv4OeE4iRN^YG!Tqet1) zN{KP9?UqiDH&VEj5AF%q5^6(oN|>$+{&O1YeOIf8vKm)|S!K~SVCU?~I0@$<^Eo_* z&0!3lGf9O1NWCtCyhjqF(J}l5ZU6_w9+M}_J=MbQKE*{hT0t)`jr0|}g8&=d6R0B0 zi%q}>lEx4usbm>QifmI}jipT`cLouH0J9FcS}687S}7-xKM#UosV7ATkfvUr|GV1# zUoCe2L7)ELGri3JwAlG~zV^Rwu|rSyxAF1c%o+a$Q15^G68H~_;(ymeGB7gzho`^* zCQl;WY(K*H_&5i3x(RDIK|MI zv%B(fdsM0$Rwk(oHlrD?pJ?ufw+QJMqCx_jikHyCV`YCOsoY4L8eb!m1lIZmvTwCI zV9Ju#@plce3n7YzJYWsGaOeo?;!rM*U_Mx$Ffr$^;bw+3M^>naA=(>r*f0AE4mOe* z+~Jm}L|acsN`~T|twY8o%;fXqm}K28$oftE6umW1rbp$sNl2TGs26XAwIKTI@Osze z`6KAqRb1_Pg_kwN4allP?C8*vr~6I}GV~goIY=(nj2V+OBLTW}b)Dy$<0G`KOrk;* zo_--!pu=|pW17zdGFU*@-|DGQBFL;}@&@&)xs$k6fl)J?(w(0}Xg~vhPh0~G2}>Oz#ghq6d%lpB zH+=^g*xIizEDvO_cAb0atf(uV6xXk6o`NAu1lZgkSL+Yk$999;TvQVYvh6iO*3=zYbXc;{d%+mNFZm zq{ENsY?7SEG^M2rhuQ2m?+^SMrOj5x=-O$!P`nY!;=o;WWB`%K99;9dR0#8td|pM^ z1-D+PKY4Q!oj2G^Bbp`vJ_{ zc~N`+wQteZn`Bs00VYhzeYW@`C^coSI4;fZR!|oLw?gk8uR&r}PM>+48^?z1c#IAy z$o|`TQV2h7in3|y^VhmB(Ta70*Q~+*-mjF^P6?_R_8o3rF*)Lz&uMCXsBT_#F+Z@U zCC?txy4h>w!+s)=qq-u!LV6Q~)6f&D{M*B@?`v^f#+o)Fb`zdX{-<`3Hr)!dUwr3u zCG!Q4Ky*Im_J$%FTwn&TF4_H~7)yd#0W_>3dHkjG_RfEmpK`8SjA4qMWJ`(mU8{6{ z#&{a|X=NpVWYoCu4d&uq7wCk!fekWHpdf79>6=3a1@hBGiI~4z%YJ4UcBaXANc-Qe zkb9Q%>Ih0k1c+=R;G=1o!VHp`xB3zPIl@kM4A|Y7=hcbymLS>adqOF7F|;D3u|S)Q}lQa}!-|#Cq46cURO! z?UH+)@=w;xzDWae#?s>DM+SxzgWh!dmo_2#@Ii*vmHU5j>F^!3gmnhGM$K?You!1o zCF-)mqu02RJl790OdrrGd1YetZ1U>n*ptTDUYCM~DmUtxOYZ2`)0IF}T?l1=u0A$Z zm7_w&7DC*3Oc6=*yLz85plvbfZp0YOP5e_|mHo>h#nT?OhpoeR&J&C=?&nOhAIbD> zUS9Ry>G^4cN^UGNDOQNdV|s}@!I)V93n$)skJhaoMcz&|C9^To=yWcyQg9EkS!S{$ zSQ(yO4dAU^@Rx^Cij{)}ie1=TkwCB}ZR!V_@$7IkIUf;>Ogp?ruME_y06B9KV+M6m z6}O^>B+rJ(7gr~MLuy;6@jwqwuIIW*3P$+0e8~~`z0oVX1U3( znE81^SQHrw+rFCp#7!ml;^+=VLVja4(KwXuZcB9+H99Zs;r_v4w^r1|hkym75OC4| z(GP%7-?8*Nep0rM7{5qEqjBn|caU?kPm5gy#VIYD*H+Hnx)D5P4clj9nb#7dqJ-}2 zGt@pORPkrFZr$rGrhvEet3K|-As>bGw|VU_snl}kSh$zytbKbFlUmmi=&nry9)5*^ z@hh@^O3h#bC#bDig1AoJ2$IMmkXg5;*DH>;l@UEhG~ zCXF)P8rC4Z{W7k*jX!CAiAre4)5QIxLt)|zFAv^Y;{LuXs^9r%QK!)a@Fh32dp`xJ z)a55eZC()rXJ;M(iy~E9gH2#UEL0zRGfJp)kR>vh@V3(4>bzvQp!^s~f!iw}#uEnK zI)^>tgL4NoB-~;iuArqnz{*N}25hY9j=_~>zBLde2W}sl>J1Rb*263QBc#flS_2j; z`G+FID_!tzcajtjxe_H9b*-AXEWy8gswM`9?XO`IJ4|hd#CrR0AitwwK--QRrF8tPUxj&hW&)UO#6VKd?mLs7L+X_rW@_I|v#CVKPQDm~Cgo$N><0-rnIO%LI!h3-djb z1v0y=_MOl+xSF^zoL(7`nCc-DHVLgM(!9={KkA9!$$<+E2?8jC<)y<6;K`Nan%v+P z=8i9;Pl2T|ZcQ=eNqz))P< z<(3cHO{;Q|=Yty-O@*ujUxNeY-(mB2GthxJbCkL_7n4{n4!- z3o-dWb=ZI4w56l_SH7r!v=jbwG}T{*^grvg{om14|4*lF4)eEIw5w>{CI;{@*$o6s zfO%mX0Lxq@ghpP3#^9I*IU7;?t*BaQl%LU%e-r!GtN*K<Z)%>c1&C$s*gv@nwAM2Ci2+KiHm^mZ34SU(vc9lSJu;3CUP(0 zwje+!_nwFZ48K#-dIHfp$#G)Tyn-u+#)ai@!wlbR-aC##=R#Ruw+o8}de?80PUh$H z;JKTdIAePwC<6F^bLo%?{NQu|E%m*DxxmP`OQoai^Fhw>2RI!U#_zz=N}nJ(&=rxx zMNN8Djak{)h(Sd=65iBT?@ulEwwWsV;v7GLhB*gB472rMnriv3zF{DWID)*OMMQf4 zigkcUT1T)VK2;yTlCWzu*j{AK>74^d*58tUwy*)o`Br+(9uD_=>cSm>Cu>-O3Po=Q^Q3ZxO&Z2eq(@Y*)F3nK1l}k!6KmF|%y0i6dFID`AoNWMxx&`K) zSAnfJ*6ezav$$MDGz$S(ta98RTD#?cj*J<&hzMZLV7E*&t!LmXnm*SE8=XrbRnuLr zddlC0uOmWyp)a$b$?Q4a-z#wg1Ibc@44!VxGC_-i5{Y6tlQ$gfCo#qVsYcv3WskZQ zc#^VwqdUe&7ab6Q)lKm~#@_-OT5(0V*eH{|#|}&YMDYb4g6f?}*Y9l{9VD0b5PKE& zc`OfS@Hl%T_-tgtN{Q5=A6g5x-yR4+@`FO@osXfL=JDX_#bEg@Jzf2!m<`>LDq#|; zxXB{nOPic`-^~kHdo$oxv=icaIWu?AWTyZO(A-EZS$drMJ^i}*r5_)iDGnPN!ciVGDh!5*QXKlzdQ+9rt!142zon-0`h(+I8txiy4_z-*1d-*8hJfJStpzi- zLT<~=dM4eH8S~_CG;%(>txxN9Xv1b=cH1jt3zNu%9bX7+qRVHPo+*IFM^mRIYwRo(qi1aWQJ+<{sU{J ziCiwRBWPWp^qu~b_>F#_3=`ONjjp|GSnrUXw*a8ADglWeOo}mFy_28rgGcCku}qBU zU~WL%=NQ{NLA?n?-(F&KfG%L|R+iL#;%zif88hfH#1G$AxPWyYehlHgdb%4ck*rWZ zQn6h#!0bdxRRy}`Lv%lT&boS_HIzPFse6Nb^&17r_#jiJY>+L&TMz?68xG(YItxh3 znN#iUc=e2+<%_O^4#Y@8n}9mE6|_#16}rE?zbYOCt;_4>sCDadAAgVk)yZd4P$#be z`yKwtM21wGN_eQ7ghijo`7aXM&5KYN+jh3YgTr8;2Uxy_sHWX0!N1>OE}GeAtmVhm zkhBv4;US*f7dPJ{qAaR)1{`RIvP_CGSNnvcjJ%KpaKa-JF z6nj;dJ{KdEhmO~ozp^8vC}P`~-sw@Ibkc^J(K@02nO-{BqJR}iDh@#=7YS|v%Usle z-1WP+wj$q-S0gt_S;P-QfDMRPRB<3E)I{yKEMDIb-mofexpt&aG0vE84ZKC+hz)_7 zf-4n+>ifV$(Yn>En8hH5jx{ykJ2`HG!?;sUdxOWS%^8@aGv~Cex-cU7@5fP!!^!qJ4LQU$wNwJ;ASrwTBLnP}C-C*{FB##%UPy)|&GQyv zK)S90vbOkODmdl0c2DN?f?EG*PO1=uB_DwS^cfxeVXu;0xYA>)Fi=u@m|fto`ZJ<~ zd)$0M*NYlu`m&sNlsD|ngh0TQ=Ydv+F_xfiliG+MU}PU6%JZ$i&A;<`#+pyE3r$9&~ER%--wa zab&R@CIEn4I3}s=MLt_k$|*&ywN@d`%!pH07M?J-d75N!Z?&ZC(G%r*6<)qeNKYaH zLNKU}6NL)R4mIaxIM}sr?o0MccRDPCO)Nyyi8FmwZNDO~h5Jz?0(;bHYXv48S%j># z42u%YmxOv^Bk^t~iHvd@Qr^}a!(t_*0mdAIUkYV@k(`!YlRD;s$SD2pwP1H8M&$l# z6l3`V-EGCnNoz@HL|yIUp|=s{IIQiQLYZD#%k1cU9OQm#2|p_{b^ce9s})aHe7uq_N_|6Z_r*5t^yK8Qzu6q zoJ~$m_0YYMUMpc?{q^VBz#N~GzSNNe#R9OCvu)4~DTE%Qz@|D8P81TG`{TvOCUv8G zDJ33N@b>}GQCA*eZZP4v_3R&IL_0J}D~<+>Ts>~OjvkBpz93CuIbFAI7S99`Ks1RX zlAi%IZF^OM7&x`@H?vB$4q@(%^;NB?{?S$aQz@CzFNQ`C1wNw!@dO;t zi2>6wyLM2zc+Q>L2odA2N4%e~maQG#aU>K5Rg%LIUB;F6Hi-mq@|z{hCoW61tEvW!&8qkH^QiO_&J=#qV>m||#NG%$~xt8v zbch0kz`1qxS2_-%iq2=padZ>`PxYaBg%NcWOo1VH_frH<^hrU8R z;3RwUV0-}3{iczG8;B`qrT=a>JZd*jb*$^r8Q%$qLR8iZ<$s)^yC|ml#0y= zZ0z8QzPvX!_hGM@mKA8MOeu0+`J0sj<-n^n^h`XpHel?{-!Gby z^-JB;j`P^`ak4evFV@0^@=;aA(Cj^#xC><`tZ_Nl57GwphUwBhZB0@@LezETqKlA9 zO5iWDRtK51*R+@#vmm~8^13>uI4($yhZs$-4uC45c_`%Z=9lqNJ9L-;RHn-Y^GZ<1QOX8GRNDS=c&XSYQz03gHVpGWF zcZNs?`UoQiI>X>zo5=3KVVzc@E6d5o)V1ofao}C#q3SW5SD3#izRal?HKb9K<`J!- zLdhh7M;6Y;xcBVP;WItEX>GAQ6J0e`#C8NNA-oDWz#{uP)FP_C^QTI{j%9WuIck)= zof+`pQG4!4x@<`HGh2IE1h#Ff#(n1L4-iY6HmQPC_qNxj_Vdf-0mO|VCrA064w6l& z?Fwloh)e0ypd~3{|MY#LG90M!S#U0cvQX+0J$ja|9M~&}E1&s9Ti-b);HI-r_=;qP zlz>p!!wH*Qx^b5WoyTjHP|5LSWwWT+m0oKZ>lL~<#ntnXQE|nSt4>zfFgxBsnqEGluER{s??Tj6Ndo*#kOlqi z*QEdZGF29%c$03Lbj|7xhaUVP)&|f6SfIXgR7_KT(7#If?p}8kfz|S9`nnF7zU2U2 znp_xho7i=R7VI(mcR6uajux3b&t76Rt`=2lX2NOm9vXU1uPfU-Cp4DeBON2Lh?8?< zp{Xv8`c4V;viOAV5w`O@dK}KD}zrKAn}}3`Q0Zc z`JGWXi2+)lrVK{f|F0Lgc9ij$FRL@YI#LMX`0d(On2-AIKM}H`rIk~ zJcK2k3);p?GvUo{iJDqY$qgCTpdUtzwy6;5h;N>XK2;EAfPH zK&v?ts#^Hii1=b6P`m|%k6GxuJDJYR&gEQuad*;mJ>96}nYQ;+7C1hh8*AlR$tE-9 ziPENR93WLV8b-ZuG$Xk+?9}Ckl&WaVJ{g&3`3JU$vAu!U>J$@)TlX~2m(RL`aVIWS_m_+L! zg18Vv8CS-71c9f)qK;C-#t>IEutkY2vri;D{P$->bQ2Gcz4+>M3cqP%qf;MS@zn(3o{bSk-u9K3Z9~5lIgg2}% z0#mx+pei;Pw^Qj)x0#cWRVIlNWzI zctKncg5gi`9a23!R@l)yVLnb25EnaV?ZH{2v(=r>SjEo~CRn<| zD4n9EBJPZ9M8SulqJ$h9csH(AJ65&wei`J;hrz-emp&$f6Z=;1^-nccCjw?0)QYbh zsUKDIw*DvR3t4snBZYk0AxixxLu4#y< z?sHZ7mcF=~z}dwc2+%3bSm9G!LRdnqt4i8m`(YnU57EC3F}y)Pp(ltE8cjVA4GgWB z=KOT@wYN8yGW%sj>BbOrR_3pw`yt*bPeW_oW)1`dN_AI6NJeM$<2`Fw+!%q{ zVo2t~6}77;7O|oz`=Gx^2Jk0^DOn|Bd&E=2#iG00YbAESXR318fYxwBfBWt{$qxRU zXMuYH*FUI`!lP0~Yy7+fM(e`Y#skkOQOn$j!-Hm4C%b_rHtVQlWA2e-Lxo4Toq zhTezE{j1H+e+Ami`cIpk|8BJTzi6}bpY<{@|G%hadRCVIm`UMZEAwY@BtqvXdDurI zDc3koV+?lY9Ra2)8K!PpX99Wq8yh0Dti89G#@8NY#%ajSZkP>0iJf(mRd9BCIOsb& zIA@ynw)zg&$Ft5up$xx!6WV=Gp128@cF*J*La^=EN>V)YeBWY+Ssby|I(}Y%T8Ix)bH% z2d&r)uOXZ=_iVW2;Za<0lhf${!+xkNarGdLm1Ufl*;#6WP*B_bMEwtc=A8tR7O`_L zp!RXv7+EY$o@H(AnK=*3D>0PckR?1*i9XH4zi})NQq(jA1T|UBD{-5{ES&_{)e)Jh zOPBPysnU_{k83-I`OR988v+V&i`Ns&Y;E$1piCQuT`4M(n{Ef!Ol(EQM!yqdQR3j% z)yZfw@_El*r>#li=^jqCqblLh=yBttuVX#8V1=yv=g4sip5@4 z4BE2cpeg%;O;70_zGIFzaTrhzmXD*on63Jy=8ES_^g?W13~Ww1o)o!!U+Eyja))t? z+HuFn$OE<96Yt0c^sFr`uU8s`%u^`Y4%?@Rv}aFkjaJYUYfF*$zSi&|jg0d2z0awxc7wR3WiXt7 zonW6#_W&)_iYao9V(skW zy`f0aAGz`Tk*v*{j%`g?_WLHzdD22GBu{7|AtZ|aqbJyHqL%PQfRsA7#^OV;j3&d7 zQ|3ftu6Cg(_`!qpe)3OvK15Ca2DpZsvQ5fFO5J)$kDvT|Dg^9A9((=98Kt{u$4751 zVU_R5rC6MKxBc~3KFTVA0+U2}aG}&+Rm$K%QKp#OHigg(Bgoshc=%qC^VDG^$NG0H z_v!)*`Jhlh;{0{}^SvY7Llujmf+JQE!u4+WCWog=3XUa2-OY7Jq5a=x-qX~}$&@~y z3QOb{OPcgIN#&3athphLYG0idGAXk0cHDa&W~;{^Rg1*5wPUeTUs5B7ihJ&biGQ{# z>RnT>RbbisUU}}FJwkk~t>LkM)IAFmOR(^9aFXePPXKuuBYJ3JY)IMuHlP+1?bLn( z06-N86)`-42LxNxmZ21IWeMLtVDCj{9Af`!;qL-kCdur5&%U%+tes2~on&X8cO3_i znD0x8btYWh>d|uD(&Hj+XW%djleU5XpyE=G$yt8}tBvuTlZe?g4Bu~9^f8#tBRXiSQsCb0068HrrmJEwXZ;0qS<-46vckc?D>^P zCP^80$PS=yUV}-YpUKB3hh?j^J&@G3olh#gGjn)5OC$sU%pqnDd*MrVa14l@Xi`Jz zC4PjvkvI+bhJ+I~FCnI!G(kjZJwJP-0kU1Z=OY<@1-W|r_3mxF^s449OCW4{@QAUB zgDOK>i4sD8+%VkQ?JZ}z3R6y}G*&IgmfEjjwKHEtHB%a%>&uvZR8sn;IAP@ z*^C7mtkS}Xw$oX9JqL9ng4nYybD~O7`RZ`0!ne(q!H9wnCTu4r>tD%^f21`0-}@-p z{z-QH8*uyI3CPmZvHpz_{r`uLlKCIB@&7s{u`v9{HcDStQUi*rw`-THca-K#ud1z#mdfs^q{_ z>CbuW{a8b4lIfJjj(ZWVqywWKwqEp;P>?`7ui^DWucp*GwB?GpC75w%rhrdF^K~c9 zRYiwoxFEPxKE##VWp=>J8sFZ6P}9eNnWDUjmN{g)!3lZE|B zt%!Y|#{Q7n9s4=i{0*lCFVE{m;M3QTLiHm6LRp4Hr>;Pq(y);>Q!laS53a=l8X_=? zK`H2WNdRv2VQLSAZ)T&97xEao7B0&2hCEzd`1~l=e?Aa2d0is5hE(0Ei4tm#iZa}4 zRhI@v4-0&E!_;sO@Wv@K(*(GM&Q=iu0*&qlL*=0MrnT$~d*TmPSkrfZA~;HmS&yf17%z1hySSmRpJ9)$;8l7B!fwxICxxTsK?ySV? z;)@t!QYNBzHJOn+2JB=T(Y-%17gk~snc2W`bR}Ho?QF}0W5>)V{&}%OPNadYyRORx z*XG!vgNS=DglW%|mANRk)?iyWKq;6wIajss%9*?=bJ_e?FTg(_?thun!a~RJFOH%A zWPbUlm^pendZzy%Lj7+@3q8ZX8?8nDKV`Q3d*mD|9Xkyh%Rgtfh_jfhc3Uqu6*RG5 zyrG(O)_bIhu+>_7u0U&&9KeA$ypf(`bVd{}$9Zpdw>r_Cv7A~h`_b@TaZI_ppHm(# zeb{Q@E@vF)=V|jrWa}8!#3#0~l`Nf{qFwTh@It8cGEn&qH_l^)nl}m<&v4wnb3s$m zK5uO3r{B7*%Be^pSSFVLx$^H_xG6T0HGMKj(Bq3M846>+CD5HwF6Y@YY}~!C1W9XC z70_k5sLU`naWyf9ovTua0aVG;pMWz4I~! z4%p@PiqG~caM(ZidhA&oeG3@h(xXbOj;G!5kij(tB{ z%z$8&<4wH(64=8`&#veBQeqX&RU*>;d>ofNWF^r8C#>#k zQwG6SYPdp)=HZcWpy#*G(sf=rupujMR*p{D8zrSVP%;)$cBZw>#&J=RFh`fm(DOf0@QCKYUHVD-y@dSwD1C zttZq3D}|RJ@YmZXW!RWLj;a6e?#wPY%}Dpn z#X^ujlUpGYn6MQ6O5)#y;_0f4>fU0m}8^tFo>h$KV;Oe71 z?xeEm{~bM(hN6q zdR*|E$42;LACD>}qYV4+XKpJw{y^na<>>q+ipIUSkX@f;=>^=VA`&mFlGRLwqan0E zb$3~P7rrY+!_;N2#Ji%>(~VGXvT7J8rq9YFMPmCNEw)zM*zHL5;H2s)%l{Ttw?`D` z?%`#Oi~{fr{Q`@eN9m;f#lrcdICVJ6(dQ8e`~#1FLV{XQ0~$1bh_iD+Y>ntYi4+8% z--x1Iymv?|MIoXJeoS7fpcbjFGwEaCN8c|(-2?jWXyDyYTxhGn!+h`^?i5Xhx((t# zzudiRnc5ceYdP_R`1pGac#Q~i!k}i3#Ae^8%FDm_LYg(qvFQgo%0eS7U6GB!bz0!X zB(dj-1j9OJ`P0E)RT9K|5Gr1+h>tq+CnFbRs6^K#v6=m&VI>kY{rZ3Kc8*P&K+$$? z8`HMUY1_uzwryL}wr$(CZQJf?+wROwQgxHc{gzbz!>KxJ@4eP~Qt57q8)4vwp=YIn zW$x0><(`t~buX8#7Rs5{arF|lU05k&v_l9&>y{XL*x=MPvJN-disI24cytlwj+sPj z=4wg&PuaCk39WEBMu%wMygc|2V+hOZ@qJBxoZ@vFv8vXd5&s>(z?L8kBTFA~p9CnE$WrH-*?eA%!k z9Yd5_(9#xi9q6>SO{nCwZ7;YQZUKMHrqg z=dU#W2lu%OgXQ-##Bb0NSU^TsUl9qc7`h53evNDtQxoxb@khb&m{Y8wpr*EQJI70M ztFb^8`4DNL2-gfUuP}b*y(Xk9_j=E@9zYt(rvKGH`2QkN#QDD{;s5W6B1RTMw*Ov@ z|NH;CTky9SD0j4=)dnSrB>>FX+L^+An_=X^IR-{lmz+GZf7ZU2QBjOxTIMb|5Vs|A%lNR_tm}dWaLLs*}chh9})2jP+ zKb0skUXNeX4A+rb)q8pcLiZ;HSV0KC)ni=e17iml@Q#x)vQ&V?ym*c@=uZV;Ix=LY zgG1q79iWCuAo#~14gPhhP}S-Sqp|(;Ls`kmRTcqHDDsECLlvO+-FGTyP_8)i!r+{| zvVAhZX#uXwGnJ^KsP=2mp`EZL2F7Gx^JQH@O3bb3xTiD@jbS2s;2D}yTVZ(lfjCif zia`LZLjdOas=Kwo-TYg1zz|d~q^pHJ+0iYUvoaz*{%YOV_m$CP<_=qFGykRM8gd;~ z-7B|}`J9@N7sfa{uz}mdwoC~*J_q!4119F}vI#p%CRQNAif_BbEd}O2Es3(w*Q34_ z)aW?_YWok$*qInVac~2F43kXg6~bGj)lbiWG<#Rzc!AT7qaTG))2D_$2>#ARxz_YN z<7Q9HfQtBuFUdIt&3?JwgY%QT?C0d@HhQ~N>`VRc5Gl~GIW4=G#4uY*(}EYo)nN+E z@AKXoor*k8Cy>w;Gbs|IN1ZG4=j}Uk(@s30M<6;V*%g&0%UQF}@0>a_JZtU=5(A~7 z&6;{JtyH?>_N5GB4==>P(-(y-De<)qDID?A?)8Xl^@r#+bqL}Cd(2>EV9R|?d+Cl- zx90_FLXzth$GU_T=gl(AYbY8+C6?w%YdDX{>188Ow2prYB7*zYxWYu5#O8C}0|-iM z*5b*T{!V-go5ISXoNhXa#uz#zJNuT|6L1=*W8~z)#`05O%6RkRTg^1lj3}Q-y-W}% zp1x{ce1DddktNEtodij&j+;QIMw_ib`OUzyXkKU;l{i=L*hn>e*v^Zzt&+I!ER_$K zYWp+$S0%$8l#(3}5JZhyC72)TTsMhtx!%Br%HYIM}+-nWh;#Vm;ug_IK|G_hExk zcFvp>-Z+{QHY!POousc&L7}BK3`t|lPxW0aWzdUI_L5J9Z0NKVPkDAm=Je9kuVapx z5|<4#|0k(^m3=Ii@ADo3nQ_+BxescxY9~YZmOIB1&bd(0$6vCR5qdP^>p+a%4UpsL zOf+aj22HhOHS6!)s(%p%+X*KYotpr?IA1GQr>B^+4-zJ91zb{ZIOCP!SkpD9A^=DHvb9Dag4kwz(mW#?Pq+XmQq@GE4CD*6AfuN`Wpo z%RJ@k&&bk=DEyg1)iy;Ttn;5$sHF6KGg>M0zvTzk)`tbEwUJFKjtWn%3R<+1$pIgS zIe@I!dvFP(eG}G-UD#G-l+-hLJy_<`gYQTEb-TephYp{+RDEW-!7m=}g()DLlru4q z6s3SsN!Le&IPZ2NIDtzTpRZ-9vmD3q2`udN>q}LG)3my)YOMt)FKp7E$vQceteG6V zoUd4Yn}hk%Kb?*gc$ei}wOpV|RpZRpm@=)2CxN5bo#iJQh)TE_)#Bw}{_|-bsFM3Yngxp^t#QM9$2W!alx&1jk z(6Yb^S&R#+m+)-IqM?RwL&E?xf{+m=$X!S=ihxUmP1=xT9eKv99vKpB zx(18E7h~;*zd_VSf{${agxO;sLRF=I7L5)ltGACFqCd5{z&t|oZc8I1I*!}J;Fq_x z{YS_Jej~{bTvh~P18d#SZ;fQpR|ka&b$`t zX|J+F8^MYfK?7O9gzu1!mfAY`FJvLxe`K`(H+wkaKg{ueNtOE_J3mH34hBXBmj9G9 z_uLUJvh;e-jN2wm>P66e%o6b&-^~nONN^ml7F~-K%w?X>0yLwT9*`-5H0)whc=Vzv z)b3TVY*_&=LAdE1H&+#Iia;4q?t`PD6y}eoq^@otm+0(+O4*>E}8s|}lzmsL#q=OU} zinpTPv?q{c+P<2HDk*b2F-Zt8dY(iatROBh`lXB0rH!{9Mu=hJL2BPxX5=jpEZ! zQ(%WdW6i-Q$7q(w%!ShUdUtd1uYuldL|#l?JyOFL{;0{Tb75EmPDAU*OAN=Elx;j| z`gQ+|d4>T*B8M7qGUH$4lbafpt9(3FeJD&@gS_c^;?!{-=j8gWJv*CG!a79&Kj)Hb}LNpy=YF*z&W`6TZnfB?vo+Yw*}bK-yZL-2(?U zRq@ff`YqLMTmjee>7+)nf6N5ae3&wP{yd;2EMzGqP@u#)^zI3k*Wj zBoI^%BE82Q^^!kt`k1f>t>10Qo+x+dP5RZFIai#0(dQ7{5|0oU~IoK41_Jjt$n{f6IgA&~JrKJqAG|a4j*n39i_|-X7q9J>7 zWhlCMQQ&fucjBo|&=RWhbC8@W#X5#~5{QPb)z`*0m`GhWS|35DVJ(D{4>h-7_`1cw z%xzDdM=e7H(oB_z$9TnHC&AN)WSNP75>=J|g1PE^Ta>IWP2a7uOM22_1pE%U|J5Hc zq#8Jh=)hH@CLsg-4#0b5-x^g4N0WpUiY8QF6477`R z{!#5bu3W}>%jN9M54(*`yRD!!Dr3F6jtYQ>6phq_zZd*-gJ>dpIh;7AOy%%Qe7&2^ z#q$RqrGqg0xWDMU`CWDIO#;}}Pzgq7qgVKYrVZWO@RQJdo{i2Ea5DND@`LORE6gLz zWf?~9gcCV4D`-FO`rea*z|`9%M^$0~-xr?=Sa1@7wUc7)H zAk`d)*4P#jOURt=pFQ|DZaD4zVbz5a--GPxpkojCUQ!lYuB%WJyX5-C;i($wSmiLOJ$7PmSYr;KRN>1*ui{Q zolm-z@yh3*5?%D8+>$!|y?17A^51ewEP>-y_WfuTcL5~oM~Z=egmrHORNGG*D8f5= zMW~*)LLfCEIF09xI)<&gJN>zP2&bSh!lqqjzPQ*%z}d{hMoS#AiVjYfaXhpFenqH- z9++^J<}0WFiKKRl;ccREBQ4GrSC_z4hmtw%2{WIfWpOcg zurtB>h=8&@AA-I7p6>dDN(duOSLlSWfaLb8T0c;4cedJc2aAu@*MX3s&y7K>wN`i{ z=MFW@nq_bc<|M*G1E*E&BWL*g%`I+UWg1U{g}87m2X+CTs z0rQvx_HMT@j{uW@G8m$J&#f*3%mlCGBi4CSxhW1*)~r8aEe7`G$-^Ab1)5NBJY_c* zk9w40W7x4A@5cs#y5R56Ai^G5}kH8s{UDRod?3Va;zWmW|r&q9?9-hXOLfW zdMH7=eCrX@1Dy&L6F>Yw@M|SlpQ*g3eQUyVVwuX25{XM2tq!UC3P#h4HS>avOp*Ny z1N$fBU`I%evE}OwLfll9;%sjc9w8cFpwJ22NknuoJ+!o8ofL+Ci76pL^?wxcSxek& zR27{ceYKf1laA3@0QosT2Zp5oZ1(Ohu&Sat#k^ClBY$a#0WaKJE8K<;$v=u)aeT4l zXN`!9#UloCa;nk?;YrMq_E82$y|XF{>(`dAGb|^{)uOzd#T@L>dFHt?u_3)p^a6h| z+Ta*+43O^)l&j=^$QK`VBT%v6d!IWsa}+C-veQ#cC$BQK;Krb_hBl2jo@1keiH56$(fQTKuD;8ebkQkAWjX-klGTrpe4oO-<=x z(|IUo==9!XVUA7En(n5Kdph7Zb&!&aj-ijomm1evM;{-$R4ZNoitJSWig)bsKMu;t z(zv&uyY#^#&gurukI?`67<8Fp^@;|v<>pE0nyc3fmE0fVKw8`NQwoN{94E3GIgWBide?DgL&H2he5nAcLkZ){-kEE zX;eMN7jy*A{n9sZUI{g|79KM&9{@|ZafIH!k8QEm;9^}gBNtu+$4*^Se$^rL!I3|G z*!jqsF#szCo>?)r=BX3dx(&@Qy)$`L`#~((QJpYb9O{19YOn{GHqB)!Eyz!2qpEp@hMzz_+{j}9VFpv{wfvX=oq96T>xc<;TY$MJ*FGOK*2 zc;C1A9g`!5*Ae4Ag=pN)IBiyAn9TaIMt*?)D^wKngCRIfC<{A#@`&xZ`KhKVO0C`Yn79EVWUB=SSA(w?QmR^nZ7z%|nvO%hdq|G3JbTdyY z+DgO|VxTA%!SEft7av zj&Ae)Cca)@DHTQ1bU&RMq}+qjtp4+uJocsd^Q!1-$q#}hh9Rr{D$-h6yg)~@0pa&9 zKKzqL{up{;_b_)(633E?!pBg$t)&HCQ<8Qh;BHx&_W|=$dsbU^6f)pL zTCY(fWXi-#L=1j*D1+y2!;*aXuiF99e~eWR&lHE3l+|zn2f*7kXk8S-#P@|x!?kZ@ zC}5h^Eb?SDXA>vfOeohWcy~!;cbmE1xfvYWBrI_N_l>wG2qLG6^^BQr7k@)-=;1> zCqE&aD$aAt2%+$P96bn}`$2xuWT4;q;Y0|UuSc+{1V>)G(PJz5buSXt6hF>i?*pMh zxHN(!8Yeh}i(xJ*9a&FRcRRSLimctS` z_L~GaX!&yrEC+JmIPQtTbRF&_*C^N6zdVi?yGnu75Tjq@re)XQnfdPZbC`N*S201h zE#;!CYKvb(c-ouYKIn#?d&apvuPj5mu6}F08`~|XuhYYvcyj1S!me4#HJ4y79MNZK zmTxDTleQl1*91r>GNw6->>EZ*#x7>?XT+pjN-1()XHQN0-T_JQHI zZ8}dbM6c!FI4v&qYotl2T9i(|K~9y7#HZnY5{49&Ja&=X`Z8!eGgT2QuhJ&$9yeSJN( zCgCY>l(?d&$lFCS-+?D5R8LTEf3&rz>GrdeP`3`rt+L2a0Y3QiP~0d3pMLb*iarS4 z;BaQWSqoi&U*lHUcOo7z^)^DJhLsdR`#HVxkX+~p9K{Tkb4v+BIREPYO}u>n6EdQ; zALbMGS>@lj>{ttkC~nPC&qmZmmIQPjGKJ(Cz`_aVMklofWKOvHFzo0*vfR`@BPrPB z+qshJ`1&Iky)KkqRF?k~;0UXBa1cP8mu zChbL?We4rTYkVs?n=^>yFR~fX`er>WW(~`m?(~O9jjWB+PoKcw=WMtff4f)|2*q%G zcn75t{f_k`Z5MuNukxJGSarG<@0R+e9lLAcM1tP85AUTYDzMC!b+-aouA05m3pFMK zE5L^x_QQ1wvGtQLGxAePO@N6#s9dV0hrA4*KCy4EfJ>CqRMozopA z(uwsJlDg56osmkjtTerdTYIbOj0i{>AwMdfHzxA77VMuIPUD!tV;@f89gsq10T0e} zzBPKVv_Y!^`Nx8Ai9D*FvF=0oFXz`Jm=&s3OOwRNhSxx^UV{?r(5JR7coY7KFNpp= z12xXrsVYzS%jAZG6R4_)1e1s}N)8*hHE&bXyd|WN59eJ}m+C{sxMxo9*2CJjD)ck= zFnAZqL<7z}$G1EmG8WZ)(@M+Wzehn*(!pJ78e2U){Sf3gfnfTm!J~)>ezfF`ss$<3 z!kU>lJ&SZ*d-RWN#+^=zWV-o=;JVGDES{Qd+mt$_V|TuVd<4DZRU)*R^q2E@dBkY4 z&a2wcs^byQA`u8M3VKXeQt>KA?iqJP()~jqeWVc_P%z*_UYev?rbgYeXY5& zjgQ4WP`RbXwQ_B@W`9|FLNq#hOJWk-;t(VuNpiL(R~{Og!)GL1;pS;5%%5%n1<~T{ zlqoUx!$(v7cGZrR>Jkds`6ze+Oq;b@E((|}mjuEpn~X9<8beC3?Pc3EWil(+p5w+% zShjGN>uM<~6ts*P_?D;(0YseznB=dTrKCACTJ$4i11kS;3Lc?v}o=W>&^1ZA$q2 z_rn)wL3V!?s?TF2MbLOgt}32#XS!0Kb+rBt`aIzGnx``11Gs00o&AuFlxf@ZEZ!0_ zhv(99HXbcSC}wiHY4=7+8KVWNH~5}1yBK1_`)~czL!Yh62W^)2R-F(jCrrRKm^(~e zy{W!Rr$ekFefEofep;nW0eJ`0H6}8mCnrK9l%_&BQiKO^7(D_WAyx%1#v;--+a?g& z@vzlY$v@=O1v>bY1l&rK*T}#4R!hIZZf4>U#qfJIDR0t>LpM^gFI0A)4uL9%5Z%@O z&Y^3qtN^qN*|D=j#t#&KDbk?h(x(g@A~GyCO_L^iaqFELmEUO36qX^6Sbe3&yd)vr z27E&zIFLPX?ctriX{e55oAl)9ndG$qZ}=F^M6_&i0QXk(DkYj~VNP(!2NZ&QQhqrU zkj|WcWk*2V3{8F=+!<7s-%F>q$~)_gvy4M-tYU_?sgTsx2+C$UDU+XZ(0s9d-XgZ|U!H)mA0!5qY5<-Ce{+Qb%WHBZtcz8WEHdyt*cv?*Qu zRJ@z9mqS~#$L~`+zI}8XdPm{JORoa`xD=I$A-Ze+ZD`!`BG8DIE(|(6*KqcyLu)tBAgW6VfjkNg&oep zSS!$Mly3CT(F&)h>c#9akj2i=uvqhoCsj84Kp6Z z{IJ9j%yT4B`h8Ix#KFL%UH@icdEE;A7$a|PRJJwolkc|T-_$p&AK{jXtwCHiv)Fu@ zQz)^i<^tU}m@?G2|J38r!>K7V-l8x9S&i@Tuu0T*&Y`PR+*S-E^?n#hmuGt7M41ka zO(|3Dtt!aU%ka35KPkWp29zJve)W@&xz-BEpndYNxn+5?V@c#y$+Zdu2scd%Q;>56 z|7M!M=cDOA&b;1J*{Kl5&$GmKsOur-pMRP+UPjQMg=wI~dygZivCF{Zc197eTQ3DZ@)XG~&0 zdD)%o{Uj)g>xo!h<)`}{V?S*0-VEUmTPEa5Z|Ou1nQTzjB4h%T0?iR^`@cP_nwN|J z0&Cdcs3!o+5p~bAr>cxfs^Im)4i7(i`p;gFbqb$ab_tl{g9e-R?id9F*_PaHE(WHc z!$GJ)DCpw@vGy#q)hsKkCW)27r4(JBy+{54AGM{tyDxa~4wS#{c5At-MabForS(Yn zQK8m1Ht)8No{QgH+;aj0G01a3Mgc3<$*RnG!vDkxJbHy`RajfjtH+0j#UL>DkdYvG zk(<{c$Mbn*5jwSMKvVsyiqK5Y`)A=dhM#9CA9oSQK~34puMMs^M6psLJ%@s_gr_j{ zoa7@bgc3^He3byIL<3iWf?9Q0J~HExD=V6M%7blm3^P86N!a!(tl8;ZY4u8lv!9It z*#I3&H|R58)d%^D%eMWMzvYsgk;oFL$du17Y`vhW>1{3BT(%HCi>}+nJKKDIg99vP zFv!2%d=v>=!Tn+mdbc~35Dmftdrr zG8Gx)_lIQE^Tg{Yv?iz$nkBw#;7SVU6t^uLMoK7Y0=$HcOP~#BF@znjyQUG4i;eAz zb+M+#wCfE_qBA5Z`CD98_FUJ2(w&`w&pg)}D44((Xs=C{FvQEpL~t(HoI4!$W2vRP z?roh0a{RBjHT~qE%Zwd_<~~y0%vw-K1>qq{2$&^Fgi2@1&(-0tYBNTmz3ex0*MaQC zfb#PvCMK1Wt`ryC7QHBQ&80PE=kv7G2igU{1a==YbYH^l4%rgux`iX0u#12K@%oFJ zhH3apmOvc`5m;fuTa;BdO0HZ|*6)6_5pF!K>a9pkeC*Yjyn(+wjk-=oY$qsVA|dy@u};1~RSt+gThpuor1vb?3MqOA>QL`(m02cUY%4Vl=pWf z2NU2pJ>-vCvbQLsjA5(oiQf>_jmT56KuQXUZ3zQ|LXA=uTy43{{mX%tg#ssR;01uV zF^ClJh$U2tmlC6Q@z@}?-xzpg3itpqjOa3<%Yjee%pS16wk^zv(TR|UVWmEn zu$gYXv6uo0qNd}-JY5Z{tV~@EbECn9#5oVHb2@MzJNlCnY;slbT6X)wC(?M`ZwBhs+ z-X@C(y22y<>ZvMYpk3?*5P!e{`g6jvzm~4~6r|VVK${qWXDFNq?FYKN3GfacWxd&B zWIHA!6bz1Ya!1*%jeRs&VQmhTm9etG1&?FJ-zaQ~< zxaagUd;*oIiwI(ZQ#m&^9tD=oYA)wzZpcb}jDbn!B$8tM2Gd~{@Q|KC*6tUab-@Q& z&mz05;IsJnu1cpd$&yS=B$dGYZ|HZAz zQBQ?K)D<`g3HbkF(f8Y9v{qG%%Hc>1wC%!F#>2e>yFh)uq)&v&qVBD$zi|bT@M+gXOCAf3zie#;I zLJaaV&q}2|ZmmE3lkoniXdSZBRH;l)&ndcrQHKx3@uj%SD^eGOul!hYbC;KvJ_Rof z@79PSkihwnqEkNPXgIJ0u9vPcgd4v&@OL|>KCD3^LU&R@p5P%CxOvmfX}((!=oqO z$MS~4og?htjs#)03~DY7<^g*j6{0wv`C=#W&?}Z}1q)A3DWHUX8{h=}meuP_x*cG2 zS+!)zOK%K-P1?Z>ir(RkHt0`&k~8-wEBJFUT*sp>jS5J0ET!E(9()UQ;tK%>h1o=! zxOmfT$gNE4aPW{xHo3TTksnZL@Iq!^AdsJ&E)(~|hTh1A}p<0r7BSLCK!dr&8JdN_|DBdM| zb2VgI0AZsfYt+D$L?9D`T48ZIWLhUU;+#`{fs6x3(*J{c@`t@N-27~@`I&cx9#UBt zLM@gQ0_)(KV9vaq9Zf&72O~!U!pX;&z%Ix+90OYm;&4as93H*)H{L=RAN&H)0-Z$R zS~4HH4He+po_QFthM8Qjf~iD!ZdQoAM;uoSgg-lLfQ#(tY5I{R3%Pkb6Ny>==(*DsfDog+CpF zRyby{)6h!&@ib&RBoZ!hcXfv^b~luhrC(QO732So^$l+b11}VUX&I0$6_y;S9;vXUf~ncrh4~jz(WUst3L77}FsEs& zLfyHk%F)5H8@uzN8vPhPQm3Pr4Etx2M@$;)aU^>)AXgS<4p0j|v1Iymx-K&0@G>v8 zq>;o5+pjU3(Lw0*@j#9ZV>(W?NX-cPX5_rCAaYWXgGcnQY(#`giz+JEUV3$dB}@l8=-h(dTl%0Q4;tXdR*15u9$>>_|u(z|8UOT$Bx86-F1og63s_sc{8&*CK4Q?v{d4H6)^M*~1}MKKrBv6-SeU)83(oLJxz9{i zMV)E}J={H_M!EW&=HS>hT=u4y3#j=L@TuoTns&Wv)DZlw3f~gWfwSz@5n;iHXS!M{ zQuM{!vIhw1ma3Lgdy14E>Tu{X+ca1qo4oH>pcCZ!)Mwfx%e{8rJWiE0kbvR~)bU_; zf#&YQsht8`2oxIyi8sVkWr21D{KeBiUZ^pY!2y*eJR%k9U&70+QA*UPAz4tlHvJ%0 zf1@@UwRb=_T{l(z?hO{8gERo4spgw^|^`TeX!krO~kLt$8?+>Uj(qVx)-NMt& zQnId|5hmUNffC-k)_7o8qI|SLr$z69tEnCBMA24QpgtRTg0WW{px``2HAv$XUZvP? znXZWNf0vL9j@Jm>u`&vJd%wL8?8rD*lAn1C2pAeB5QZ ze)EmQ`DE+3s|Rt^DtVdW)4ynjxt=7WLpJ?(S$7voQ9(!R1AON7S00`x3ZYcCUv&?0 z8ToiDO2pH5RbYp!O~Ji+&&7Gt&#v{IoP`_~(NeHJ$mehw71oZ<8mv_Cp^VrtkM&l? zg1QGD_N;OO3YTMx?ClG*e+ZOb3ba^*o@vbXV83$31rS3n`I{8$L*Pj_pi5|8yWm`O zNh9YN!Zs!05o;aYOaT&EMOn3@au_hAd3&5_D#m4q3m4gqR*wb(f}iM$vcI`h`^bdB zXsP~G@oWRbZ%cm&;5`;^d4-TgU2eR48V!harzv0LufFIU2ZF^?a0pEX*R4AFoyHD| zu}O-MdXCWHq3*ZFu^%DqSfYztyXS!rRO2s7Q03xDm^koYQb{l(T3+=h)MT6!QQsSK zx)Rmf-GaC4BY=MKIzAt`ZLf^7BTMdAVBrG%{sCQx)U2IaURhMDdb<3 z_CE;(STmZ>fNg6#FxJjzOJ@JhXRA1Ogj1EcC6{+lk-Ah1hO zJv8!Ckj|(Cz{>SSjACyoU4O>uCAX-xk$;g3@ zod_jc?4ZnVM6ylkQJ3Gd%}j?lz%xf-uOHqQm@yg6F-sVfj!y*Zsy~GVTS@udQ@-aF z_jpw6uOiL1F*mD@rVaw;eN;33O$hLwDzQ)N00;Qpj@|5iYe4Puxcr*n@ve>jICf$vY8nx0I*2JQ zn;lNBp{wSlG1SeNjBQEOd^s`R+U?1iIqrcH=E)4~Q0+#|m&GRsf#Q3@5Jsd6@VNJ~4IZDoik75%tI8d*|H*vw0C9CU*#P~Me}m3IyY_zv0> zshmY!6gq|y{6!>;>@wE)0-J2D;U7BHf{3P^LI28>zR4T(OU4nN(%;Biz7_*y%5_{@ zOjB8JR_HIOG>wStr;0N)|6qI&lT`NBG-s~PS+>&J_g^x3=^W7<*ibuRxLNpx)84X` z=quh=2|`8nR^vm<`YzUHeey&nk4lDgBvef9ac=l0-3SfH+J@kH)8FlKm~E-`5O_ka z44?VGBoo&TeDHMl8*qSMKB~AXBU+29#uo8ymEBpYD?`W-jf6r%(>k9GQEU-*d$E0?-RsG{*CndY4miM`e7ymIwOx=e$FB{e{8b8!#@s0KY7U z?WkbLDw{62j2KmP>h&r(r$YbEq1A&isuZkR$zm4IEvFFT?r%**iRIXM{)$3MbLait zyKIv=&u5a&%;s4_Dj$v=Ia0dQ54+h59TTR4>{mE4AOyisw)$xFl62I~uDfOMyR zHg)9lv%!i|tyftoE!Yqv9xL$-vIl-N6E*jtSJA+vw<99I3(Hy^sJ!%2qTWqER z5%9I+Bbx~@&va57DpYix#lc-el8Q0BeZrm4JP6s-W|vhM|H-Is(oW8@gtjwRlvH~N zg^X7uVEdBQI=Oz=NxFYDsK-6^)Y>2ClZ;d9tX{J%@r)OjH)B*#9A)rNCGR9jL3>7P zQ}$UdNdr>uUmjK34))B$dM}nKX`9Z79>C4MyBQjH4l*6*L^n{z2M0E>p`L6Ux>{&!Nc~XI454~f1Y6LQq7B!RR+Ecl1&ND@>+R_7SeOr$IaF*fm z0dmHL*pI0z8WYec=@`&zir}_qEani|Fpp7)ER*W(r!ks0#60H$$JiI8$$uh8qKFO_ zg-J!kk$2nG-jO;FBeFd|XZbCKvbu`3YDS14qvZ_6g>#+*2-Zl{uc1_otsO2ApxoCG#G9t4#7tn2ANUP6ESF;XH6%Pg-B)ia@0j~wNameApgz4QW$h| z*@gx~^)Sn+8GK|JP?(Y|M9Y#g3(1NS*h|mwrv&8Kl}C(B^%PnFTSqoDyd@|!1*1>% zdqfUwMnO<~xId@1t`Wz53+DR43T1FPiZnurnLu=d%(nbk=R8b{TGlYifG9b<6SoZc}4oKXkUH(nMNd2kbW*eqbHv{q`s_bvAlvLaG3L zWPAbvF&Oq3t@NJ^pFyRupN2mHt52z7r|4oK=^YUFz9#S5Wwblp(j=^yyf1UG@`yk*+e+vn+FR<0(J6v#_-l{_^Do%Ff@{K_`acZ?ZECztOPO$B64^MnEomno2 z;W3^Gm1u`}?p%RdU7@j4yAdpBU&CAa`c*~MBLNq3!p6}EQ;}%3;VbSKQZj>O7_{(o zkpnsgsb3H#D3I0Dkrlr6E}&Q+mV9)#zT7LObWr%$TZ9;?oQSs9F}9)DCKz!@YXF1| zir3nbhkhX<=ELVbg};6G8DYqRBC|Fj-E8GhZ>|(W@9Mz!={XddBlEq4XI@%iJQ8xa zdREV#E7sjZxu36IHv=Mnnk)^Cg0bb7klAX?nIDL^;1PG7baRdz8@a^APCA{v@o##s z7fsxiqqMf zYg*z`9uF6!cyT8*C=_hXzsDe)xZSBN;;Y{&Cv79v&Du`nV%>feAq3vQjQ|TPpx)GR<(3)gc^0+gnrVKA( zMdc&duY@~z<;a6)I4`KsOY!Sn8&ynjjg0iWvPuZY7zy(oFI}`b+#KoYkJcL!6kS z&2<_&TSA~{u$yPr(7pA8XMt8xcvLvN3~a)q5+~HfeYOm;%xs?vI@gd98sk`AzCAik z1Nd2_NMH1nk2=#inRT{gW8_zG|dr!0g>#ZQ5~GppCn4Btp*(h=YXux3!TGsnX0ar^i*4x|i_{VRB47Jh0HfeTnBp=zT97B=BD zc$rN==8ESn#bO?>YO7}YZzHiIzKOW*-QPvYN83jb)OtJS-(B`>s0U z?nOM%z$70^d)T9 z-LfwQR;Y4j+60m3a!HTn8-=1gcBh-e`b>ogLG|c0Wjx3W&?NZP?P1cDucykzA*qyX zHdCh1l|*O-*xegFQz<3$!;O>5$q#tCn@{SoC%-`lV>)l4yr~m&B6_gzp;24*BYQKh zUEE+X51Lh?`q|)JghQ3Scz(cS5}K2uQWI_dhh#CN4oS&w(8*bMGZQu=n%-&=`{L5| zFIEh`xrlgP1fhLaV)|*+ulb0u*Z?9J?r%ls>58>N#coJ)YFf(Ik9e2V1KCzU&Mi!i|j& zRlGxtyqvw5L*;sBP9+%x`Mm8WV>iy$oLq5fxZUNGsDdUAR4Ost`jM4(%`q75d%OfF zX+k~3_)qe8kxVlOxr0OCJb{AMF-(9gMV?PfIlHiVKBJlF&2yJ6!=Sh$Ldo&?;p9 zwG;c3BP)1r&viDZdVI27Y;ahc8n|S(9kom6-hTD6{yRjO8ZS(kp`jb|$CFH$n_p81 zT%?i&xAal|O%wSDfm|3llJ-n~SfuyqH`E8bTiJtB5!mn#HV=ryVDMIWGA?|ZtnL_G zZ|5j>i&%q3#vR5Uhrb1z$r4|K#Q4+Mf)PQt*>2`=@Gjq{UhWD!{iURRC3v(@@-)gp ze9#57xb^xtzD*yZe}FONBh<18;dnlHLkP7|OXVRzz8k=v``H0eBs(d|CiR8ob`Q^^ z^L2q%VLnw%H5e$1Pd(Z!5$v2`qB)HANj^<1?W+m;3&C9YN)5pj@3)njjq0-|H16Qn z7>J%~>1^+$sKTmW|2H2QWc@n+BH5E zzy0r^76c+N=3|D>=quXEX~n73SIGC$d=A4yZds3#T_qbEZ!bIGTm;d8b&;;i{UR5% zGGn?kvil05beCsWpjcJ*$VP(0tD*hW-FY`Dy;&L6i=CwWTm;(Ne0*W$2UO!QPr^!^ zJS{6#95;~}Im3*3*_{W6suAXKeHcoRe9Jdhc8u;Fj_@tE!A@Q&G*fwoUOVDo$~A}L zI1H%R%Y>;iR8Qtw>`jc0zO(8V;~z=C32d3H*p_#x-|Zt5=2CX~WiM5EY8avL$+oI| zA-t|hSc8)4dGPO_wY z&$@YfRB&b&$B8A0o&lUR>6=%f2DLkne#Gl|tH{F9ZO2njN&{;Yf-5&L-mI$2y+8V4+6^prAyPd&#SvnAcootu{=o(3#eU)nU8e=l zTp*2ugn4|K@@EPTfNs;lTgc+O|YcEu!{J1E^AOEQ_f*4*RT;>wPJbg zP0~5TJx1OMYl=E^iY`LI41Gk)ooIML%cwd_TyC|AO(TTrIABd=`JO(Dk;cM;ZCv~& zISb#tI0pV3bMF{r%d&-wwryjzZQHhO+qP}nwryLhd#$#O)wcWf-sjxA&y9QH#*6nN zUc8upvZ`{9%FK~DYmTqJ{KhFjul|cO)u=n!jt^20wY4};3Req#y2QX92D%V2z>8yP zv0ME*&z>bXc?UWaOsr=ZeIr^j*^T8N%Ja$Sq0*cT9c$8D6U1hIIS!LZHA?PGJc$)0 zSt_T{#DjH;4DJ?^Mp2hRuyi4yWec9iJrOmNx5R=|W=GWgwjK25b~tbsb^yQzYEPaF zPym{n$a_0=bn`=pp%Wk~+a}2cFOf{${tt3olPM?4>v=)iP#P1iC{3v6HV5Mea62*2 z;u|ratKWRIkqMdT5An!ITx6gGjx7Ce4$l|E%^+~-)0MBKa$`}ZuGyrYJ<9MXJ%kpP zQduiulo&g+a(x~@tS~|+y0cOGIrP9cp~a&6aWL4O>9|FtMPzW7 zz%PszPnEU`^zfFm??zZ~|Lh zsjPsuky>;I1ybevcDk8iUmO#OQ`ri}WQRh5g^FGF`@j2fh8k$@_~&-!3v&5lBx_&% zJUb^lRn4nLq`Q!CoCYZU$&Z>b3S47n=Z0E35Q=OznLc~;p*f+>(eN8-6@TUG;+7X- zW3`q#GAY0{l06dwvSdFzAFMtf9pZxFI;oL=MwK_4s}JVEh}|Gr(uPaX%+tNlP`;(c zN-1d9v#Ve42BE%_Bb*$U^5qyak7xrupy^#s6}0u@_GixWBInH!jo%H;V6nDTuqsx; z^m*68o7)@NAZ@n+H~Jfr&}l;`=9@}KLAQ&RF*mCLI<>(lV8 z`icsKarp{Ty%z5!P<{PRD-AHAIH&b{{-IfIA^fEWFZo|empoebBCOGwSPEBwRtjZQ z5BympV zIX_8>+Gg(tqsO5LiuG0!W_QQ)9yivLYRW&e%7HWTiLq5{q(7Gj4(0^if|!i2{Gm?D z3(WXt;Ya9fMC}T2H0BwkYrx79ZT3{?n1stRVKqX0AYXoVY3V4Q=>XmmgRsKoiF23) zfSTG2WEg^Ig+wC!nPstc(Rs)F9#ouuLhZ;nc|1`7mx zMA%L)+!y5p7xSaYku8j&e{j0=2B-I+nds3OM07b2e`)Z9Ln?A;|H6H@gsUuxUIloQnqtBL2RT`iuwo7>#%BGvgHy;e zi!g);C^Nw;^~w2FtF6aD7Z)m|@Qc7P%F*JTZ8yuHu3bRa=JT-V&uPt0YTt@nUh2+| zO*iYTQ%K=tx8-k1?y94viqE8FJ!0~8$7XSLFDIR_JXi8!gSvs}=UDYAHs?r;cT68V z85#7*Z7f;Rwm92Q+S^HXYqD*Fa=bZBa$Xj~qVAuT`jqqsDfcVVdk0vJ3ye_my?>&I z8*$myZJB9N2ZV4(xeM-%_ap#-2Q)DCnM1)ATsO2$?GM(}*wi7$j)Gixg7Da8mPOY3 zY!k1EQsV1W6r-Oo#b7KQ;yMge`xd8U$r?{u0BsZye&fUmW6qP(@MA);a+SDNhi`|W z;C8uKtX-_@gI}2hxz?MJoI+$LJA&s}9;s25|8(}i*$dOp#Ba?;Ctyt8Ys!kLNuP{s zJnZnYGNf4%XQPku=FB}(qf6r9oGG}BD%i6dzyJw(BN-Sq)55ENz+k6aapGqe`5hfT zB4klb6s5olv92XP=;R_v3724n*NNJCWY>_QQa&Wi=qvq866g?LqlTtKP#c=4ee6jl z4!}E}8ui1+2GA|n8C!o!EXi@Vd5sA~6pra$|G^!>jFip^H;_2?y2`}0VOG{mIu=N- z;cy_4E{~<%K*bj++k9j}dKFi|4*<-Tk3Y*sL0Iu?DpJ~;@9jbwJd7uvMI-f%yY&tz?_5juGGs*IXK*A}VCGfoX%Brm zDB2upaii(H*hgNeGWs$jD!p^PCWoLy8noT5@j%LpG?}b*VcsADyUQIr9;d+gk4HF& zC%vY;h9fshFDuumw^8If3u{M-V))=zNRt|aiynJefWFbLNF}5o(mCEuKO>xg+ARwcWts=s3$}5A=X#D-6DgZHg2( zW=Rp0*2JM|NinDf&%dGxg5oZ4AsY-aD(UD{3y@=~xhz$w_p~kGg0!9^-a(*VD}$Z= z`cD!@(q+Qy$TMS~4}>hEPC#h;2(=Dp66~j>;6bGAceBv~NDx&^XZlNv7q)%jTTEd( zt&JZsefYsakV`BTbKbdCxok4ex{01;bZms`Id zmuUA>)@j_m@?Z#UZxj)|?E8YoxELQtZOHa9Jk7SqhWR;KOU94;vw{7g8Z;?(7aP%b z=EC0(Y#v;k7iHzedi3LG-ylXx3m>_^HlA+TPr z>>^oh2?aAATkqt(&Ssnad=9yMSftw*Cmg@);$&oE>x@ss$nag~+oYhNox2vz_ocs2;WN_H)8n%-vg^u6!`Z0ATP;cQ@SVI*K{W^IB`PbY0+ zU~FM)hR?)AC*W%Kua+<~Gw|}ln%EkDYZSn;{*}(}yP(Ca#mL64!@$I%#l%9d!@$Cz z#lps_!@$m{#mLC0qw_!O|06oD&%4e|6|vJMz2qPml0f|8j>SouGk}$zNCg z?Ey9XzniW|_x)96J244i83TJd3FGh9SU7w9byCU0>Dze{wx)LYtbglL(Fv>JGkg#5 zKg0GPP5QT}trqLwBKZGw_kYu8Wn}*LoQ1WsiQ`{Rb~X_x5z0Ujox_DjMhi|qqi*9GXlW~Y5Tgh!}7yJ?E!hFoQ$7t6BMO=kRs zpZIJ~F;sz%L7?0X+2<@Zz1EBz3paKsK6dm?Ak%efa8i^xHh1ji+$f`6Lzv4j!O=M9 zK5$P3r)P)((j{_uijdSEg?x*LH=LaA+=B7Vu~$}8&`o!JLA~(Yw5mN_KoI8F zZl@5cPrB9|kRSWi1K*$~*e{Y>wj~GT28SCAI6b2P?vX!`?xCPwHOz#+VCsky)4YAC zH;s@?0z;`T@dzcTpQ|_MP=m3o-SpxA{I~V4g71?f;8s zmF-k)E&du*eAa(S1B=*xAAQfQ|LI;D@&D?>f8^Ny$Fvf)bF}$h1GZ-03y_(f@xO`s z|A#Co3qA8+tKs`Y%fQOc_J32B^e+vyf2j$JvVG65e>M3Zu~ItG|HwP}ovPsPHLEUX zXlY{PO!xQl|Lcy-Z0xk(R+t%CY1tV6L$}n1#xupV0aDeqaMJ<_RvJdsCOGU+RQ1$7 z3ctR%v(Ra_P6u%d&o|#0LCP3kpxjFBw_rjFi~%Z+CF1P2n$4%Dw^e&>->~D3p^ZfR zYJ_|6^8CCGLKh>7Q(+PP9IzY_vqy){4SU_0e1%SxtvM$RbnruTtu|8>%yrQ8@=UGh5Tn2l$zJn^c6|aBK`S*3o;-yFXuto&_SiDSG~&Ft?iZmVRh9 z9v~Uf5pRQ_HQ7Z3wJ`9NYXHYxIzTxz$tm;3W6zOAgY9}LGq<97(mmHRD*!}NT3g7V z2zq)Ab-M7Nbe`dnckPvsT!+(OkwDG#$esnEphl8{j;q1oiJq7C!=8%ZxCk;{ZDwjB zH5wRQ(4;zhr0qLsvTG&Q&y4KeNv|gZb;;TSdzk?vt%M19vK3QQ8&^i1;Yd{=@W}$X z7vL6gI2vK1$@utzfZwv}7yC!5?fTXPNU`i!Wg{+P3_(~e>Wln-*=_=)R!{`+Zbtz+ z! zn&$OO5zA2q@3hr$&{>`w+{g>A*$1js#YEja)P*kg<&Bn~g1;tl@3N3{9+F)VRSs4L zPH4ONt*i>}o9bq-mrGxDn~$-D8Q2P%KK7V3bX8+W#6Wimc)`el6PdO^!Pe=0ky?pF zF_`0-l6In0F|JF$ME4=$jz-bY%dElBGbku2XEQ zj#Y_IOz_EZ8Aak@4;Yj#xCFry&LGcEpPOPGUI#HPG=f)hi! z3YX7CJ`vh$(N z(muJb1t0917F2`;*J(xg$k9 zc4w-Ot<`K7`ctQ48FnR#LJZc>Y(WQfOf>@u%NHjVw2iECOD5(gS_bmLevCot)~+ND zQ13QFwSz7;Zwks@=aRk-Ff%OvhQgyI*3AKDR2){8sW`Q|e^s4xWkpGH6mhAxKG*3i zgJ#?XOZN>}VpKm&ZPcE#_QQ`_4?OF-?><)@^m!g5<*Ur~CICwlV#dRs3=hnTP1Req zt{;J-c4~a|BpOM?H!1o8qfr~_`)#dJGZb^Tx1)8k!<9VVgp>o(2oqEX$pb4@xfNLV zlp z*bKR=AAp#aIvcw(b$wlJ8UnOZLxmD!U!g&msO-9W52|ee!tq-UQ7S4FFA*%#iDAIu z{KioUEAA2<5QNdTWh};(e%*Qnm`D<>s?<{s{v=tt!@`zy zmSACGvtH0lP;)D#Kx*~|FnB6e7?xFR7P;|}aItrtzBa^84#q<`4mvxk#rxUBOI9Mo z4?#Dp;x%gDJQQiW6hpej6Ofrs>BrFeqwdEAyb0cMT(nV7D|P2^R)w$`D1y9XzE~IE zv=ezhoNZ;gsqv)M8IMb*q#6^|Z$78;3eY!b2ml0cm10A-loGpg_K?+KgHb~`&tE}> zsP3IIucMuYHSDkkeal{o%tY{FzgTdQ1|RGQ)_#G8!><-RRXM#(md6|?)2_U5I@vu8 zP-p-ufPcR>pyfhOakN+K!5soB#C?A<8A)GP`U>XG;xhZvxXtxD0=6%JDVL8)Qc~AY zAMsAhoVgTyPI+Ky1ALNV5LgPP5DbqFO^e2~1(}Sv(iw(}&lZY;WpU&jo6C=!t4D*L zb67L+g{fQ=L0u9_hZ-nL9ar?KU?mTOtu^aGCaf69+#h1}kxpoh1Ai%~)VXl#}>rjc3IlBH9h5 z)TF%_ToaUOo_HJ&_2&eDt#Pii}cB=0HHO+HG9@_(oW?{FWnR%nS zUS!Ca*z2&MTv4@;ay9c^ruByx`F)vWaQrL%0Zx$`qgcsAuo{X_9ZPoy+vx&GYF$kP zIz+LeEU91D#ho`E?nKzK0Sxqt#`2#y2W&-tWDWeghXD}Xye`Q|e7an>$)Agh|f+4jhmTLRe`QX8{kwHB_abR5OGK!$Q4mrp# zflP%e*1LA)DuMtgi+jcum!tg5CgnnaFiS!a+TTqF{FYpxzl6rxIpBd6)G9PnGZD1@ zjVZp`dm%Ay2M6%5Vcld$0n-9k69S7Or+mNJlQU4SAR?Z!a`Bx5^f7vSbL){dPvpx@ zq>3m@BRa`wE%_>Bp}Vw)lqvSig#MyZGsu+`&B4$2eZdg{Q%v#}z&i6oLquLPzZ1KA z`i0m_(sJ8tk{#!lmcOi&IQx!W z?~TS8GcNXxo)cJ;RX6#sgm-`~E+KITMJGtqT&K;;Fi$AEDwj*%l&RJURQ>gkSA z6ogVP&Y}#`u3VB@aK~M<|I8X{GL3ANED@lBGaWw=R%^8IlLl(Q`$-rew&{#Wt;$C0 zu&A_uaT7RD%j4qto!*C0kEA}a-WrP4p5(?@@4gD0V5pa+M>#Z<^{W5(Y;rV%6={CtWi;T zYA*$QH96PmX$YOUU?A2b#KC6QPIfS9`vx64n=fZrR(Q0@qmjjTi1q%%oMMeE;J*ub ze?x?%TsUGp>!JI~Bt`*>`v02P%4_NTWN<|Z!)je*g*d*%qZ(L)nuCLO<<4-?7)K@v z?v-QF1WRt!xPb4n+Url=lW0&;e~c#&Q9!e@ zEmt@AqO_O;xGyk0;))^@45p)6X#}P8{*8nmyv=lzsq7MWUCrz%_#1nK_QfT#itLHMRIs0?#1yr+WeA_B?4q2~WlH>3OY>c;43kRtDZ3)I>ss2#lX zkcnM)FO_Vt*gvoGyi_P30eSKR&pmaZp%6N^yvkP8wcFpM(;WnhI_hW33Jt=Cl%8{t zGMG~T4{B*t4p+LhCNt~J5(f%Tq!b{@f6bsw{bg^$zME`T@s0`Q= z(s^%9y{%nfT%#=Ktng27t{8R0A8?S@Is#xA3*rj19Qlbiswy!_&U@`t5wF=@m=h&D z;MkJV#{Uf(`A6IQ|8er9ZvaZ@8$S6)x}5OY{sIsFzf7L=UvoAxekW=9H}1jkom%NH z5ak;YW&AGw3wRS{`Y!$rtkH=wi^J-r~6Ob|Q5B<|YbE(6IWaNYecF6+N26enc>C%-Y>ZcNi#ZE;1H$ z(H~sk!=#uERS$ivyEqrkJ*oub3F7gjqEuAUybQ(c!anxzv`@tJM+LgM03EiOOa*3K z_C4^HoB^#u@GTo255)7YUI~0*to=Y8h>JvGxJ=;M=)xY)ut0@)ISdNuYnb54lSS}Y z33#V5X}4We%2=2L%YRVY-ZW^;fZnl0qEWf6B4TSx9zLoMNn<0|O~YVaEuBAxqy(ND zu!xbh|E2f{Y!7HYbs|Md;<^9Hd*tjY#d|4jP(^3suwEIh&U9{b5Qx9;ST5tQHujSz z3ygB^rkw$4&if7E{!;!_w{N9IOg==gob)<~Uo5*&$}$HJB}BZP<}&K6Y&iL<+qyrm zp7o505+xI*WhR(L0U*JH$2Trxm{;i~K>5mRB`!DF!;tO9%cu~bbE7(9Zb!~8V_(2Q z*c!eh5AxIzazYI6^bnO)=f1v^e0SC?9bN=lqQaz$2s_5G)lk5mclrLOymylQvN=wL!}n-s&05-|;MQy}!L>Fdsv+L7UC;cVQ}B(~o&YwJlw34jar6jF1MB z-6CT6!+__KR%V{GSwXT_H|QBV#bO}ZSoh+8{@6J6L6cTMsz_Se!qgs%RZu9_J{-(t zDAWT08KLU`-RF&hc!#j3?SMy}+=IPpx!KA$?^>5b<`oI+$-kwHM6v)m<4(+rmbaSj zZalt*5Rlx6x>hz>SF-fN^y=*v#Be!E@AzwrK?TH|w%1?L4=VFgZ(tWYaMue%n7iQ} zyUDHkzWdaxwsMVc*Bj<0q!eDtq=i&#Y4Z=4#}$U~M!t?hQubR{L#+*gZ|sQMjU_24 z+$-met>Ve-rZu8^cYgm>In6BFdNo7+S4h1TxOzhyA(JC2O72_Tqac47iN?k&nxdL4 zsS^f!?6F94PYpBL+xCF2F9W5f-P>nl-`pQEf#y0wc}_}!-h51k`i<7!_9^T_F{=a) z6abnl;a=F_x01I9&j3FKtG9hd94U3QKUI(2z{`zl@!&^o`fgOfP@~~%d{V>)KSLa? zkQ%isnkFLGS2Pi@q0bc)67Q+JKf>UG;3}b!;?i2sP|bg5^v|+pZnC(AIWNjOov^0_ zGAT2s3X1LR#*ZI}1MjZSLjR}=l5i$75&MHubjl;6-b5vx0jHQoj(vS=WFk|<5j#(y zgvm4bI}S>EY4&LnD+v5lOx{?K-KE_jy&beY$Ca)F-LgTR*p@746=ICqiYJWS1I)vD z0-iGx^Z4p4>F$F<5Pe2?4uUGZrU*=aNy3Pg#j~?RNo3uU1ospy`({90A+W{6Ha2qQ z9l^_JrUOAVe7_1==*+g_}vSa-5oWQ)dVuz{*hz?^Tn^}D~U;|Ov?<~(o zQgP(Xz+tSVwlk*JqN-UN_zdYB&jQ8PQo*jo!guS>u#tXt232w`D;-W@aYxyc)GRZP zJ~QjH5#0p)ItZe?+VXIyIAF|Jy7#c&6(?{SbI=aH+66AMI7|Lu!Bm({HzS)>CQ{~R zO-N(uguM81^F6_?Pc}jc=<*_atCw61FPPU_Pqp|ES}`WR*g$B5k2I^(2JmKbk}@WJ z=>1&G^D4iRA5G#oXS9Qd$$g3v$%vfSb{8t-wV*L)We5bEZy`*QPI0(9*MC!XLhlT_ zNpTP%+P90L3bnpF(nlBnAiGH}nw|$)JSumtc6Mi$B&nK-L#kd>Y{m*U^YRvB80BvkyqjmmhDLUp!X4KXd&Bf`UwZvhrH|dLY8=9& znTuzzlp5lRJZ+p^RrQ=SNcenw6yF~E1B(x|DycDb=ZmG1$MRarP(rJDhI&C`UD5Tepoe!9AU>v6UZ;TF)yp#kBNE{c-|Ra>$@pjIR@*e z4hMH$o8ud9t-*KH$Wi#s4plFBmrslHY;TnyRJ@1L5DA7)j}9U1VjP(LTUdyh!nWU; zPR;$U_*iCtP^h{|Bk<{jtGTOo1I=4tLBtgbE88@KdviU{?1SH*@)q}L)4H7HXqOpN zaaw`~614{AASVTa1B;enShdcBs#4S6S+fU*ppTo>rI-4^Hm{@retT6p?a_FOS>U=< zX=v?Z1}SjbAvClM3@cMh!U^C;RisJhfwz&#CKMQ7cG##+tB6-CfD)*SJ5X%xBibi! zi222|yk|x9K8#=MwFAfcXD>BE4hA!xJnJb6J6I2e7@ZGu*oq%jJvAPt?8#U~l)bg` zTg>XlS8L6XurNNGU`1b|p!XK1t#%$wl%noGI@rj1#1)iOk9~!ru+MuE6eMt;{tlWV zJsvnO#CrM&c_JNG6M~xIaP^ruXJW(Q+gTWwbd-HDQnxmTZ95j+M~4`^iKnO(G4gn+ zjUmo5vuX_8S=G^4$OfyqU#|=dtY&Xo!_Tz`;g(t1Cl(j2$}xnit{$`+1=_i45)e-i z|Al_4zahBzA^p=6q9`$`4p{M;cHsP41b~tZETL<2VmqTu7(qFmELAb7ay@T|{%KkZ z48>cLOYzZBt4n0=2v`H*P5&3&(_2=wHZ4_dZ`Uj+cD6!=?EZpF;p;X{!};h)u>#Z- z@p>1jyP$XBAH}Hiq|;$?j_#`(Z(FXpNjz9Yl`0a@ovgyb48B~52PD-=>|Q`U2i^CD zIYB0EX9H)FKj0T#S7*8cjBAqi73}$CkLci&pk^~B{Te$0ej%|>Hz(;Ebep{ynd)O0 z{p#_|`#OxC8M*Q3r-ISM<|ZWGWs3$rnflqbw#tMI6`tkSfvfh4+ZBjqL7y;P5py5r z611|J+Wm^p(_KHa;&fzg!#xq)5=7O-&cuRo=OsMV`&!;fHH@z!V-%XyQ#_i+~U-q z|Fp*kGU>Iir6h`w6wZI@q1Bd48oO8*!w!1~)MHo6b1PzGlvIv&WXJeu$}2+zoux zTuQL+3v4k(9HkN;Uvr{DD=#y%8`ji0i)$^ASsk3xhDop`0XhxcUmu^&AwAa`5}Xq3 zJz;~pw?uCCF+2F9ti6x~VKj2Pc|E-ihZ}@)$QeC_yCAGMSAs(+1iK?zIVC@@;kUW# zM}0W7xT{;e9}W?N<5)7E&_MO2lQk?ExXz#12>?LSXLng?)y<{?CXtm>$w#2+1qiz- z*?r&CJb(*6624yzOp5;S4jERYZcUa+v?b*!b?HMF8FO9j!ym;ICP!~-0{zNb!q_|e z**AyB_1s1?vPxZCl6c&DGfTBQDXtZLthrK7ZJAk4ivt2r;egr-r|Rze zMzyZ*p*s*sL$uG!kHf>7zzkrAt4lf?DYyxpw%n>c0kGS^HOX*JWnIEH09+n~RIF?4 zoy?%bsj}_YU5bR~*#NNhH1Cjtr~G8M_$zYwo~>;QvIJ!I?e06B9hwi&XJ|_F{LKwB z4(97ko@DC7M^wJ$Rl*mo;KHm8EGGoDA$%X&SA%$?d#;*{l%KOY<4CBesk55*OxQU$ zK>)}DR18U(cB_&=#Wszk7eJxhy+1b@aUy@Y*6f7&Lt{;uMn&ve-}Vivzn0 z{lV%VlFY}XWx)Z#h#Nd`&y4yd zv0a(7du0c*)k`rQTjiHxJ=U8C>OSjXBg4;E9|Ij`VGX0jck#9dg~mQW**)6q+bO#Drv= zNQr@#0`X^y51!UX!AER)*FW(K=y{=dsH}=HG2F1@GFgA{LX9?VveACLswvZ=5ip-jjTnm>@YAJ_o8TX)L93hSS}a2%+jmug71IQ4`!8`h+dq__{~DJI*xK4TJ83a6 z{r#q2hfdzW@h{%XzjBu<(kUAlI?*Z7DLFg37&-szniD=V!+*r-|B8tf?Y@6?|KjC{ zIoi3{b92)PDSeY7TrG@D6vYI;4JbPr*gDz&W!uQ(Urd3&D}K`kWK4`L4E`bu{T1-D zGBDz^aWLw9Q*4~g09}}(=)~RHLP6t|;=Fe{D|*AXk(&@| z3ineUpd*4n3c7JP>xl&`ZX=&MKH&&Ku&5$?`T(SaJR2%3_JizAMpGjJr6xLMAA3bsg9_)%luGk^ftNBuXrXCHkm(`bG9#Ye%;1sTrl+NS*l(L2f#YCISwhB z?XuztG`3KEEz{w{pOWoVaheE7q;E#)U;|(Col1bI92GwU{*0NHMpzYpu2-*L{iHXi zAeiBO&)v(qL5~Dh&js#1);3tEC*lYZ8rBeV6Z4NyeWi^Q{k4*Q_}jsu&;tHd0=92i zSEdX<-Eoj3MT3ry*bS#q(1FNUt(3G*%})BWof2b>)=l#&W&nS;PpB}X2lKX_zLNKy z(=!>LRwf+1Ym8)pnrtsjjuN#%WRD*>ltvh zyTb6Pg#F|vo6qF z$eNX>-|SmUK;4drREW|Ee8Er>p8wCOX?T|5=jW%XW_W3IDw!CxU9Fzy?hGaRW{eq4 zXs@%)r8x2HR3AMf`mQ$RT#nitA-*H|!df=-OKt&@r%!M>@D^tyR!Y}7$HmA79%pq? z3nGz)!;4`INCP%bEeS5i7h<40ZC=k&3Q*^CRJfpv(ZfJ|zHXJ+!srE`M38$8ol{a( zZnm2~7`d!xTotx=6dxP>HzdmBOraYRRU#x1tRJ+c0ya5$q#Kd%3drfQ&AB&17oM|M z#h!r@DE7P2f*G3zyZ)&lbN4*ATXn*5BCA|87bYifG{K=l_;jm21UU1qw34Xco0mlJ zO^MQ5Cr~CSec^VW2S0|Uho0W3AY{1c?j5*DKI@?SsV}8`cK6Mv_X4rz^)~w!W1W1+ z#fK3d4mx2kTmziUBf`6IwvPHCXb6kijBl2jQN=>+Qip`;yqwgD)w$9pI>ut9N;N18 za%`o62P1m7OZd+_qUY6*AaN?|P?IVt=E+v{{aMFf|7g@$FW6Z>`L$wIZsOF9H0IA1KY9lR@?8j0gsC+WO8#{PiC+gD=vQ3$G zK64IA;L>1Mbqaj{B>zP2))}NfLddm2%{}_L9OI|MyiB2n=d(15+ZQQj6=pqSR6D|I zdW{nj_PX0VJehy|Qcd;5+GDwI)Ms7f%SwZw-(4H=N@;GDGl=181%{ivjMYd0D>>Md zW+#k)8O73T(KJ%*u^z))EgOl$buP(M&SV=b^qu4P;f4X?I-H%&xhyH3W2={+s%}&%7HcSp-SuAjm;0*pUSWi zuNGN`_ahu1pOS?5qRJz1Tt}SU$+6-nMvjlaf{8aYxYh5Nuz!QPkGeRFMq-Q9 z)D_Hl!cQ-p+sko*F#5LieVP$90Q6=yh57K*s>nk3P(=>Im0l?h#`+ErmSFvN6ApY0 zH9y=>u%wPcTQq8eEU@lt)p3z!s6F?~y1E8;0%&ddBqpOY5RYd4KaEaO_`wwII}oDN z4;RBHu&$n-k2p*$b)jyt|=n-1U$6z}|oaB{Cn@`(nw z%*_aV%$AglCd|K4ole0GoI4vniNj>3lo5X=xnsV$^d(vZynRrCHsBo^4ayKvAyZ+X zGUehwVh1}8{IeKROuFek6_(lc(KZ1l=ko<)S_^}(Q``+%%>nx0EVuBPFs38#pd)!+ zHsuVx>#<1N(Jd{O7bURPI}whVPTs98L!`R5?fgF9XOdwp)~X4o!vc>lX2(jms^Pip z(A|MP&1V6DcRc;q_aPFD3vPrgEPo-7skHq;%wQ26c zbGE9@ER#nbp0tZxaUQMppRZK9H1FdueVLGeDblg*hp&2LmLsIO^QW;Afl-mf#_E=@ zWS+iSgd$W|AdaV7-4KFR-Y~3>hCTf}>L;ijVHFWXG_wRx;j4(AyFLhSl65*I$$*1P z-wN=W-5!3l47+89h3&E1_kQ`9{5AMbpWa>20dz2~xuDz{alN!(s!zUwsQ~AiHe;O= zaKG;>Q9&QkVKTBFgxd4ojxjak_g{sCv;?MtPLaU>un@)n6q~g9oxK|Y3=^|XA!4LP zF4r1Gaj8VY02+2e9*qxHxNQ)+Qa&q9#BzM=o>#G_qG_bOvxVIw;ISC~3jw&6=MkQi z9*I@w#J){S8A+Okfntfd%vISrI@sg2l9Kj7OvSGb1GvfPz4C}?>=O^vR3v9EV}Ph3 z0YA4V5D<4T?@Z>8rCCB4lKGy7Av~C2$CgU8kyh|B^s(-4Y5zfzk-YW8W4^5L5J3Yb z*Aw!~s_Zndd%L93$$@Ybl20Q(K*! zrb-#EG&)yXNFN^$C!mOfRMAKgtRG{?4Yp7hb9}PVFcMJ|-lH`iy!}WAM z5++QTSl?JwOEr%kO;>c?2cc?R9ZH>}j=bzaXl8ixRw&h}rL3MT+!vLx40epqEn~YZ zupUXmoffAesLwr2XcXdpx2S1c>tj1u_NsR7u+296PQ+HgXTb`1yx^~?;);<-Uky}- z^PicKnK)_GH+7MXj?t2q;gz*S+UcEQiy_nxoTk0FuuxV-L~W<8j78G|e-<9F`k*R@1(1SJ{X&g?N$CcbRhy@L=S zhk_55_Zp&g02L7FEBt^=^s~~)MMH{UNKMR=`fN92b6w}S!-heG`v|0uJ4ti#h-@sR z%U)I+X8n$E3=5Uz_eb_^(7 zqu1h`jT`zPF~yjZA#Gene$UHh}>Cj(Y$bz4k%SV?pn)P zhdVd$nnqA=>09i9az&M8jrvPN>~u?RLbXxUQSxEaKdIVUn%KHCpl=FRiMt$V!yz##Uh(*8LkZ2GwtW+k3n3~qg#^% zx6O>j7!cy0Q)|cf+FXsUF;VV31@RQ8$a;mZaTb371TIL;Cy;c#>;a}P`XWeH;8e;S z$tJ{mF67^;U-zxa2yjsf+3M^h&?q+>#g7l&WcvHK@ZuxZ%J3V@k&8)c7;f9PVK?ef z2@xxU|4GO=m)|T*yakWjY=<3PeI5aJxJKG|qN_Ylp@>oRSDrQJkoUoorB+@5Q);#Le{YdP@~Zu84Yzcv67s{{?NPF(xv!` zyjGQ1dpp=j0qX%Ijc?=*r8=BgG_%YyCCpHS$6Pp1At~qW*49noG+L*vmRns;h&r;2 z{JSYp?*1~oH1Q_f{hN2x04KgIkhpML*W46Awh7_vqS$Rtimo{_@&Fs_UwOmE&zisC z2XY2v9KaSZYiEAa)-E&Jy0}oj^qL6vVXg=w>Ozc;o69*-!5SEjiC6Aq4L$k6qq(1# zTDQZN#EvEr!DL8l&4e7;{AQ`Q83?**UNM|WOaQ@LixeM|JxGwRX|w&Fn8qWq(-v5% z(0%?P#@o;C?}Hm;Lqb%j?*;;W5-c3%0~m0>);dy@kbm(>Ekpn*+=QP+cn%IlJVI$Q zg0>WKdgM9)zac6kG_p$LqyBSGKfdG#Y7$Q`G-h;dK%NC@WbK)Yft9RPdd#z^c7H%W z@yXsjPni|Q(zsN%EkhhoMaT9%c2m>RrWK`o-g}pzzeFe-;iA5tF&KH`(Jd@-;`pLU zd-p^?I=xkRHi+>c`fKsua010xCdEMtzXY5Of7%o|j@y zJc$w3oF@J4Kp9=zq(f}IZl|3@th|Xp_=R64u&wGJiJ`DoD?y8kN`do12wQNn z!0>PAg-*5{_vQ3Yf~HVB#84x+4>(Jy3fB9}#GY=BD)9ndjIpY?@N+MUdHilMO6<)# z++@iTM=uSlX{xcou5y4(R6s25^j}4$vu?Z+zHVC)t}>Z*6}D0VBzACx#`d8OwOs4~ zPM>P3!tlZqSO?UB6J_y*1n6oZR7XcJg`Jm^(SGr7^J}b#iC06F5M@@9%8F$B=tfZy z$x>pOO1c`++0Qsr5Ak3TTO-Xf04DAeK&ph7r<2#1L*<_KeDMn`JcF1a<`N$s-FxK? z53|J+0UllLCzCNPyXX<~_c!2Trg}g2lUOacZQ!n$9);DLJ zZT<12ruz6zAlBbZ{%B6ez^%kLX`U%ThChHY0fz+=DhuyF*?@7ar!`!A<<> z>unq4N;+nbn)E=B8I&inHQhA0!l)AyA5fNX(-~IK%jL~|t+jk1$LPl$vle$XVx<$; z*k0(~bDRr$lscr=O*Z>>rs>Ryz2ATDYM2iE(H&F=CqUNABCjP?SID8-K!=|-YGpAN z8ZS(67v&_04@o(%Y74o+!j7?iLXG}OYhm=?cDd-b;}%fUnP*-}Nrt;XqjHbvFn|V$&~)$s9Cg<@5g{d_Du1) zch6ioL&rVYa_^lr{>x*ZNW2b}x_>-U8-nb~FvQF6K$^E%s&M_xwvLQ8%1~)GM|dMu z0Mon3>NkY5IVz!ce6l}NZ^~WtPHZQK>;Wd=^w~(WWatTIk|3t*I&CTlGr$CEeGEu^ zQPj7b7;WxGqfOf3qqxTzOp=xDg9ynI>)qz*reX14zUod3wWFFLHz4ZV!v>LHxm8-~4B1 zT}X3z^|4)7$hJ-TZYxQ~J{^DCgTiz9Uym zaKXMlByTrFoKuQ~b9`&}s8$SiPX(KX0l(3-z%vsjalY%o-!dJ^_D|2+eptu9c0E`G z(?dyE9kg5BT*?Z^pBxnQmR)&tEb5}2(6wAIn;0(9iWnF7 ziVV_?b%70Nc|sxUTCvP@l_+AS-ePaeqj@j#-lCHJGRF23j&oISyOQg;XKuirAsIYk2sTfM=}Bf* z@Lr{5fGoIOCf4*`;uz)J7Zx{j+MoH85lDoxED!if?f)X}o`YnG_I<&(ZQHhOd$(=d zwr%gWZSMAN+qP}Hd-|Mn-?`_-+<7q*6BYGGMy*=8G9xQ1BUk>upOoep54LD?UUIm< zVT>Qmx2zftbnH2X=r|Ih^Gmn5Isj=$tAt(}gf8FJ(YuhIjpAysB{X*TOLoVHw~`pn z_y~ElQO}S!vF*iT2EEU~SyjUF5gUt|ZFnlBHG(P%auivkF2r!sDQ7(r&38OwPzc)3 zd=Kduk_T1eq2&ur+sxyT5- zLn|k>cRvAn5mCSH&t62$3{mvtvmamqM;^9&F$i)a8dd6?$c$LDS&-}`DXnb*et{*6 zn$^u{f#8B`kMGL>b$lo4?NP@D6LlPa^vpzMAe>Gu&3yg^LzFkEoe2==T2yx|5!gYm0EfDW3&^SUH>oQDdgTEnwX36!AQL}+So>l^~ zZWGytwojk#I!B&>0P0%A?gJXxD>LK^vOwOz4;4&I z<9vN&+Y?Tc93FW;ZRtIh)v~k`{ciHOODOXO3fVR27jO$RDu#}FU4$LEeOzuYJN1NL zK*4KUof%DVlM>l~(_WsQm1+s^90AK|885(XtCZz}oc9M|mW*+amPj{TohH@Ka_4_h zTGx?TKin;X337fq;<>xTJ8DM} zK|UX8TIXO>nXKg)^95~9sgWWNp?YRX&S(8RETE7V(jr?bk&&!QM!v3EV|( zWMyA5VoTeHP(-A`R9@K#PO0KC@`69C83?UQw-Sc7q>ZJI6f~OpJlot0oFTVc41BQr z1^9uiQ&){L!!}O->C@(@Yv7WT`KPpBZfr?6Xh6#_=P`XygrUHcO;58^1>&apsNGK`}q*BYhE~GUpot)EPjd!uAlwRc%4N z&q|@H+vhD1dEYreokH>N7#$AlkFy220Lv*AnI5uKhAMD_!%$6{{&c%tm<`fL2x9-_ zkKV$^YyyWVnYg$4rbhlZtqMdu%A=hce5WjwiRJ4d8(ngky!G-V-Os$u9CXx}M6C zLF8akK9vjps#RSXs)fJu<-((sFUY~_oDr{Ooc$=geR#C<&#K7*bcg*r6t4_lkKRKy&iTNB zQ`pd9DEXzuXHg3qk@(67Tg5DCi4jJl!SmQ+vpl`wo$d`O282o+B9=Jc)zrEX-FV9H zoiYCEHY38scBoN(q-#RKD*c1Yt;Mjlq_4d-8okcMV+?KZ1VBkH1(1+ifo~1EpZ3yK z9up2{C}b9{U--sTIey?l7^YQH0uBWy6x*OASdzgKx&vA)`R#eD&9vgc7UiR4h|E5 zb+=Jy8TCr063!fWWlR~#&iWK;qL$rRZ)s_fsoO|9h^z?a(EEYan9p}3i_fkv*+hhQ zz~gmkR!^`~xln}uO-L@8_jw`OkpN!0{5jy(sL`~3AI$WL%0ie%v&p- z%B3EXbOTJ)Vi%rIJHE#>PZOQszMKx-A|C7>kk2seSpi#dD@>B=!vF^*&fiSJfTd&+ zS4D~APMJ9mObm$sT#|Oq)g%F0+-T}| z5TEM+sb1KzX03*+jyi-bLQMs$ks_LZfa~R1^EPT^pB1Ft-abR(bNm{zV(moin@V&N z0|;$AMLN>ZCiTV)?eRC8TFJV+dP!DU@RNI^4`41y6|wZr#k z#U=IRB=jW-<j-8Td0#%AlmmU;h!>v5EZCLiN`!2`UiDkFC4m-tG|;CKs4vP`tJY{ZB( zDU0K9sDOde{~5(xgMLE>R1KQ1W0UloJMhPHwfn3MwO|J(6VTY_l^MfkKEE17M#Aq! zJDeG|CQ<``!5{0$Sw~z@u3>#HC_60iIe<5vQPF27t7Nlv6?( z;?69T>&|Nbw3;CoBp9{C^wJda-DS$BAm@G21!vJzO9j+?5!NUS_3S{nh!JPG7m%K= zO?xZt)Qc-nx({Le=xdgm!c-s}>oaf6M0{1hkT{U^kdC`|2)SWbedN=k9Q0X=yHrBB zz=LSBGJ*1Y)D6lL>41}qJ>0@ZAqQ&xLO5VaO+_ir2T`6br;CRydjK3W%UalMuUv`o zfwM0G^@nj(@B8(xqqNR`KXO;yD#+*v{4gt23RT9g9NMzE!@H-OlSoE75dD{BHE}}S zCZ6dk%8|p1?i*h=ANwKe)yv|Vv6G}&DSkBaIwN2+34GgvGSnu|Gzp&~KF4)#{MJcx zh3If>eS2#hB#)c~Hg4NJp29C?%AYjfs(4CPp`m1ZJEBkKb9NT#<0w1Dgni|d3vbXIafuGZH;fcOXM55gvi+Qn_uVm$H@!0NKW{zIzFd zR?w|f*M^VzR!rYp>*bImadcP(WZhGRv0>+`RQECuSA4ZLZ z(@s1vgH*p0R$Mu@S@edPr$JcC40>&8#i}K14^Qh0wDOQMN&ySb9-@mRkU?*8B7p61 z;ikLh_EqZZB1`mQ!|J6C&K6O&lNUu{&MZ;Zx3QbDe%B=#qD!-~qOAMjju zL0l)~7kN3j8CSnKWnnqP2HT@q1cDL{uNHkL;Y>-W#S00V>diYVj*-s3<=Ll)(7BYG z=vX8@Mqt?q8UzI zR23~GDw7)FgBg+7q$;CpcX$#L%drmhh2qc0Mr(L;?jzdI2d8GHrgVSbVm-b`_v3U* zqKt8@VPVe9t*Z0!$}+&H0^gNFzg4yfvX?;Gsm&tI87p93an(OBI5CJSu=h7^*N(Z2 z&pw6eWSmHW;Gf3;4qNz_pDq*(J@bPhXhP&MsB!@Gc7&?A6t!zy~GdOpg z9*0VxKBC^ICf(@^sOzRhDb-o$@ID*e)Y8BIOjooI@{t=8X4u`qOpCv#ndmjPto5ec zHMhT4ocT;-nhcFv08!Su)z-Ax_u@m5CNaU;lr#Ws0)Uct3Tv7+ zF4q$)9J8IZjST?aQ76_xO?>ei5WrAuAp0|$bW<#S%V4wnH1uZ!n%$aCIdR3BL`nBG z6IH)T91RV!w`XI1kCrS-2PBre-jD1q|4Qu0Yv7=E?3Uk9YhP=0iu!vXz+p8$mvMI~ zBuYOx>_N&g%BM2>-SO`>NVRzGTQ+7OYZFmOD^9) z3ROU2k*TL%VdI%a%u)=NLPA1v%9+)*2tE-0pPDaUg2F-_`F5ajyRuwHr4tgd7%8hq zzy*vkmqafW?_P1H-^Jb0`LX~88t7h}JS z#1B+a!M*9NnjRf=zT=9?A$$K3rhH{ip^%OWma94=tA}hTBiUMO*AdEfMQZh_r95ai z-x*R3prjq~7Ou=${aalJ0Vi3pn)#!ZJJpAhr+`(~QWsEs1g?BsiwwxNCQfrcbm|w3H%CJtR=pgRjFh84%07rH9^;U> zf_N+CM2^`-!-%v+ezw+k{{s`p?CwZEr__WKA_j@ak^; zlzi-Xm%D4C5wv}z%(?+!F%>I~qs)*yq{RsGuf7Lj*t*HL=^xiAe>OnG)l;v+V2W zfYLm5ha<2L@AiKIFzJX27j#S59yUamFImgRU7CPbFe4OXFRX z;*v_pk~lF)qXJh!G6njc5EOTo11^K<>2JIKSJ z!F^iV5osETmxDW;({1f2e+iXS6MUnOE*R3^GD=U8e+kwr=5Lcy+*O&d>Z}1pRpg;= zWP*T+ofpoeK-)Em&rGFU+`R#_AB6%k?ZDbLx_ISe?J4tkuN0U*K}Aqw(gIaWXu=b~ z1Bu&#k$1XOHGmzn=HY^pl1%LfwH#=51hT3pUoqy|^0D-NFVi7wHlxPP%2NBK=Ufy+ zM^jmE$`Z&lBrl?{2JJ9DRExMH4{_}b78d#&DnpKD2+&`QO3BL*4?XBN07>3S#UaaS zHv|a-#ZWod1aA};$G}P+RVgI$Qb<+W6jwLDqtA4ERh zJ zJ{feMPK7|HVFle1l;Fje&+%**nm5)uqbNtTywwng(E*6pEEd|U!5JV>@Z|4(HPNrk zhdB`0+in`mwpny<_@$<`dD3aslmow#{GHq121K^r_t1uBOHhaK;Ukx0VJnE4p}Xe) zYYk##6p*7?6!+V4&6-1BS+~t)>(DG}{BKG0F_c(%2>-}^=zg<>4SIHEgZ!{vM&%H4 z{)ju2JeD3o4{ z#{|na33}mURI83vYR45LnWdUHTFBRFR4@+O)?F80DYAK(DJ08tVLiSe@B3$PU@9ZC-B+e(fkDO6)$_3G zwGq^85zz6I@7)}(-Q#ZDAK6*F=o0lh-h7&k;79qSJ637IVRS{c^q1j1Eq|JmT@`&( zIuuHe^*Z5y`SfW~CX4>Dxn_!~+`?D8#_;S2$~Xyc8fTt+n^NJpPcf=4QO z5?N~ri191fY?c0Hbxcu_X6_LGisyXH#!K5T+$b{>e_i-7f?htrh2psQvcFDrjmsv# zb(!p>^w7g~w~gDr4^DZ4*EZcC z>(1aB8S~4@7K?r({)XYpnkC)zaM+ony9XcZamG@v!Gy14Vny6m5~WB<^@gbPFM+2H z-MQD%4buj?&W+}lfMn1uLG+@si}S(D@Pa?t>K;`Kwh~038A3*%LNVRxWyCk2Rh2LS zQ#sdsotwdKaC$Ku;!)6(V$=Z}HxTc5l!(lqiNV9~){VoR_I-zH+Fw;oL>Fv6?d2eA zsE@@8xCm7|$<|6lJrOg+l6i14PY8z#RLRaA{0Di9o18dwYM{eC3d!=i?tkgoj-T7O(Jy= zS{s`~!e3S|G`=09>HKHf&RW7NodVmk%Q-a8%gC!Y4_`Jw3LXU8@;aMKesyz(mv@HW z=g)}4pCla|2k?eI;_sE)|Bbtrx`3>0a0f|EHjfHmOyJt$o9ju4SLFz)+^29S#iIt$ z#QWyiI_^T;EPqW(1AwyGPa}R(bZ?AdaoJU!=#7G?Wb_Jpdxl%-wFhRuf@BXRNm%B6JZAX^iqJMlQoD6^CVDIo*lj`1*UA%U=Y}s*bVcV$ z74w@kbe;?vGsd-$xA^`6iwE+A2^3E0j_WT_lUr0RhkS7AFN8qGz%i+9UBf@d>(t`a zVFq_TqBhmHuPiXwbsGDNQYUz>ftHO8_(s8iEFM46(0}6!*u;`RiEmGM5fEsqV}RvF zh!?EeTe(GPtz%@Q=^7n8qBxCHg#;1aRoY(vSTKhNg_&TvUFl+hifAj3p@F)#4yjWK zQpULO+-63pWKV9q?IA;3(d1qDLqFQ^@lh#FX`FBaOebtw2^S*r)4HKLg-Y^lx;y+< z;gFUk<65nNW}_=_A?#&$U(y1*Daz$EF`4u^eZXO5N%c_A$x!uZ_{|AaNTE`$S+F%j z<;esS&;tNe0f)VA4vxQj=d@P`(_d1;SVd`bNweVax%KfFc(<(JBCIpI)okjgQB4^Z z8m0{9skT%3a6;X2^~9N0^dlTjzcX zHl{?oj`pm6mK{v@gnx)n?NAWGDyc(Oo&GX~5bBIBbH#C8nv7R$rTxz=VYg%VotjTZ=f?=R)99b=6Z8h}+ zPtHYjnrsR8zge9aOyMMNEXmG;w%b}30(xBFA&(3EdD->X=6ZaPD1DKE@)Mq$JwV;k zMQaS`ynci05GZ&~n#DXMR!dLiBO6Do=*4F$EQR9P5P|+m1^aCKb0CyuP^{W&8y3y4 z)OkIJ*0FVnMf7<1skl(?=;vnNZuJ3UDg}{zERXUI@N-w13o0#oBk`BhY~CApkZeRT zU0w60jn$}$g4)9NezJryoGrbZYX_&eM0w7O(fKg3<4@WdOfsia{Cvcu5EOP!#FZ%^ z?A3TNNOT8|Y~A+WseQa=8%t3}d*ZxE9rqL$jN!}1;jfPQs(PfB4&OY86hg#5brEg@kQl$&Th=x~DPDRyG zB}x?L=go?QvIyr(Ej`?^8aab9%SQY>%0exS3&uVErX}nVqbln1ul#=d<(b89gF~edmCR&5`p{OUi8-5Di>9sx=sMMsHWyp@&K9j^}<416Vm1qW6F7>ocH#n zU%O-U2Y=FM(RHha8?N7wyODjc3@kF1*)eIJc^W&bbsZ(ytQYIIZEB+9$$}QOSbGnK z=*mB#pwVyH?}l$z{{kYTApSnwxs^b=IGDV@k}bI_f)>cR?m;%pxutdSAqHJVOh%Y& zkEtEC)ue(#1sbHJW4_2NaWabw@NNJgMQO~xPs2~8kA1fI~oL zf(lBVVE(PhKmC(v&Q9=C^KLs)^zLKPbivm}jn+oY9wF6x8zs&%=m?sMUYT&BtYB)iE;l9Fb_=umc0a3ph)VUeG4>|frEiL! zOAH4c-4fb2G#lmqrpn=O8a;`lX#+XG?k$xgfNpAxS?l2uax^@BRzr3W`I_sumGnh7 z>A*&wMY>XlaqQG2!F+i6zJS547Mdmh;{&-=3HQfDj$K{bbsS?bQ> znaaY~~{za!|N6 zP4!iGtjjuJ?96$@Cdvy-uM01hb{-%(j3_I~QW^=Vx7|5DoZvi=E1lLlUFI+FBzH!6 z1RSOuU3~k45Qn5<|P4kivx02oorkywsN{6-bDTCa8>a-gSr>I7C2`klPS=jvUL*bP8ixEB>rHa3U3E$Y^U?ajhs@l7s7mB%}%4pmQ|dyU&9 z-TO&?#7V#yRXOLWXZ)5-#g~kEs+FTht|wUCCF(71jRZGNO9jBXSv!mD-_hhGG{ZL~ z8%QrE>+al5K=4p*H3`tY=nHjsYL-Y!NP$zZ_eU9{4P{tu=V=vik-iI(NVN|nDEXDHko%jxt7y#msh~-s9&RJ*>N56>VDbLYJ z5G!NpEHA-P6TI&ZoPV-a2+1|jhq?M2t)$NsdkSVV5^B+c)R#d!T0|R$MT+2ZKEFi7 zj|a$-q7tzocRG8ZJf1`_a6oAx*)kx-zUaJ&$ScL6^CDY$WbfZz56^x0cQnhW5b#E+ zSr_deoy$agopKK5cqAE1&$3Tqv?XwOUKeH-Ep?z;6@GasTh(aKuzsrceV~yCmUfIl zuepJi)7zaB2)5{V({2S4MXCVwVd-Ux7*l+0?wYQOeCO54ic`qzx3` zJ^_RO2?fa%{xcO+C>>Ebo#ac&RWi2+wRV3b4|@#TtRZuEYv8Z*RdC-M^KvooPFqgW z<(?QzXP$W~F0RLDg#LoIF^1^x;Qj5tMHn64JOby&{>PxhVzQye{#cDz86gd{d_eo6 zg7}im3bm&pOgzgL5J6pQ26Nj)>O#mQFJ^!xT0t^K5Yc|sSqBy8?QoXe6u^)h`decB z)S111Atw35!n+UcFMWL9T!S{wmyIqR3}+ZmPimbCRw*Q1rg{>AWsPK=LD7yI2Q!_C z^ivqm`W$udpE3&|vc)(;0m3;>ax>FqAy)cfFTS{`a{MDlMp)(h}s_Y?SJwF-AKb!M}c z?8r0;zKZ(w+{GaK&pzCo`W0zL(kErGV#b}v1N{U{cybvT4Z@&lWaHs>Do3%P#Qv-j z_w;O>BZDX^Q*fg84yX?qx}KReO>!l>{6BIrWSkx5#wtsQR`iCV%yX(IN9FQDPy5t4M#XNFF zuJ#mWopXL>VjJSMelaBl;r!oQ&A%)P8Z%^Tu&nZ1Kw|o#Zx7yaRmVabpHkS4sBE$O zs+pW=O!TQ4pwR*|(PDw|`v9O&@fvdqHC{b=DB=eF14lK-A@IZKryJotqGH$nxPFot z!R$xxagybs#Fnh}$i(?uF;)%GzlwR}I$MPSpMGQH6&$@MmM%u^^|tB))5MT0K(8Sq zBul|yK!{zqoXs2&|5cE5=Pyw!o2PUIZc}*akC=TmD3!08CFw%`DW6{2g}eqCVhDZW ziSgxl*|YBO$MA2YN8Ww~BaJMUc`c1PXi)`|D)J(l4$^TgX6LU)PZ&kx$FM}gH_?rt zdMko*dqWHwG}hFfq@du#jA8)gEP@(`PiDVkKM^{*kMgP%SBM!xLo+6-@4Oc1*N|kz zMza=-ir_lA{Z&JLCd%u2Y;!`Z8~aWM&NdH3-kjT6O{_wwGelA{C(a2^nK%I_zuE)9 za*gU^n4|bs9p5eFRZmw1i*!x zMEdhpCklaw8A)-V>KGP$+9oj*vU4!{eT&J-F4T(^RI#6^`qr~(L5rZ`)v_B?2;?s` zj(OBcYHnDB43b9-4SwdE{Zl9PievEqjZJK9ngj2azY{NglZXJz2>b#VcivwN#t-EJW zI~@gAxA^Yl@e)KU#!{&|@8U}Lf{!VBPlgNEbiA}UMjV2qIO*XzLA>>gBCW`_8h1op zdwamLxrVrsZqgAFyme}Tbc{<72J#GVi@mDGym7}Q@u(tC+c zb~-RRTg9b&o<>cO^_! zN>TfmA7FR!N+ycfk-Y3b^=(#xLzoT`a}gxoM1~%%)Jbl0t3cc>77)D-{%*@rk>vT@ zMY6QPdc)R#isVx&wn%7J_b@a+prIzM{u>xwdYal#gWt5(&QaM;%aO*mm62CPXl$!N zDNcD2@Frk|LegZ5FyqCqsQ{FCO71%~Uj#8GVzE?yYwi;g6+S9A#th)kv4@*3zHXl} zS5H><-Dx@p$wsRlJX-<JEyP{x|qUP_}JR__bZg4VO1xf``fphIf})A5%1jXB%K9 zIncf`J$Z>KH-8QKBPRCf7*8$eb6;@#54c3aGU|j;ouuD-T}Z1l4nojuIUE~xYO8J2 z??FlmC^^j2+ru$Jf$+GX*#`p*tLVn;N+J=GSq}_vaN2f)8RQpVVUpD-#Xe~OlH5RK z{q?iJ%OK$11n=Lw#Z4**SN`0Tnnx$7vijS0i1K)2TAL0~CVllp0I_mx84mvA|5GK; ze-TMP7}I}|G(WK~|9@U=oE$&FtN%z|Wo7?|y7NQMF#RL*=4Y9eoq&VopV-Y0X2ndv z&cRN=#`&){?9Bg9YiDEl$G2JktB;>Z8m51=Wcp{y>pyzs{E2>LWBz$F{Pf23kKS3B z*#Fs{nezwCVP^g}vGmX3{3{~nU)t6WZ1oQw=wI5Fkg$lTD7C7IYpF~ zOW*om0kc2t|Bw0>BkND<%zx`!4DA2x<6rvLPmR=%zV$OsMwTCHik*%1-}=^%7WKdJ zTR(!={}+CXmhnH-Emj7O|K_It8G-v>+w5ZK{13)U+0n)1pEl4xw*5c!tAFkuMS2+n zCud=E14jZzMt1stI$l5FzyFHV{pXGnWBCst>wn&97LNbb#ScsNZ&FF^XTHhS$>QJ3 z{~p4B4EF!dIsKowE{=bV>c6?J|7|q%Y6Kkr%0l{o;dXKS<498cKe=7(|7||~n|WgV zAL`xyyTXmeZkpmxg=4W$a0w8oA?w2VtNNLy-TA8AsloF}jdR!_GI|>-&Ugx+IGB~Y z13bNsAHNQq;*OOrZiRdic=yj(_#Ln1=o#aYG2IAdw^iV)tP#e|`?A4dFWtR?e?jWf&XgZnCdN`re`w+X36 zGOe#Undwt!5nxwpV~MUTt5V(2%sDx=x!%Fm1Ya+*8n1tJRBney{H1jGNN(SGXXx1Q z=|alwSs&!1yceRR>nYoAU~%X?nC4Wi!EKj=k}d!4mGd-XwyBwE2Vpw##|SKE*tC<^ zFe^$>FTz)`o1T!3EmdD*kMg!ufs?p~MvSbbmmmP0NQo!tRW2M&UY-Mp{ZD7V|4PZ$ zV*gj%*8jri{&_t7ub<8TgwK_tx{68YTI2i&K39wCEv4}v_#DSS&RhRmA{7%82h0By zN%ij0skjTp7Dh z+IMf(2_$tqLKIEfU*aBnS~&HY2U($}G0W+*Fet9c&?feg{QY}A5-RF`Wh=Jy;h90q zpB|zZ8tkHH7y5QOtal*piowG{a+d@CEY5!jb}E)V(JG*5oTSqmocJ4p0ux~f1fWGT zJZewqZ}j-0|7XTi{DNQ=gejwZxN;;s+Z_|^F9MQXLiQydz<$p^&w1c7M!%rCWG*Rb zGvDSV1?zmIdf5tGn9tcnLsdS|X>%hIzTVTH$t3^2+&w$jd-|kbqG$5MOfornaTrVc z2fhEL5O05Ti59U-mW#xoP#OZa3)Bo+Dc%01x9=2%(x!lT2P&IUs{RsDfWd=;Zju@? zkxH%3n~T(6r?{UWwBtC_is;Rv|AFVNy4vy0+9}x>ZkxVx9^b;v@R+(;o4XH?+`c56 zlCzy#XSBj{W|cxgOw=0fGJIB>SV1==l)UFt3PKn5lHPy--#C7`vOorT%Ee9YP8}B1 z&fv*mfjkQa97fNJ5xTug1mfSiOn|?)obvgMFaCzw|O26MU(*nVn1G z%g|jSj=Y^Do{^Wcwa%lVj)@#q?PLLW+!E0aU!sVxq3cv?MO4f;{;Z*T%nucpT1-$q zkF_u#=Sbh_Ghu+z6&gBJd2jiNc--)OrYdn5C;7ouB<=JYX7NZ!fuY9TcspVQi}Q9i zYMPv?`B$lmo{ku496mwWNfoMJ0B$G$T8^(yDi1cP1NS~PT^`?=1z{{&@?H0K4C&{X zbPBFdCEwA-CQim*zqjP71qC#qB;{FTdK;t(699gYVe32j=kAJ0R9uwdg^W-h1*ehX z2ZymY3HRm6?K}>zzc`X%N%504D9#{y=~9$+8m7{o1rK@PaTrb|^cwHc=$I& zg`alRFDA1i*X;xVd&C+wPOD=cFY;e_Cy0Ye?9Ce{W~rFJU|hiS`Qd}&xzh+sa-V)e ze01k4jqUHArpl~-XIk_O-c#UJ*-+nH{GRD_80n*R$!=Si_bxXS-ta!Dk|c$AWx3u_ zWB~KpX+6*)q0~r9K*@Fz(1bLYIR_bo@R{}!#{NamG`ri(Lb8#|`-Z?ZcQD9uzlv)4 z@SVl@$S`|-|DXh=@^pbQUD~PKGG_Q0LyQ7gee*XAT)23Ka1?FOwjGG91XF%0ThDl zk{g*eiYX7X*MZ#+{${gpdzUCD4lJ0(g;lZ62Y%-n^({tFH8^HXi$nAiqZ8S>Wup0v zF7}sQa^FOH7~L2Nhnq-sEJ0@_3f7(n3s~XMvedgMzj#NlWvS-}sx(Jvb~0cTbSJq! z_o8G-Z>3by`)iuaSarDnfXS}=p@mSJW;{w&RF_F#tS}DgA%b&&NATdw<33Y)oc_0M zu-cc#dK{icY!Yhcy!gI{K|Q5FUhx*z%(sriwLnF(ggK|hs}Kh|w;wS9Y6ZgS9M;zSWO14uR>ZZp3mPrs zRPYkqX>~oG7{rkPOt@DvbK=YoqX{avraGr5MMq_K!iN6A9Kw@<-EY1RFF_kDe!{Hm zr?QVo8to9>;>xef;n(NGTcamaWxW{E?`~d2A6wr`+zc?W^jtpp-o$WI3|T2X9|_eP zI!wjQ6+wp=RYtHLbQwcHuihiLicTWudSGr~d4T25DM@W81| z_82Ntx4rWhsuDhUcv7$U#=8Xi*Dg*`VUE=#Zng6tBK(f8e|^^4Xx?b}TW!ij`wp%+ zr6vyb;0Yx+paBH~NMgw4ff;_|?}uMfq0t_OuGsGdv5F?#5UmOZ@5}JEXnX2NbQ?}( zN|UmD2Wl&UYXhQ;vZmb0bSJO%f(kOl%R;<+TLWM4u_00ax~h{mW>@~^bf>q<@yM-cgNq5 zs)-6yLwCkalF?V~os`Ul)X{jWMlUcT9X&p+{W%ruK5kv_7fe5hcIIJBYnNU0x4OO; z`3093>PRj`z~ohatPvXNA^X>h0q9-0%~bKbp&R->7_pOkyM`vfUwR&!krFem&B7wXE9o|HFtfnz8us2>) zA4@Jy>^qZ9^45A~p)?~^hMkNQl{8^yjG z)}zitKNmWrtkv_vsW9mlmE5H;xO3&Zo`*D88$^}agknFfw;fk{uIqEkg635KKbOSl zGYVqs;=0jGk`zoVMZ1Xn7g(^>hf+!0yCD~&Cy_jpt1SfS(6F{_nL<08OG#2ih{?L) znx^lan_PC)szYKex~OxI8Vrh-BHT&6(JMty635mvY{ly}72TB`X3&QFyDATWf7!fq z4yZZfjL)}`=w^(x(7^CaT#t@G&2OH0`xC?t_0QBahHrH!?}820UJDky{pFoh;0K1U zZd{ojI&r`Zpi;cdqwV9&S(&pTbX_SOO~ zvf-jM{i4elzqSMhXJc###%`dOzVa-PsjwbZY~0GZ65&Pvr%JT=|zPhW=V|fr@2uW5Ncf_NnjaBE&>;Pjkv_I>605i(XmY5FPj?sY^Z{YUHj31N<4LmCS zhAsph@~~&mTOzQR$7|)D%pC;bBelUherjVqx&xE(I^waZ~-xw$r8~uoP#BkEI>hQ}-C(L!fF0G?2 z`Yfe3pV0>*7!f!q^MekzM=ho|{9=AY;ua)}!=UL!Zm545ql*w7^8u3w+U-hj=?9JrI^?&^7XyLj^LTMb`7LsB(2J!KqXY7|>HeL$Ws zfJICgKdMgvhf_s+#mmnj`ggdw0HtDRoZCxEG*Fu^U{2`09DnMT?jo0meTH#;T}k>Y ztEB|>X#|s;OjTg~Th>xEVF}iF%k{M$R6C(}`v%N9v^hAD3=~4mh)~VVS83oG@<0o` zE4Z3GIcKfvnN$ZhqgyWOm3FWO?3#ZuarMr{?08evhd@`>R+tol*h`+^$jSf z&o?gFBF%85xtPD`ap0wc8L>U*V9A{Av_14BWC1Adh2dkJ`UMaWCkeZhe;%$nUkD04 zR!pZ_UJ|M%l=yjCM?>-L`H zMw`*(yHi)JZBU^glCphG1Nb?>ba3OOiQ@}Ks-k2hjt|vML&VV_?OWusCLPhgWt zH`!s%zyaGjjloR-svt4YjO~~MQBn%x&!~05XS zh9n`|WJn;KAUlz#ZbTv(NTK)`KrU$WIzJb(gP^lwAf9~Y8}*ZPOCjs#9H!FL>a=L+ zhy(Wa9T+v}Q2A@}T5_IId107BP&t}4u0aLf-dT$Ks$>T`1~4<8h4B#0-vRb-Mk@s_1>nMElF=pMlOEuGzp4s};_m|G(2C9}f-jfE_mqiirF60B zL;5%!P(Yp0T7`{G&ucj_;m$LcMS~@3y0G2&Izu&}mce%FV#F3tg@;Y)_)v2RO|n01 zWq6}-r#KY>w+sc1@QVzw#}>EBmTL@jjQKLy9ABsDHtF3|L#yvU%m1xVN+1e-6aEA~ z_xh$Im2hd(nn7#Q9q_S;!49!@o2Az6jD@SMZNMMRlGlrSl9k^TH|poEbLl-5xvbH7 zA?lmpkQ0Vp*LtMf!pyO0jghAdFOHc>EYyL4Pt%P^2^8vZ6(84HB%J&yEjz^J%0{w* zo3F=!=yp>%%hlPkp6sv5y%IT(?G>%|n^fv`PWu%?;=Q)XQW|XKR9G9P^NzPxrtP% zTUN6CUA+c#`$47DFC5~^fzy)U-RS%k9{$Zra0djOJy1TF;MKkmj}=8sXh?iV40yIc zc(;3t;FCllmd{xx;CD& zjAh2Ql~Kqw9CFvmW@%XcP9<~ixgNz!;GdrFPw4{S^VkPM(l)nn`}3~P~%`*Bb+B-$c(^B zn@3*;b3V&|F0a#Pr5tbPAu}K{a2hI+Zz}f@2?>vC32;r3zFYF^8t;2})>e!n;BoX6 zPI+7S@W{R6>d))saLYc7E#FblzBiO}Z+DjHxJ^-u!yxGT7NX8W)Nqc2F{<_s4C|x6 z)38TnSneJ^v=$AdR9v6C6H$g4A8z3|L53etkeqzu6yTijH` z=?it?FlQ!7#V7Yl#wXl(@YKHu88pa{zJ1z(tK1oy)gMt8+VsntZNU@e+drwTPw%UI z7>|}m!#S9yVs!hRXYl@wMPck}A}!X&qZ4djR01br2+i&Bf8)A`ns9dn{u{TX-r=?r z@E5knz(7tA$QikTkomFiF3U#RuJu>zb=VF#1Fc*x$SuiB5!6(v4Qgafna4r*MTUG@ z@%8Q}lkw+%YJ10L9_?iBB$}Bes-ZQwZ zV*a}P+A1d9tZwL3U|nG(J&g40!!0SbVg~?uXDz^f9EN2sf&m3ao0Jva!^LMfBq|(g zEA=LVuHm6R-yRlX7yddLkUz^#jXESGgHn?{nx|h!;Hs*Wbkjl$=+&4t))Cuzs_aq7 z&vdb1hqmpOAW;Qg$3BTOX4r+E9Oo!1#E;1{8dPB@ewv|HSeGnDd1gg>Z0Id&WuVP| zjfh!PQX%~PSWB)4dq&86(8y8PlU>sO+SXkMWN^(dS7eI=Q|aZKVH(a($2gsm2irVK z0!%bgO?0jB(RCD<-^ZMQH$aD&Z|3Y^+c~V|c8GHG_-!BPeQLSXb!70=b40&E9QbPv zwmGQ^RLW=w+6z#*`njRv(yaeWmN$bFM~5y&CzR^b+{#bk(zDlQ4)m0HtCJ)Q5#Y+( zCxJ(ufI0%B8aI{tQV^nzwwL5Km2EepOwQFSMcrfZZp77==`8h`r*|{fb z9U#fG+;c)^S`oGl#29q*f@x`OTF1cdIWwG>-}mk{qHCoH^C~ zNlVDfNv?LITD7Z{|11R_Sr+r`0F+j@OZY2wv%6 zRn06jfhQDGClIal!?1jx1+XE8UyGrLUCC#lgK^Wf19``hytI-(#fe{A&E1z$Da?{k zlUjnF!h5YFAB}Bh;gqzx9_PI{5%B?RrNATh^sW84vQre*K8?~qu{yZR?$Oa?!$NBG z5PAd)UmF(OYuRbh_jCYFdU?O9q3=7(tiJzW}gf_i6bg`_!TmEoX!gI<56BkyZ)?DTCWpMy?v6u)k>j4m|<&73dm z+>Y|Hgp1R0lNE6;{G)Cf!byp&PUU^@P}x~iR6?m34}mF~9W;eOX_DNvCA3DN)cGnr zq)Uod^=N8+_xCeP<){_F7VL%tYbA`J{H5G&HiDrOMmx)qe`UYy|B>X?P(fb=;Vu)c z2JRE#y4*7a{Q-_#XBt3wPVU4jXs8NRgIWayr)Mvjdv<1czVYjARISM<@~n}tXiU4T z9e8C#%>dz2sZa^phx663QpbAdg5J*{#=mi$V$1z<&NWQUWgn>}EtOTt za3q1VbVGz59g|TC?wf7!@(q`{Q*iN2rU5Nsuz64&WX(GdVp<2~8M7URSm&@O3BYMw zB(xHtB<*Xpg_+1`DhiKM!6{}ndL@gKg>jW2jZ@4{cCp;md2`+t{+2uTbw(KI7H*1E z#@&F&wv>w7AOV0YDVMq%Ft2W{A@yxitpK<;l9RoiJzmc!3ia(nalFC#^RjtlqraN~ zv|e0wK;_YfLhSl^1f1nBvK^J!?jUzINK8->sUS2o!l5bNkuNDWZ1pG|L%#IgvGq0n z6ul@KF>*hi@Y&b#LhHJc&m6g_`Y;TT!4&u*fHDvM;?Kope|+WC}dO`%Ej#_ft~99O$cKm5kIl2p5W#_GS)FLcj1)^nca#gt@N|E=^V z>2tk%Mvx&F>?>oSKDp~tW89g(d)VMm!-O?VS=&4Zr1?sqKicngd(K(jM5c+33-krk z)Um-xQBn3}ra>@szwQ7N5ILDnfDBPxU{G?yaK^*{ht{^75?vFz^cUZMzc7De*ELkm zvZ=nDNhhUztL@{`Zw*dv)#*KAuu^f)#d>z|m#s_m|Eg}?2cQtn=;$_&M0+HIZtv+h z@ln>{KYJ*S-t>I+^|(eqr2&p*2yna?*}^h^*f%`)gDCiT3{fRe>v0J#hHi#>sEylJ z(mK7BIdF!5QcnzmM4CZw+HqgfJkoLCW11xyom>53#}dqVeqpzl^xONJ|GeTcD+fMF z`o}^+gjSmF7ha{VPt)~*aX>Q#L;j>*>ockgjl{+jDo`#dw1R^-kny5(raPt$1WS{> z@rZ3UACbej(I~)sEoe1Hb6J0_%~1f)-V_f+&UXMeQaQ^alpagOxQd&Zrjnw+BXY_A zkJQc7;11OBW=b_6zD#0XqqR*^l%9)f*wiC5mTus#G3MVtIwI60|7v??=;IP}VVhm1 zH&A{uU!}Eg#;q)I#~qyR51PpmI$7EN!oQ*Jv(x(XR7ZeeNF_dCbu5+|o)R}~+F!Fg zz+KASEp8O8GG@SgcUPN}Oq@-#`1%iRYGAS@JHdj_)LP|8JuA~8b ztX((T0gMFeM4y|JNwGu_<3k_{R&YJXy(YTZxqbtdkw1z*AfHKR3#(j#=s-BJSOl{Q zlD6NQ_IycU#=7z9$w#&~LJPOzH(CS=IRpIeI_`PVrg3@RQn+on^S|?@b|eRAaFHv$;!QL zN|{|HdK?Jtts$XFP~C(eQyH|$`Xt_w66EBGyy-W}01^a^T!;IpDU2^KO@AK@ljluF zV4V)St6)vlUbIOT)o%r2gD>n{_PSGA_AhACHzgm>Tzg1l&K!(&eU03*sREA1sxF+y zGKjnO6e(s4H-~I?^tb7WixT0F5mU)#q5dgdrXb!dHXTx(jcuT4s0YvJd*F^lC8h&e z8e?YdvHN%!_`NuGboB*zy??z}Z7~)RhD?8OGIw?wiY-sBpG`J2rJ+GR3-c9H`Mzt;Dowo*tz}v%NvbvL+${11YX~8Bz)mGAY zmAza?L|egRl_>(lo<}XFb^b1MA8dr&d&t2e{yZT#j0Lk67 zP_Wb#;KIR|n&at6JHBgKTKS zATSMvx#5|$dI*YaQv%8hW`&P9s@@YP`KDjA-1x1ZW7><*3yUpxmH;{5Lz-JG3#A8@ z8?pZgaCz%b$bOKoXD$fV~LP#Q<+P~>7)>6BJ2__Lb0Ua zGQG^Yw5oIIzEUdX?xS?8Ze~0a^FPt zsbe`{cFU#!RW32zmv{Q`km;f@lj^kA=%%qj>*-D>+5Mh(<&=w9N~Xv(v#7toMppTL zz$R=6^_6u|lPH+LR$a|>HZZH3Y)rIxJHXRhah~0A z5wMN}aJMC(*_=1Gf);9*AGqCahFrg4N%)%Z)&h?!eF1R#sr_xy!^zT!Hyrhcv~UMm z?Z=Uzf^k>79c+$n{&kP`09$%i~gKl`(f3wq$^wk%iy#6{QS-;j5- z<+tB0`BpiNO$``WY4-eb+HSBU%ZmMq^fs|@y%jOwT(Z%R&}CH^Ux*$!o|-?j#u4hu zl`WI5Mi6n7%c-A^#}9>{KT-c>Ww@8%L}RLYJbA4qe-WRVa$KG$9N6_%2!GM5XzALO z6nAazdJwK{27^H$Dr=oV=*$V4kA0fZTiW4cED;#Os27uM457TC@&HF#APVk_e+ORC z*Y$SN#tFUv9PYNz2Pq*>X<*%>2% zc5-2D7CYYEb4u)sxbA;7>Z+7M#$!_bSMK%2ec6%#sv#;gM2Lj?CBtUo6`GIjhJfp)0cCYuA)f(_W!Y@8kEyTg<$`k-12DMLiADQ+%# zZU;{)a^70D9s z@xs~e{7TIfR~Ja*=G|vHmKeVh!avp4hnXH`4Iifc`815T?4ej>#vQFL{_6^IL}^jF z2D2#f0%n`aECeLOEQpYe7#f-Z$6o!;eJ%M&0DAuQMc6)svc)RMVu+x*g}?yFZU7)j z&`4u#EYcINgd?&oH&I+r=&iDW`IG0Uu|s{)=H_XI{%!v1aF0exYI71gp>e~pvC>r? zR4Q_f8s#xvp0@_N5QaX^rfGc=^KcDZMZY`Uea(~$RWFy9Frvg2o*0DLWcz>4!NYW8 ziZ3+M2vn6ab~4oU2u`|S6UF{%(wtxoz3TdLnCjMRIPL-yc!-wUSd#@ZylG{(KzOp- z4|~;JWERhY?x=Viur=#?(y0}Idd`(|PxP^#3MAe^#YjMl@fgnRdkW~A-=^r_Dqe~T zS9!iX9k=krM}+YL(79jTAfqOuLYO=@htzEejMKs5#?StYUBfrWjC*Z%c-BNQTA;Oa zrA4L5SYcAB%$>x!X})hJrxJ|GQ~Nz2$ISij8T52ngLIxUm}@zPQxFYj~l zp@+fz|6Y4Yi@@2k2%-aoibVAZ1JLhXW)?EQqgQOx7Q^~SGUINRjcEQ_f zp_B3cMIx?)pk5?w6T`$4BNmIiolv7Ka_u9jJz;0dZ$lMPW5jF!lAAA3Q`dV%MQ_-W z03BLAFvb|zSc8X4*TWaXv|w_&0Ve=O`U_;#N!O0a{sfM)2X?dUm53F_!ndFuN=gK=HA1k%b%8Nm9VVXg9djBABI`nmNUT{|E#oS@GdDF1N11u4m}SV}GR zQz4b5LbejpLNz;)F#|IIT_vVZPMB2hZ~pzhktz~jm|Kl$`XT`Zq*>RWdtWRm%OGfE zwRHImsiBIH!8QWz(KHn8>-siX{pq)y22000J*%`-dacqQ0ngMp7+_9jSYdwY5*PTZ66w(bOWHhRh zYo}bEJd^`_N!@d!#z~(RnSTuIK0C~Z)w0y+c1kzAEZsa6=Ak$sE8n19-B{$F2xa#` z>9Iwrd$u0KrAa)D6|i!k!b$wCDvUtCCKITuBztjM<90$5-DvQ49AvDULK2Y**4*={ zN;|EMDM1h3JOv!BNp}X*x(d3?fQZV9ro;r-#Tx4V{rp}J1AnbXp*ZdVBlml0q^rSW z-4TxQEALLt^&7KyJqHaYQ`||Qug5*id4BytyJfj;ix zBvzj)@tII$^bh*@_*3_Q46z#rDyt(On#JfTG)qh@KZFek6bm3P@s?uATxW=wfRnit zm#!dw+hFg%`44aHK&EQ%`yLOhbO$E9b&z&5ePOv>y;-ihqu*`Q{(Of-79JiqI@S@6 zBk0p1kP{dm%d!|BGU;KwVzUrI#z;VR)MPzVx5$%w?ppLY0O3J_OWl9yJg@dLCi%w~O@{uRpSTUR9O(U#d?pu@}#9dB>5&a`#Z)t*wT`qHQ!pa1~kGQ(u}y&;D68QHqb_j-I^b4 zBNM|P|2`p~X&*?N?gNNXhI1oDAvYNnhgdmPB4y2)vZ z3k@Edc}h7fs*ZRPP{~qqI5C4}UIMx+I&OZ9w{HI214BdNclhh~j1Ss+S-aur{`Sr0 zm0HErG8v7?XFm~MgwxfL-N+8JrxIMXr{bW=++}hje>1S7w?uN<9p3+``KsGU1FMRl zVn)8irmsu*^p%y8zB;z;&C4q2ubUEj;spf`!wgF!OS}8IWMVT1B@nAnthSbpuI*tz z5G*7)l`kBg8Ed43ZV$3`&mEkg++eWAp?4p!MF7r;f|dRY(EvP6G9)y>Q?4tz!b=h{ zK-u!soX~UnB9@Hvo`yf}X= z2Mbk};%DmX$vxY6>py+VG2;S~5hXgx89J^RR~vJsn133q)g<1XEs;P!>a+*MAkZUG z?Q%26Q$PHz{}yPB{l~3Wpx|?zlax3s;z-^PdG?BlO1*-J{A~n#|Dq;CuIdv*@g{z- zNi?U>l*c^DCIXI&f+$6hsx{iF7YG8Ep3`_mzrU9pBx*-@q|w~KTN6%iPup>(8}Nb{ z_QCtv{LXS5A$RFqj30bX-0f$*;ggzc*aRqCx{HueoqCbqV4?5%FW4esysf zVkTSZDKr-JYQ4hV_y!8uquPQ;;+92O2D8KWo6{FC0wA72lhxxJD6YP2nrhp#P+ncw z-i@B~WG!2T*>GQHVeZjoW}t4f0iP{-Fydu$yKXDRFWwkhXVpCMpzr+Hqq>!EyVGk2 z#o@U8S-mfS@}4d%y4_Hn?Aby^$d!icLgeho@|wivVd=@9O}xNhWTpjLn4d`?d#o17 z!$VQ@faA@lrV_P*vg4+C4+dl={=F31i^yEZyjBf@oX*J51fTiX2tS%V!&&-9X02R_ z`&5zYcA2qSef->xGUEW1)$Pl`ac&$@>jgGT!mn0f(WT4n2Oxr0@Ih2Zxuc+}rB&F^ z*uuH-2+r6!J^A2->m6u~1ZA?j&K+lO)ql_L!)9|QgojGGP~rQFw*>SCkWZmx5U0B| zg7eym@K_AlL1dMTqvnsTxOrQ~`cN9Ts~6J>@bTwoDyu$HxfuY?+&S8nDg+%X5ZbTf z8(wMtIW<6fh3tU2k~y~*dz_x0fzOSC`ZrrAQ{`;ofrsR!FZmNMdQh=V2LpIpR92ml zIrt#(dO=S;$8i66^(|QO1s<$<(g!2kaoqgkao$K8y0e@FrJ#XX&WBh&Y@xSra3mWe zDo6*m-JP{DmcL)WW-r0>w0I$VgtR0+Oe}n|6P~jby&!(UMujk~B_9G{d1*?T)zrTi z8E1)u6HtaDE>C`&tdId>mTy>O`|1zLtC-qJ3r<6f0;M-C3Y{P5rdMEpy-y-7&2Mrk zr-nDRY^*8TlliJ{OcnG=fZ8wRmMHYt>NdYo?bbCpZ>#nX6a$i2usZNXq43D(Yo98g zK9i79bNuOo>@e;ktoZ5U=^t|&cI&x^2=HTZErFjS5>(Ny5&5*Fu{%rxUDuXnckzr( zxEGG6xY}O1_1&Hf3U@>M)81g2l}LXZBOrCuv>HVtC2h6K#Qh_n zQGUCNcRJ?d<~~>41s3lWAhR5du<7`&S7$mMzLIDP-k%mDNU8nym;hy6SS}=RxtA*? z%oFe<)aTe7p~ReNEUtFS$t}JjdmMl8aVdp->yXK2`x7|h+)_kQNl-+iBg>NjCkPRh zlo&ic`v&DlNNt5as=k_Atszcw$*F$Y_?i@ib}X|*DRA6}%8|8FAag`<9fTpwb4XX4 z+V=_gz65&MqCQNR>SWA##M+IYhWb*o;b^_P0E!1J^m=E*5a(Pb|G2k;Eo2@>_*i+LXOv ztmj5{X{$at?V)KW_{MO;3Wg5`6_V0u$*0hRqpX&7NA+YQbdc^I6@b~BX0jn0a9%ol zmLNi)oMKMvAO@Z1!$}q!kFpG+%J`i6Tto)0eJUC+GWIts;WmLzMlLSqnI(o+JFIhY zcppTKkrS2$m3Dp%^lRF1e~I$DmIc%2HaN-m)&Kl~#!#c(xj>CQ7DGp6M?HKV*Ux(| zCGi;QF2J*Z-lPQp>nr#rvAwzWD_ZRCk=Yo5-!f;ZUlHul=oqaz>VUpej#)TouQZ_z zGW*~Ht3A$ehzsf(-zOZN9`JgU=?J(-rd0Kzu}s?Xr|h443-roEd5UkBaJmT}t zo1ZxD_Z}~ZT`OY7C;=FA3v`WyN-5@UbtFW4q$0{eJwO*M^r&#NC51}R5uwrPQX1s7 z+OdN->I815i?xtLx4lpar=)}u$B)$8me5NuI`v`L(!V2k`P|CG5VI59e{951TUQzLh zmOl>tH?}1;S`C+foyPzhEau`$qyL4IzPUYKV6vv_Yqx1ejHo^`5S^VC$VNLB2xC1l zL<06HGV5!N-eF{2TwVtd^jA-!4^&9(BsT1=>z0U)9SBqcL=j=@PFcY;_D~fLp<8)@ zH=rrLaufO?;OHYIA6*nsJbt2k3F#=|0sq~}%tOIp_|@g!mZev_Y?2%yG6Mak^*-ow zpK0oX;O7vtk<*Hf@1d5_MKVV+D1d%8C#5A`6<=~vPMKz){Rr%vst0LRW)Fl=Hi|JN z`u0o#@;>;A)^jcEZV$=9Ltj^!BfoOh$a^#mDk@h}KEa7+ipUsVZ`_P?zxP61H2t#+ zVadmC81}fK?0B)jChD^@{;Kaf8aPo}DG4{qC1kGbwS^JfOozKX$hzMYvt#cw~|M^0S_6yXT&yo%=iYzgp%D!$SYMpl#Z8pV{2fF8S=TTxIa8- z-NK~Gtu|yUfv+3N-BlJ#LAKdzRTvagM~i{3dYoMr-2(H$dP^LK&(;Ip^o!J#(i3MiB@zyx)xUq73HzaA?6`=VXx)P2|3L+WG;Z#ka{ z$;yo0@bLVa5k3PM2!=$j{}r(Qwu<8qSy-(%5Ww{!V`-4#qV|x8v2#S9%Y-Z6yvXoz zM@YE_iH4QSlXgcx4*unLK1aypz?+Wh;Q{NEVau9k)h7%J`SV~Mflx5Sy0yKFyh|P^ z1y7WH;v-!PD3{{W%l8w>lX9D8T@m7r3xF1J)YeR=e61U${l&KvbU|AEFD~Jnd&`OV zdC8rAjB4Vp4rDqWIW3f{_w&ZCVDS!#BYZ=DND;9{D5*}0_h=6Jj3&qA5|M*nJaU@4 z6H{Aquv{hWp9zKDI}|-svhRO1@NV0qY#R)7O9x=$1~%v%<>G>inl+N&FfGsIX4#I6LC&^@1lR~my$xI4psEpWWF&>y)S zX^Ebu^j8In6e7o46T%pSk(A-0;rMpIcCbDS10x5Jb|Jo*++DpyFhmJP7NSo9V3;vp z`UThTDKsFL$4P`dP$P0ixsze$A>O4fP)!tWmI?P&B4J2(9-qAIy%&|9^lx1g)iCZe zF#=xs71Oc9ZGA&02nyJu%v*IT?6Fih+|k~Ehw(Q*lv!-*UnarB8B&hh1aCe>dBVy`|ky@+DsC>u% zg}~3GLlv;8$3^e#w02+6V8??{Nqk-wLM%Peya_uHw(D35is&6J&(D!2Ae+t8!&YyR zGbIAYte%YAT2v^^IsQ~+;8(l41b=(xNBrcAj1Yrqm~kiNyPI7|#F=nCEK_dGqv)u% zWOt7tI3g!*E}+dB6))gY!lsf(i>aZwZo*an=1)i|`amvkcRJmu&akK*?rOJ#9WWk@ zJG4<0Q?+sgweRG+3qVz~;~vEa+(0u8y|)&*C=zqJ$rY_A{c*2X9UtxfRdrh&5qWB-BHruz2ocvL2*kfeSi`sUX{}Jn_BP<*adCQMU;8#F6t5IQkH`?^K*CG)IvLMaH}5P{g^8Z>#@8x7*xKB7Xe*7v zJ-xAqN`hFmpzPg#W_VT}wj~6cz8i%*2^X!<3f(i<#fEqqrN;Mg4YXT9vzo_wr)< z1T`oNA5=45F}a71)MBmq2{E`W+@1SCvWO(8@fwZrNv|Ctvl7L~RAS+)W}YYU%}R-E znmyPs0`pciIaPDDnZ+Vt=2vjOOl-n+h(&KQ7d^xJ+aK~3Ox()PGZ#_~P8EqpV zU#`BmsEz0iSAq_@v8d{){?P}I0TW}A-l=qli5T{xg|H;JiwSqBc-6=l7YdjY1lyt} z>8G>`MP*5J=-3m4T)BLA7Hz8hAgsv}QsUcg+lf&z%Zw#1X3C={M$jklA4OCSN4ebt z>JI_nYZ_gW_o7B8=q+!z z8CfI75U`hBQ>PeLjBd2*jcB##*dOmN%F$ZkEoJny=|=NtS-w8*H^Tiq9xT?7x@4?t z3mm3sR%AbUm$JhyG_z7mKOMU9Kqx`>a=tlOCx;~m`xqNR&bBQZ#fXpUJDlpc-+i^o)+Z%%_G3DUPLZ<@v z@nmD|IeddL^bJ1ghJ2#WW#6F`H_f38B~=o2I{wg%4kq>7>Q-(t+-b$s`A4dA_5w9m zm<4(7kxXHD?#ohMmOm@wu+}rG+QDg}-IAfc1;8gLjsgmY5fstnDrc1f#?(O92Rj05 zVuf+=|JwWqsakBkptPQw%7R11)(srpso4Hp%Ne?1EU6Pl@r<;RpzsY&JqE9>ASGR< zWUS*RNX&&yQxRxBkm185JD~U#6cYepM#Vf8W=$(wMV2-J8+5-5De@VDUPqjhZTZ!l zHyu0x-hX%@l}VE6dQsmVU}H(m{#DzbFyZGv+tKORVS4{ZCwxms)w+NWRXIypphQUj@+wL8PX5WZ z!op`P>fb6xk2hcs=0XE@*-D45YGKFmY3wf>hM}0!2$LSqN}6IDtGvvZG|AGn4Dqh& z=J7FH!n=~J$7VLvAL_HItoJEN;FYDZ!dcU}1hZvuH5hW(rzY)DR*fZ22{WRehhwSw zwL>epa=ALY{vs>M%3~9LME{TSok!e)5ZK4}Iq8`LzD}{kgd(HWy5iuJvr7ExWdok5 zC(g^cLjgJ>lD6Bz9Si^M+=?&^9ibldegc=%YBloMdKz|6`Hu{!sMY~oaovu zkmnq9HTh(<)_AauAK{(io@aoDn;47vTGXojO?uf;vIi>t>YW>#DJ`fK=_}1Mm)3C! z3^fD6l6t55Apg9pJ7SH;Nv@=OdfeXu_eYZOQe_2r@RZ zT?fQ2tNO(A>B#c!KgbMSCXh9Zld|(E6ubPknjV7!pIJ5?hw9>Ymv>T)nW+}6(1_ep zoE= z1^QEnfwyv9RN*x)G3ry0ASD^M~ z*YikhCL${=id4UrA+SQiJm#L7eL&km8>X72a2@A>N=M$RyD3JCclb3~B9+);!-MV_ z*99Phkwt?6BaMF|R{26BN7y3P1Rb+w@SDb2GVt)4N*AK8rT&oc+Yuu8@qkF4a)5T3 zSI2=oGt+9)U1Ft%|u9QUrys=#A)qgH4tG;N;hU789h zLnBSWw&44zqrq`N<487d6iQ0iLa8%z10-_-jx&Zi{&nS0WYkRaP2N*cpSB5h6LA6+ zmI3LF!Qg@&@e0K3Bu31Yn6)cjHIvpmTbExQLhT7}TARZaV`;Aj9Y0ju6)C@*bt06C zm&vbmiFgqaRf5Y=M&i~$p~0!}DLabAez4f5%La?q~IpJd+ zdg5V*Wh$LX`LE%`s{=`u$L38F4Tk^HP44Z~hP^Dt{@zFY?c{weW9kZ;)||+GkwXwk zq_7A}t=2a(ctNw0hagr|KYAlu7%W-1A+b$XeWFLkz`!w<(K_Innkyj&;FwK8gY+bf zp=m#(p8V=l5B`(_twiuuf4mpI#=7l)?+{UpYIFJV$fESJ$^}G|3yK)Bo}cVHJ|cmIREKpQ-!&(|jb^fPC#kQNfxn ztJ3X*kLxpCHBwPMeXE&k>ZEwEvf$=HK8`@X%C_mE?nhEY?eZLk&e(|X&*Ff@UT2jx zjCLnw>3q3)$W(RzN zhO{NU068MSqexl-OS9EP{PVj_AMksB#y zwzr|M)NjC)*pBd3`==8vDc*zu2;>IeT^dd^YA)RDx$jh}6JjHme2wUcCH)Hz3v}$v z;xp)%+al-z_-L_P?cmRnY|kT%c$#un$p-Yl)vGZAtMGK<$h9k4C6gFcPg$b&JFEw#7JGuRfC@D z)ako&gn|GFGM0EC-+d#_ESYKa7g+mJ{~tQ${;imB4W(W>E1;QlW8p-};SzT?(Zpbq4!G-SQ_|xX#(u>o9ssjm z01aPpEH7_F&YihpmtNmjD$R?c#*egrjEO_PMTaP~sy4@C?WAD&myP$$b3fSai}G{T z7;gE@1%_KK&;!i!_tecShF#@amt-cS8{Z!2+S9Hw5@M&Eazx3DS^+^o-AgL0qNAlR z-z#E&>&5L9rBWV4DPTm*fr`e-_j8(8kuQUUc(vPnB%F6;zUb;?$PqU+k|2E`ip(Kt zIchQyF`I+Y8zdNtX^LOs`;F{Jk`}`&o@*)lazKN#e;v!;#|^2&HJ_O+U#w1g3yig` zk9$Gx=r_qzooTX=20t^&62!aFD|GD_P)MqygTDmoCX!&jlLXk9s2QXG; zEGy;8aqXz{#n4ovdH-}nRv-ulFr`a z9$l+iTGD{M$wnK1Lc+S#DZ)$nc@y?yUI}y)qD^O--zu&n$EtXf??sv=z0X6t+xzCKP$Hrs{1$%Mk;g6lb|Ml4_S zr89wYLQ1Ffb=a(A7iD_jdofbPs&O4iw#;R$;>i?S4>?j_dZ3Ilo_| zrIsHJvJtfI+PHxXGK%3Mw#vAgs0`h2r*?Jd+7#;gM_LRMnI8y6EL>@**7aDlO~BiX z!dXM7uk+yYEHoOn`0{ROj5ozKxm=h}W_Hw|SjDiD6Bo!sacqoMV$hk*?pp<9GWK|UX54({?#I}dpV(XP!& zfkeKbKdogurSDF(y0B6yWz^5P*r^6zGBDaCR!aQ=*r50Ikq!<&;`55InpWw$OLV!N zFfaj-W=kW4fLN~Q#+wNx-DB83+>CsRzA7F-24K+|ZFpk@ z)XJBF?n&deIAog)7b_BVaW-a|vaHCqbN%>V0<{Tgl^|9M{7CCD?%sNCFBmCh^>+}{ z2&y+>8LQ7GSaQC)wyBQ|V~SNu;coc)P_W8Hz6Yw0>*vMB)9>W>#OnboKtY7wlm&#` ztDx8nsW;BQ7zk-ti9h+K7~ZIbXG`ul*%lC7z1>YLi1aNi_|Npf*uttl`jM$MXLkR_ z!i*^xU0=x5joe_6EI>jBqLA9^yoTk^Jpjs8snQXoiKM#l@+x_mxT)x#!!J1Ejl}UX zYSJH5>tq;k|IqN;H${}p7S{`3B**Q>Wh9t1<}bdij?^S?{hdV-ai(W@v0M}hi8Exd zb{L1m%l#>OLAm1}@nK+~G8|R&JUcrAeC3BIr$$asvW1rt3{p0!*(MZvqYh7=H;6)Yq3`T*41H4KY;We0Tf|_#D z1pfShQux^NE0z`8w^cQq6M(k`g|dM;ytvKlr6Ih>sb6`#z;R%+NxUXrCnBdboGi%e{G&d-P z)~=>l5FEiu+GQnJ?G8i1?~zV>-&KTmyJM46Lu+JXQTr$K@Y$BXr+@@wJBcmaLLNg8 z(`+IolBEFGUbQ4@K}zK+P2&_NgY6EfDeAwrhyP2`y+^}jNN{zYEoW&i69_j{?`4wZ zTc)Mx!Mw173rLnD7g*<#6JQY89G2}f_kCt@*Z~ImgQ|?=4-*oU?zFaE8_(1ckqX?B@p0*dTgNeL{9e)X^$(L2yRqp7X|*tG?sj{ z=zqiTrF$5>`vw3K7z_Itsg3@JSS(_ZbMGZAZ=JnvT%eg>TSIacx0kQ8p76GjKOUjP zy#-VqTh}d!yA#~q<=_xpg1c*QcZZ;X5Q1B<0Kp}=TOhc*1qtrKH8_2MBscfI?|c33 z-#xlVMy1ZFs#B}hs{!Y^u~kq@i>jFK27N zz475-7QBW;3&efBz5^vggpU86iW^?jx6`(ZUhNI;hePCjW{!MFdFK`5mmFdwUshBN zA!1JI<02v0EHPh>gMbsU+Cm^NgliocOZ#US%~$Epzc*_3|L|Q|k5K;o%*FsMh{6B^ z&fYqYw@9^+fDbSF#F?Z^qU16k?Oe&E;lP)6(qVCMYZef1uOw_yMa^>b<`@fdzp5Vy z<*@+o{zKP;xr27V1x$!`-jp9*U-2v2HuB;sG+G}&t*@{0F02J$(*$JreD{(g7GE|( zK_WOV84ccl7Kygb$XUcH+&ZTUe)ER={dl5z*<9cbiE>{?sr>xLB{9T4HP?m1#F}y} z>>e?qQOb*XaKlY$KapJ_=A*!VN$E|c;=T8^P`&tRAa~~p8XQ|bz>**mm`EEj_h@-^ zBgnDQA3_%z@FQ?4*buJ4O1-N@;q4T8>~RPx#ILbm3?;!aR%W76zq=Ek6ZfS`u{R>k z&{ScNAwLSX^@XceuEFt5lEl@FY~3w=_N84WF$vXf6aY!{wnv3-K8eiC;_9gKIyksQ zFGnBJ=EE&Ps7&rPLHD78_UyACTznnN*n6@hzH>X>xfw{yy2e!4inam~f`Y}fMWpPI zdm}F2gIsv})o=25Sju-Bnu6)1oQS6m0f<@TPhUjl$mF&#ks@LGuH>_ zA0{mRkqmQK^VH@2NA8*7W5`~95w7@8U6C=e7G>i3J>0G9Mj&6bl2#U$#pUGW1uA`< zPE*tPeB(bmnqxxPeBkv7kAg8*N-FF&jLaQ8OJqaE;C!Yuh}?k>|Bhugw11OxoucJS z*QkkOL6M=31B=`|c^0`P6+w;V^bgL&OB8`hIj+lesrSBWNq*UkdHVXF&zRx`_QSr) zM1_M{NrpkmXtNmU3Gdh05Z7|boP=NDeLggtw>Py8>#l#H(;qDzH9AttX`5PhDVeZz z*h88x9H^DYn<(My#88=7byA9|<|L`5&UUq25mkGu^_hZ6%UTM&DxA+TAozQSJ|QHl zYaksnyK02lxj|vvwD_qh&2{Y#kK#}QUKT&h_nB;HCeqIAQ$e~Gw2i>b4LK`sj2Jn| zTnM-4dt8Emc+e%J>NmG(#p#hUD(@CWl5%-frd|fGaV)2zE#;w4J2&FC2I!^?l6o$- zCPZnr%H=0hLAz%aRJ4^g5jIDCR51-alvM{UhK%=Sgq}LZ=+)@=t(6t5Srl_;Iiyvi zO!EBJY~aiSk4Sg&{m6v30IfY%&@ghkNW}CrBX;Erd>ZD#jQ6n0IM`Fy2&v)8Bb^+srisat=@+LaI0bYFya zB+6nMzlU>~M=FysG@AzboaJ2gr3y&tug;TJWw-KmZz?SZHx0QG<){?^3fkR>f7V(& zWf>e}uI(jA_#9cv&JMejV_2a?VY4UHKKx|j)XF|Scd9cN!r2E$*5a~}Cz%NGqXt|N zq>6;NopuK;0fT@WY^-%U{_P>Zmn=6OXSUokwO7JjjGnxNnT?vsh#S}jAN^TOi5t_j z@Y9IVVGF39N!q^&bt8Z8mPoKPFEiHyivf$+)_)$r#em%_1L>frpIbPy*XaJ$in1f` zhrm7h`zjn_IWqzgInd>xxd81Z0>53>j*b;<+8SKMMq+_?V*W0rkoBKwt8F~Tq%Ij2}+Q5^re!j-IIDTBrUy4Qj@Wz@%UyNDSxY4SswKQ z&|M!Wz^E!e{SNdjrH*kjBCcb1>Ds`^|>loOiq*ymwed zuz|j58C0NW7DhPku^N|Rge)mI3_CODR{cPH*b@W=uM^G%+FML!?m)J#M zL7C7wI;!7M6dA0EcCD}fy`DD0)hCT%csDu$RuDvP zoYVAX27Oc}RTg6polnv;$$LY9sj-;?a_GiuB_lOtVMMk-Sl+5iY&RFCwML6$i5i572c6eEnk6Zak5v<-bGx&eGPg{8D z&@&@EVo%0%4ATM5M|&Mon^G;9jck^E+~M@$$Y|PB`R!(ti_u_r;d+^g{^y)vXLWZO z`~-+?4A-g8_^p+5V_sn4@p73V9wW@Vr7z6laQ7zp(+#O~omWYDHw_Q(mir^5bMqQX zq)4H*Zej>H%3RsH-&NS(@-VmLycmH?xORWNHMLj%_NYYJuO(kR9(vyhO3jhc4hq*X z)fk>fl_#7+KUDM7?D-v=R>lX6C5bI`@r9<~kyajI`Y-6bJB&W^q{C1x)|QJ{5#M3p z;K7C2_;11{;}-Yfzs*Y1PT{uQEBW=geR>mjv9a8<3TIS{iU#^3^IB>r6Kd@K0##(^ z+Q!16LtUp_f}jOBR_ksFE4WYnr2eTs*okgj-7u*iY1~h0()z=_a7$GO%P@|EaJhQJ z67u^`>M(3dMH-4B#{gIkJ0A|y9a9&~d=W~$QMLdp?#%UOL)kEUOay`pdC~?ER@hIC zI>7!E6-?&a<}=qHnw#U@5{L3)&tfn6zd-kX;g6wP%J_a-e@UMp^+p22ocW*xb)qhR zGkh}8(7*vhNCY7E?JLXk%AN%zclK;Bq#b^2h6r&s-;eRRXaKF^uhn3-hxC~*$`|BO zE|iN}pON3{w#D3q@wbI+k{XENIKG|l&X`tuHwlkx(*Lmox#DVWgQMk(s(a$$-f6JZ zf!JE#hG+TYtmF{wmiQS6K#D>^eV@%3YD)Oq0f{d((#bWd&bI;I7fRZM)Z<&vcQ1p8 z{r2$a2%{i{Ev~+I)u=-qT^39n5b%7=W1nZFJ?}FW4V#N)<6`IDuIPYgWazj1B4L2F zLAgJC78#e+!CtK~*cxw3Gw%9PLt)6!2kSpjJwK9x1L>HxSs$tHf#mSI0CsJl%9$>J z^I=EK#{NJT&+*SqmxW#XkHfkw+}gk^by-=oxd2?ctQ^`LKpt`qF5vGTi0?T8z~8gz zvatXerP+x&*#Qsi_quGH+P}!}IoW_$JrLhB1OMp8s{O!!|9Arc2k`?3KJc?HJ2&v2 zz{3D`T@IE}8rE+@D413msfi1Br~ z*tP%3jL*&d-~=&{vi@Py1+cPfv$L@S0|Iz-4#3Iz;5zX8gU{T+2yyEIxLCAVIJk9x zv+8p_Q11Vt%KphP52TrA{z-xlWYc$kAesk~$UksxEB!a}cqSD)Ra*-qJ7W`IcpfkO z%@i+bY+~zd;q1X6!KCs)VE=HtzewXBS>S)#cQ&z6BmVEK{(sQLk= zvo_#~0AE8>ix{Zgz{U(TrTa&WALJaKV*F?sz{vk!`oD1`WbN+PT-ULY56BHJ@Cc-E#i-U{x<#i zApgQN*UyOmW%@rwockdtf4uFdJY!{HVPpnk#Z#WKvavD#n>1s26vc1`;@zKKvvB~y z;}5U7|Dw$QBi^j+9Kf9ZZJF~S_x^>`ERRs+tPRBCKLY-MXMZ#OkcIz%vHv2J@dQu5 zbuxe=7e8e(o_u>!$>8{3fKJ4~+QQJ$0;n1BKa|Jd{tIdU))D{!#^3Fq{jpj6i|7D; zMh7TO@+&$IIl%$cPWfASe#*rB&c~-#_?QO2-^}BC`WLoY08jbI{uI&Q2*CXJw(uws z^G7}ce%gLagx|)wfl>GuwgEp80N5S>={MVhV9K8v`A_6~vdzZ9{0Hc=0U?0>-=rjf z?a6W0N7ac(40s4SE3hyAoALh)eQaE8jK3QquzzA?{x>ZV@UtcUXn59oWc{ABF6X&?>)M@s+a-5gNM=CPk+ zdw8F}QJ0P7?;rq_;rYAQKU0nE(cEw2Y+OJj{5Qsb_H=(3|4(fU@The3N6dd&f3)}8 z`eW+-8|y#2c(w=Mo?L&h4q*R#9}i&u3jzNC-=_h^FXJ4n%>NF2eTk*R%kjr{^~?5S+W#BBS${UNCz+sM=)(Fiy!@ku1DO8_ZBK)nr-t>*IQs+0{u|>z zq3s{7jP>Cq{LT17SNyZvc^tj6u{{n-A3G5tM+*b%|NAj23kOgx>MzMDAfi8vke?){ zfTw_iRABg7n1Q*?$pTDUAt$4UfgktZ6{lFZ{*~esGf=a}z}UjpjF|Ng=_xigz+Zz# z0P|ni`D-}(-?XOy4+BnMa{lgA0bGDzy($1GnDub(sbA&%qhEar&;PVLeY!6&_Q2WF z1K9ob4*(p8umUGjj~f>^aESeoA`jmlu3={f4tf8}_H_2IJ3W2k-~i6|fEy=pX#21M zMa%#|{V$-^r*FUR`mldE`f%;T%ldUC@cPFiPyhe@?!TV|_k_=f}IS1J6DT zthsJq@kDZg__w*6~9CQ9|A-@#N{^R@-0C;NXzxBYB zJ!}l^tpAu;0v>uAU?%+^&MX1UfAvJa68L|oM+W$ba{qh)b)b~mQ@8VfphN~#U3+{+ zQQ)tDP4+*{c%SV22^t)K2-*Gg`T+u-lFE6hi}b>F*2aHgBPTFe zFRTsBoQQz~a#;iSrwKF*2N2l)@ab>Z2psbKe~68o+ z^@u0G5b4*ipY{*dAFlax|M1)o#~!v{IQy{Y0^;hg;}3fv5U_OX)8t zeFTCh-1wVh4pWWbXMrF9!a4WQn2r5`{USzSfm^Ji^_@s)H*Ky zy|r&@KV;Ds6yaH%YXyToAJarsb1Jw52uWF2Me@=lT2c-GeNfU?)kT(9s|q3<@M_O_AiaDCNrOlZFje$8{iwJNpJLJRd2EM-zEE0moOFwzVah+3(E>JY< zxZAK*V?nm6^vyroUq`i>I$)_8|cMnj(KwjHlhvyeo_`pLd z@r`F9ZpIN|@a;x?QOH!Os3k+FUva=vvcOFu(8Ti0$-q3Z2j5$b@t_MZNpU);BhV&R z(Ma=HvqhTrfhfWeog+ABS9P;mc(d5`J|)efyDyEJPK{_u)~Kq1u>j8@VQp(P!gFIkgX=ihH=l9qr?St&-h9pKRDwB}n_0RL zjjuaQ+?<6IUw!fU^KyE)S4#jikAk&&^RAu^5@Job1iIC|!#B9iVFOZ6m zB~h%oGtaTBnYH>?2l#Rhsc1)O>n86uw+`}qqQRY*2x60OZM`sA1lyk{U#5Q%q?ypR z-NWWmAE&6MPIT%Bn)M+<>MRvaJeDa`5QE?V=nMxU+Ds08+emDM_9LOg|f%@o_{Dhn(S87ZaPcmyN-DbNpvBr9$Z_@~3$g-=v2?62dRma}w&9x7q)vg2dgqETXd zivquLGEWdB_vuiIpuSnhBkFd=S3Z- z*=2GXSZv>3CxRk|!$QCo4YAP31vRTZWLe>^3}Hc_Bs{M3v$sZLvv!JTRL?+yV{2J# z3m}*qh!0Qext*(&!V;bKjA?S3-drSViS}w}_Jq%)lO(MYP0a4|5Jg&F;x~$%6x$f8 z8u^AQL0ZR0S3~u-n2|wO+$`JRo|>sHJQqEs8oEo);=R0#R1Evhdl8k}h%&3O)o7dW z1zFljEVi5o%E}{_F}~bEPPv0(V4(A)$^&ZohClT%u7-#Qd1%tUe9!JxYem0Qr+Q`D zZl3d$la~H7z8QJ4#m+s&b#iyDS~kpGfTV5=q430(z2mcQyA6!9IJU+L)}&gQuvTT) zs#Yl(=O`DJPC18rBR6XM0e2OQ)!(Kg%fj|JweH+4`x04Y-)MB)2-j)by@L>LQF{$) zvUeDFRos@krpli5UDRV)VLki(D~1=(2#eJ6u?(G=)RV<=z5T?TNk7~*?Bs|GT;xAa|}{7 zAt5PANA%|widdW7)k;=C4Nmc*$xf^Y!JlL&H~6^hFNHM+hsyR%td_g%6|CS+y$-ro zUz}-bA%{Uuf36?Ro_W?@2$pbZAixOYvewASSLwuBQNM8N6VdQYVUl2z_kx+|t}=0D zl)=8u-fJYX(hsQzXGM0#5sNGHc;ZI12Qa2oPWEaGnTRq3_Uf(<&ikD64rE9W;HsgY{C3u{7hOntM z5V_!~PHCBjfzny}^Almxk=dsdQro{7$5CJg^e6-D4|5YJGZ>EXCS zN5m`kKK3R4P1f6H(z0Qg8)=mgxy30N4Y1O~cqoPBnGU>&XBpZ#n?geHgo z#U+2%5mqZBUgE;VjYmM0qfm3ZrwYLu;DFYFV=(qjTJL$>t78SZ8>~%uGJd5p5-6G# zZ^_(Uo}{R09TzZZ=LCNQBMK9FM z+w|Kv=c`i4s_SGwO4vDjJ9NPVwWS8YdaY8?51o&wEsg=~=DaWT|`vIrAk>GBE zoqixmp|Q&=M+6s6mgG~7Z5y3J-F=*6A6j=%#sf#XbTo@7MX6O_6u^#ShM(gkMQ*8) zya=Y(7I+s=*H?kFHpF?X-qyPrt{71Ht?p)dD{0Vv;Bc3A*YCOL0mCGTi54Sdz;<}O zWe_Sws2fLz`&n+^?u8}lTGXHx0z~8%H7l#MV&DL?EG3V-%Rnw#pYQ!_=efoCivrf` zuhz75J;58Vs&d8$6-HYqUnn7p=2NUyRQB=k!*Kvt9XaG!E*~V6_#`my?pn{$krI#tYA<5&37}!U?l#6*Lg;&pm?42))4B}-L(4;c zQU^|AGPQJd%N=gK2}s);jU@l5?3&|SggecP>Xa6i*9a#Mf=D)664BoFq2^NcfClRa z4LM6c76rZb{ezGNJjD!;L!GJL#__H_-IbA<&drKapzRw6v zxOOs>D0j+dv-2;tDq}}1V9YAsN$TCDxfKmTRLv$?K?64aC%>qO3s zmLR2);ZcGlCKgKYlJGl1-J&Frm6by!zBe&4bF1nCT7jA4~4Ji;zJ~w zu)U{{sDPyjuUZHM$*GWyU$$d*N!a*y)zeRtU&&(KdGE3!|~ytYbHdGN@~dP$TSzKd6=*5t}xc zK6JeXQ0$8kej#ik)CeFMplDuAM*>VtZc zLp!d|%>+XJVjICBEF?br`3js^@kgsq%O!aRq}9@;=Y#{(vV2%ZVxRFozhF{$;l)^= zf!u<#7{7u*wurZphHp355$4p2N?RT=e&ihiS}e+8Gcu+ywSb;h0KNj~2t!<_Im!qe zyrh3?N<&|ABYYFtxaw=}IYqF+wEW&7K)evo)^cC1dm~p;fY8t7M_2eB0M@uqQNvLh z?|Sj|{nop0!!WH$77c^jb#WK_))18$pzNN0UkRj)#w=@}<1=)Q(|4!K+4QfP6eRnM zFy+|Jb(qxaR3~|DzwYP?$s9+aEoM`s?out2^9H|*YZiDn0tFToepHBPSdreri@DE~ zNr{LspG)NClPoBpnA+xI<;%f*7>MdKD-rq0pBd69s6CV`I~YCeh$Q!L%O^jq)x2Iy zir53-CTqM^dDq`H=A^0h7QG>Y7oOPl*ubN<*d4Fk>612dSC)@jIK%B;v;;IG?e`>Y zHfC%<>ZJgg@jIw(?8?(|h)B@@&>+>#*HhEX^i6tJ~YpfZWURS;EazKNG3@Q zt~U+N-&>1u7RZNZ;jC$%DTNdHIWL6iDjYP1VHRZZ%ZhdsT+9hf4Q4E2RS=pxU%E(( z)xLY;bU&`pB6iOwD{u2@Esx$~q;_q;H|zpk3KnCpY+6<$L`O~)ps@>5$<_51qtlG3 z1)L~&A{***$!OD4S0IWA&%jW*>XqN)SGWh9Gi3OqKsjZcH^0eNWblAtR?XHFDrWcO zMe&`UcBuP$t*i$95fnGZ{xsrj&$1EOAzh0oFoL-u_!Y6~NfM>zh$&v_6-Kt68eqiG z{y7sheKd#6Hh9l%+K$~AKW_TAu{PAbAZIyV7QG(^Ht7&1v7}LeD0pWW@oPaX=R%w{ z0xsmNg>X%%l90%qzN7sO^s`3N>4{2eg_$>3OPzA;DG)Chy%@$8k~W1rnb6~|eh4-U zcSC!I3;83=v0HU#hvE2*hC3cQfUV@`c`YUJEF>7}pM6Ulp22+w;JikAzr%o07B9>- z+j>{|6>2Jl@=g0$jzlt3a^aRS9U`d=SmvuF`U|CHvO#z9f%=u!T7(8q9C%suH18cX zU4EBB=}F2>zTxaa@aZj$N__YGT;1+>C_{~w2|E`K!{EqzUDRkx&+cH(LS9PlrijYF zX)AG{K(#*~Gv#pTEYH`Q{s=D7=5%87-kPahL87Q$L8bZo<#eYf_iIGU8)MM>%d-tR z_155;N;{5E1|s9Da|XXPVIhIcjqGDc8Es@TX&DX`0wnx@jMj=?Mpi!(lE_N;YZFLlbO48;4dz3#w~{w^uD$DQuvI_Ma3yzxpi+Cs8Q8Km>)h@; zXP5H6+Lt3p|wj=_6|!Yc39Vd8qOJC5k)W@&tB2jRCS1jsmuu+A3tEP zmVGwAuFi0~)LUPG1I=I@(sjqZFmGU_m|!$T+rDDnMdEXO4?$#k`)!;zwNJX1n3~Xn zUAuhN1E?|YyzDMUDJdj+%fNDfLq!CCfL7(ZEcA+1nsk3)=-8Awm`(qJInB1IbNvn% z!BzoEfp3)q=M<|z30i0hpHdechE9xUOkas23(bS{*wkD9<6;rP{A=hn=X>vc%J!MN znvw<+24R1=Z${1^{iZLX-b6eXRZbKSEPP2&Pj)!mO>H@P-6>g0R-6S|*M#^m>fn}t3W_+{9$)uIB$ zIqILuWB|zdLIZ-_&h@q9lt>2Po?)IkI38|EVc{8ms&*E@`v84X_Uc|o+3Pxd6-JjF zO%0aVg8aR?Mfd$}E{wmM3sn`9JKGvQ2qm2HDI1?iyAVAu`D-T8LF1H)r5;!iGU!Y2 zJ^{pi@Hs>l+4->Rlol0Owvx)e%7IYb;((lGaD)NKF}PJXy*SyBioNIGXWuK3I$rxj z)vNMI4WpB^3h?!qVFZJ*(2~f|Lz{FE@6hqpzV-f1hs}<;i#u`pK z+};v*1I{^7m(IKJW=N%hYq?2Vi=NM{wl(lOSef2NP0n|t>Ihy60(+U~qAKM_@hMF( zATGU91S5U3=P>515xZWhtLS~#@$aBrHB9Ro`+E&Rkj;&a&)zW2%9o3=Y_GE881ZJb z)(NdPxGPF4%ZW6sZ2Q$9IRaqJ+N8_|S+1H!lLXG}zoRA7MM(JC8b*0aN4BKEmC>|$ z)hKwWL8HIMRoe>QH~7A@#o@0yOcL_2|u(X(`#4Bvl7ok;WTTM;DrY-bexTE;W%XIAxNC~Hyfnh zF-cD#WuAc4p)P|a|A=W(C*Z-tim5t3>6KFGGY40oHCL@X`}=9AcEmk1TvMe{<{VdSDgw>9F)3AYR=jaCne&4rcY;zP@V z@ZQOAd!R_1w=JnRjS~e@F;{;wf^-W-JbI_uQr#-W^jr<2t%P4Tdf|CBp)^=cmYUPN zBGJBMRlWyg+I8sbEzj(Kpcla)1?U2?j>}2U1}Mbvr`HA@zFPl?DM9Cel2mfn zjcxcEDecrSY2xk;=3~HgZL!XI=Fs3rcJ-XI(0^(Jw=B-ptzx}j8ft>L1LWH{1pm^_BR+LX98V;l1>|3iV z>`@1jyQp$m*`btScfXYgeX3!>Gihm4G$gGx&Xv5bXWpYO5)PjS`Epn)+`zT8wwJR$ zB%7pfF%{QsrJZ`9wZsU2axsu)0ln+iG^o2U-9RsqPhi%4aR^DRl-O^Ww6Ms7Az|pG z%BVGLkY(x0TlK8><*Y$33iF3E62Vc?F=Zk;N$(RnYV~nK4!s-I_9VKz+}6@j3; zGT%h01bRp%W3mp{(L`_HJ<&;OMuUrt1LA$ye$sX$G<)cGo>R_|+5Q!sPl8Yx;Gmgp z?_)Cy+67q%ZHV5s;Ab)-xL$0GQQd!{EWnW5^*jWs2v~2?VWw_;lI8FeTlDCeBKTU4 zbqh6I!HxC<6*UDnkB}iw{+6Q6b*UfLB7P6o211vfzz8t{nLlS` zyX@WjT;c5oo&BXdYT33I%_Gjz@#b~=`Qlflpj2Ik^Wr$PQ68uJAT#p(^oclMCRv!o zLR(;Oe89 z{`|+gya?!B-iuqWx+_rwd3W=9C6ItVP!^^4)hkX^S1@$mbZ=*h4mo}C)@!hrLOFZY z+?hd!6l?0j@Y&QxxOCuBRafV_2q<8}s9kP#D^^cdPt8d0la*ww!vi=h4d7NI`biT# zg4ZM$92+i(qXceE&_%v1m+Pcfu-U5Bt~!xg?#Z7^WlEzclb2a@xSzT}lo3(e9#w&O zSuK{HCRaIAK}slW&h8(NE4{vXxnv)Yvqwa7-(aO;n@f|`VvHHUv_@F%!aeJAse9Q@ zFA2@UuZxQfkC4VdbYza#BmeT1l@6=57SHT!SM==^z{VMJ+PALb&NC)@NlyI9{62i_ zQ@k(2iO~M{{IYDdru1JDeYNiC8*kii0(cmwSdk30ifScz{nQt=u_aA`#V-r+B|~V~ z4e2sX*dR(2mI^N}qZN_Ik21hn!N1=tS>(ULos6TPBwCorA1386G=#5ci`6m?v|1D8 z9)O4!^gYeaxm3)}y&ri@j&!_B&6JrisPTO z2(Wf*zt%c>XY};pP5JPg>;Jg*4L>E1co)dPK(@G#ijx{gG8}{Mhok6ID?Qek;dCba z&bXhOMMONn_j$39;){~#&qj=%OtS63(i{|x@v_)YX1iS0dP!tPxzEtZt(xNCKc5<2 zE#V~hquE8IV9L4L;q3B$X3&)8A?PU&VZ`I&qA?c7Y>vHI`%3RMW-7 z^h}};uiN%ZwP$Ceb=T@H?i|!{g3f0eV2tuxv}x8k7>?$0K`f+WpP-Cxd7D)?T5sb0 z>=Q;pATnx;(A#_O1)^{X~pjZLr(cov}nE5T(6nG^OeSE+Gy=kWwnlEQ^P zs?s59h9tC$KF{s;n$hsPZF2xh*Jp-;(UceNsf%iHg>eV3wbDI~KG~@X-xH~QG9=sF zxBKu-DN^7ix1liDyY4g%e-zA}aJJE?+U4%He#7%CZPGR8Ljo1ImqjlZBHmHb3FXe0 z*!fTNNYyiqIW~Rnh;t`xKJ1^@SeGi;msXb_`Un%*s)$TU04bV3okH4VYZ>sp+Wf+g z=?%LUc^E@2>4&c$I|_Qxi?4c-+abukMwXFIb|#rVIyyvni{qVs!djBr^MiiwAsxev ztJM6%zTBMGz_)@Ki#MXzKHcpcFTIlo^bWJDCVN>}bpE;?gmIXFw|(!%%y+qeO(j<# zsN-YAh0MgxYoyxK$q)G@y_3kQMf`POa~eHpR6}9dpuv`bwd~&U7l8e*)*FnT;2+zp z$>e>jW^bt@@$gun8!9$@b_H*Xj#ALTVEMAnzyX1c%)%SOnF z_EaqiDdF?He^!L``7&DOrq9NUoT`^U*iq1YMbodl6%!?XlOmFgQ*qF<(qZ6EwcP1m zU6u(;1v=Qd^q%hIM{un?-pcjGQ1qr|SmCP{FF9E?UWOKGgE2+wAm}SzJH@?1y1u$sMuNlXsk2U)^JLTVwb=b6> zBS>hbmeT0S?=Z3^g6GD1!mWE_Q}J4b8RKdl1F?XsATNm+pT4-D%{;v(yZw-uuO##o zvL`>P3w2nw##)jTGH`8q$GwHHj?PCBosQ= z>*YAApf$<0f+j48!U&NzdYp{k*}Q2}G=kL=*-Otqh``%1mdRe>Aeo(RbcTKNRZ$U27HF{DQj`6+)ibMhD-_+ zKSA1zupJ!{l5c{^PoWs(hKc{GEBb4!IkDPpDP*uPa?udkRh$R$M76}80plt1IgKgT zGc8?i&y9~4sHBDTmkN1{(WdHc5HvMX7wc)H0;0)A^i*r__GcE_c}jZY>C>eZ@O)&K z+-*z`y+(-T_PtflsS{xnuZj^^t7~2BjP4fSid8~SY>_hBM!}EK(Yhqkg;sMzf+ryj za$cSH!tdZU)ekG#xvN2wUUM8b!NN7zd2<<`^GAX}cO+k}y%klS;G4fma-DEfTV*C{ z{FFjT#G9w*?*uC5fBSr=Pz)ya%|Q-cnhQG&o5=2wufCC}`D?rhJb;@s%n#x5(ynDX z^-@Mt1O2m4&Pw0pKiV&R+bjX2W=PyxhDDLb0ueRKn5LLL8fHsd>Y55H%|{_W5kn#0 z9_evzeocR0OJ{bR*%Gy&#avy}M3d7c`Zd%zi>!4alI5#z;H@OP&a2=?p%9_h zG8l5xXoKg;z22MOoR~sy+@;sx238ALMb* z?N`4vFjy0zLeZkK(dnAlelehv%XltpIjmjV+hgs9Y(HWZWqIP!`1yPMD%%XXmclmN zTk8Ah_l*-5$)Q5al=@O|@w?|O{PX6BcYAL~QKZxJ%f*quq6xf*Cp-CmI)40~SGEBX zb~f<7$I9=651N9lb&K`2=SQo&Wg`4K`f4JI7vz-LUuw57F@A5HCQ*rM<5izM;>du_>APPKXI*T z3DR$3(8YI!M5>B!RA&6uly@4xeII4Tx-OEl^Ni zfrM|D3sH@PjoZrBRHYt?OY0gLY60)fC9x5UW5_d9HI;hF)t!Xcg`K)rZq{e!iWh2W zbkutvdTW|GS;VWRUOBq-736FcxoPj&CAU^wiU7z7m0u9K3%03J31_6B!bHNUJe6(Z z639>y4X((DZCey$!~_AQ+--jX3e1;${_o7j3@yEBHY;IjF+_MGtXwrSw|e3<8uqTHgx+Bh1DbRPySq6&7GJ1kWyim|3=XdKN@;&RY;fe2 zmfDGcRaon#UDML&gzI%$%yG7Ja$Eg*GtXA(ZR^GLQaUP@RpqO+Z_3x0Yhu%HlI5N0 zKiQ4PWzfi3ngts)>do1>0faEs4`2g#b!lIhLbVf?XnT^x#bTBq8{700`k{Qd$FZ`| ztogF~QlKGI7kj#%=8$G+X|YHO?=YS`nq|(hx(yomUi$rogOs2?_K!iE&!qm4QE?XV zEDT1r;WazioW;xpy!G9NP2mT>v;-F&mS`$HQZxH#7Z}hhPW^++)W8d7mcWyv(CA8~ zvkSprgw!*}LC~^hZo+G!K0bbg4DsEZ)F<)SuzJPvwFKIBOn>ug=J9fCk%~Yo3KKIW z8ys&XKXJW8mS!{j`<%ckIVS;DC)k(DAyA#{BGjE+rOPv~D?iw|Z;P2MHjD1c+!i>L zYVm`$t?Ol6`EA9i8~~O&l_0Yi35EQEz-T@an7X!?S~c|2O1?BM8qHA$8#>+}GLag> zoeqr1sH+P9wF`_eQ!2S#Mst0heALrqnsS15Ix!;f)-tmcEQm)iQ!D_ZIMW9oN6UXZ%T*)P z0QBY~+-lyj;BWxG0__xPZAZo%xUx^jJNMBnAXnM7xQe(AOk(ZW#p$p7KGRi@(>ab^ji?^)z_aXagg6fK?40G4xPyJ zrgKbTM3v`btkX-I%4HCX?KnzIqHQ{Bt}SE=E$XQO$UgfziUy;C&}7=KmgA#pc62?w z5Z_^}E@R2zeWq&WIgKIB6EH@eCDiY;(B@*9wGCJKVhCo>8b=xM2D$g97*6xQNxl4h zRBLFQDCfqtX26jyR!14NIfHydVa#?l$IhP`V)@08FYKCE6EO%&Rv}x9bkp@~mXwAa zymS~gBWH;^1i7t%ld19hZ_`?Vu0TyR!#s9PB>Q6gbNpULTM(8SeE&4Q*<+#|zL(kbB);lvu~Gkz=SM7f~+_ zS)jS?d{FZ%EYYCn=t8-~Q`M=DXOl)@GKs-YTi{fth@qZ`&|Wk<6S^6*FeCUr*r)}~0_$8YeQa^0WRrdZq^)7G{j3~kSi z;_G`Q$(S99u9jEyy{^a1upitxo#bMVIK^$RsdJ}ZIlojN8p%J4;t;ia=JEQn%#_AW zYh3cPix(3r(i;l`adl(%EF$tUPmZ_^!esbYlWarcV9#|M)o<||*64Rc*rM@EC|!u( zD2r(Z3}x_uNO!TPtDeQID8j))#5qo-Ck>UrrCkMXq=z=@jJJYgq-j-4uPkGT_p&3K z#{;b1R8=h`4RKGM@Cp_!8eQ&>n!iN6B9K`jIc05>UJRR4!(I`jJ#gLx@7ZZSwAOSQ zfNRggtKRi0ff^7Gs($-+5B_m5)gbJmPaw}QTM{dWygZ(k$L~oZA zYt@>;>D1OF2!W)}rN!o<70AWm;$wyIQ5?&sm=FR2`lONIW#u(k$!;nA7Hqz_Mn>Ii zcLE`Nd>f1b!q<2VFBw?)cED^~!4W66@~E3okpqQN4CUPH6ygC<%*B{$}@v{5a6U&{GOzsUp7XT%?(Dwm1wtOkR7;wpE@_VrD5 zUZFR0AP07P92xB%XoZrdrypr(@)ySD1mnmvQbFc%&YJ1Gw6NPFqkitDld zR;O`^Uj|BOc^l17CSe;>wSt9n%TTBNnS51lIH+wC6_{am-4Hf0CaB?AvdW~4g+}=# z&xOCo_~6>}>q3!$*P_bCoX9ut+rE|Efs^vPCvb}%_4>j zp?z*ri9g`uhqgFc97{tdQXg6yhV53ZB7XEA$P1nd2p$&ovS|a?N9%GiYdn~M`zu+O5+3apOSY-Zu)?C3#l>eQ+-Mf2zC^}lK|el8?tVFy+VSXeuo zI6f@GcQz3G^it~A63m+SPo%a>*~18i;?VV0bg%kGAZh)# zyuN16kcZQK2IXt}_>F3cKY{Q+zSIA;yyU;tN3lHBkNj00#lrrpJc{Md>L_6C*YD~R zAz=|wF)=z3I~PX_pmHP&vz&?B|I@YQkM;6TE69IU#QfJse(>&(_3wX`NwYqz-T$@v z9RT>>Kk@&(Tp9qR$oRcl|A`smsiNhnh~z0cY9@|Ah6;nfs!4v<%sf^({EZ*tKi8K4 zIJtf?T{r`aNtmC?RGw<@I9VT$5Cb@Y6>OXw?EkH526*a!S~bJY@drNy;PIjVw!WVm zz|Qg?+U4)%{cOyDhdcagr9>;2Xeq?fD7^=)@VNVe4Tr2gyJsgb(^Q=kIqC$iV^%i>nq%_wrxH5XBE>jE~-tG>1ua~(n)##tT&%80_HlW7#g+d|%q0e}UmyhS=_I9_R6*DWKv3e(ftixoUUM!7Pk> zaB3C#DsSV2N2>Ang+gbP864Ri zIA5fX?_G<6ob@E6Vpm-Au^usKdTEL#N$h)D81OiMb`r1`u4yt`mAfO&G%!DB1lJ3{{wlhUx&6~8OFh|bhLr(ze=MYBmKFo{ z+I@8oERy1cXa#}+vA0lC4t7E99QIpm9XRRB+WksiQ|aG7`ZD5H@_apAE>YGO-h-r< z#-Vy!p_3e!J?WRL?LG+E9EXS}iMy-x!Qi81hnZv%*e*=5Ol#DJigCHn!I$R?=i1uE zJUP}~l`p@im1(Xu+}igf$L-%8D)Tw2tqHPetutAz1i2FTtf@kF4wR|h1hCKN69{tZ zXqY*%eb9~EsB}6j%)p*MPCHGE~I3z7&$X$ ze3J;ou}SJ~cOJ5$ceU^^_PzJ(wjq6>t|o%~_J{S@w@VzpoEhuWNyRArwL;*EjLw3 zlwdB=)#urgJ>XREbH7g4A-R2WdXh~f5)aM58E ztyl$kDDKvpB*|#C9d!$4E@j zDO((I{ASjxfiPrP7sA)~lR26Rg>gnOFFj{ZIDV!GLa9#UXdiV2DRcAak2%INRW|PT zUlId;^iAiC%&=S#ZoR7ac63b(ksF*JD5|OUtXJIPCC!} zaYd}XPEyE;@~#uI+X+w9D2p1bhEVqNHfSbcq2$}w%vb*xW9JklX}6}^v~AnAZQHhO z+g7D*+g7D*+s;Z=`qcmT?%v(w?6Xf_#Kjj8CuGi-k-G@ElooRimW1oAY?)nYY=N*}S^l}3fYACv0dt6+0r43YA18v6 zRRdPO$S+bZA_N8`I$EXH(C;Jl2b&LN}7 zgOTJGrve(Sz-69K8cG&lh)x4*(9_+$+5>we9$G?m|7WQtf})azCmjGMRI!mu)^FuD z7CJ+3GM!&BSAJ7#gpl&41!?_Cq3#FS5fSOQZq?eqNeZ((Mv zd$qbtjnjDYVc8n8oclrDwyLQc=&dzezba}lj{%3)ad6J~{T)C#q_QgW&U514&8eIn zeJBUr0*&01n6Fhr@{dqX?BjVU9WLo;UI)>5CA_|uuP*R-L6ldCMrTR1L>fEHGaF4( z{H=hc*oB9yil76q26ph8w-Sfl&IVk%bJT*`7;ejQ-XfS+9{O*V0CbA8ysf*Lc!;Y)8vSi|-J3#Gy_S)dBO7QH@8%-s8G&?#ZcC zm$QPgUis}T3yl}Z)L^;*FbqIaNxL{lUB^x;R515$9sld&nL{>85B>8F9B zTRFexA_tY1t>~L7*E{6~T0OeSey56zGZ8pe=iTg4kxSnQ3a%CQTeveBIQ--O9fPx6 z+-xwqkw7X2LfHo7$^xG>_ia81tqPws{%-!ok^9csM-dnClu)@P{vbv&z5>7;;geP@ z$CPkB_o%nXeZBP(G5JOlSS+4DDZ97Z)B^smytpMMl7~+Ph3L6BXgcv&h-LlM6dVy?ZM3LCJ3d7==<|W&nzV?f(q7bMt9 zm_*-$6;)OAW9D1}@<>RTys#B9GG^piC@4j9fdM1Ew`J0QXiAq|cTgO=%vNmMY01CW zY)?deTwYs2BS>xFsPU3-@Z?z%%zK!M`HPM03zms4uOM$ldyzuquGj`!@>er%o4p|% zX^KS#|Ll_GduPPUupP*EzJ7)rqa*-O215cq8+3aAKp5(=-DIiNU^IGl4R2cjGBgJr zeb2xk@*%triL1Jsl!A{rGoR(tZuK)>Y)>^5df7K!I8P7)hsp_xmAR6 zK~fFC1HEERAv7PnLJL|Gy0W27QHEA+;=BIniV(8`xzqJpBlHel zlblijx`VuyDlqOfpx)1lj}u#!rJK5maS;Ad;Vr-Pu{KMkxsr*aRzB*VWq_9gSI+@0 z!~%S+Luu)qCSbT>^1?FERkD(7`83omz+w8?^M$7wZ@#LV0&+R%b|cOyLPa(1o3pn< zG*zZ+11IIOSk2s}Gjp#%CD7Ha?uVns)Az#Vm_ely&n=Q8taFL;eoSYkvp-@wI`UkGte0ZUDK!3#Tf|Rr|S=h!_zqo8N6{<0dt|ZIlho@>2cXFs5U`HAo zMtT@ylY^Lh^}(?H(Ta0!L3;WAQF*uvMpRnQPv z#P$K^PZ;VOC!Wxgno}8$dQ*XtY7)SQ@nWi+Za-QlX}dYayEaAA4>7`;z!6Or@;Xu- zkR{^dNVKArxlIa>W`mI{YwZ*0aW`*v*Az8?Gd7_#bS#CMoG=P#NAWz;M?d64u})L* zNI^%4^Yug!Cq-~r-5j%k$_1Nc zJSA^Ng4}*TdvX(H4RZ+$p`448r&_w#FT3P}*JkV06NwCN%!F|w5J#t-&cAR|RVrh` z(>yqE)B*U`N4G~rbVP>P3;G0~K-0r?=9yl;`cd=8In&CDF`{Zo#z^WzJeU4jhnVof^6mM7J*hrUb?INAId@r=h9KG{lcrdSY36 za?a($w=qn${U4iJ1XZ{M2g)M^Alv6fRfkv|+d0g-*7`&hr}|{XAFPG7#EUM|RUN^x zSWw1hJ6Z}c&1<*v)pDJSllahw-wzk0?+U*!z&fXWh2e*gp!f2g-WOM=J2$n{RB)B; zB?F>urbB#vy$dWNL5F3%B1UE&k0p~zt-N8|Qi zv$wSij?rE`n9yt0%SgEU#G7S{Ldpz^g*Qf~2d{p>UsaAY;WP#Wiw`u{E=sQ(fU#Yx zohB3VWj0$Z$OIK+KFbRMceq{UV&8PBmLq|Hr z1o=vD9BK~i!^Nr7T6bpV_d)C6!Vfs=W*5!pq*F>7!NqJLvC~<+*M;^ae}*G&?A1B? zNt+)ivBxOG&=To$0C0SV46-J!#+NNwcmWDr@h_iB(%*e3W zV?WY*=@>i|u{_N!w$UK^!Z(`GM#s(w{9?0)#8jZ#1%?Wkru-MrpA!j!mYu`Y%nhYN zhnJ>tJ+>h|cN-m}VU=Tg-(hwlimP(d&EuyY`=0~I*}1{G5M8J%s<1K_#5an9MsFoT zoh*8K3}5Bgh&dFPOxcX0AjrSfevark=?ojCAU_wX847_0VG#@tEJrEK;5m~((sdM; zMihQIhDP56|4NNUumrAUiX@OsYFCwF`)bSUTEj>7p`<&D3O8-P^FWw#lHYE;a<+gO zfB(STTw#}Iwa=vM5zg*jCB4SS*Wf~g$re4f3vwj0-v&|dIIhZ}$MceV0SX~wb-0I= z%|!w1741MEVvMPxdpkh50Jr1xo|cV$m=sf5AzYd+woRpzk|H8St9N*T<1Pp^r*5Z`H!36<27LxRCM>!kfw9IUy#uC z6AcF#xoa-BA4f^9;kbZ@&XBK~B^xV{nwaj1s%_^zKmhhZb$|z3qd64%z$Zrdg}s&g z*AtZ6M7*Bs!Cq2bOKSe;ABa;BV^h2eMaf~Np7b{sb0)D=F_+zNPonYF3 zox*wBsH{_SV11^s5G-3Md8Y(~rL-$IUiY6CeuY9>Vk@=Cy3Ev|wJYrG8_VI&;>BLu zz8%yEuya_$&Kh+!jb0TgS;@lYck$uCI#$;F#4E3y#~11}D4;qioO7@HK9A&+a$DhlsTh3?nHbeGe~e7@$9u)Mj|Ve+)#?LPCXMn|X*JI|oll&VVQai>Mv&GN$2((<#{ zcq_BrY?E;vYI~0A@%|amQrnpC!!%C@0Tq5$#&@=ws zJwY9{2xW;Y|MYx)H|)Zd^agrX_3kLkV-k|XhdzVD9(Evi9%KUhsk8$?brPq%UGP9F zy9utrcUolz;ExkZV3V9a#Shsdj?OSMqrb;GTGCXMWwAyuhwlXSa#m8}Yp~E_`~_S` z3L>?@(B(XvcYQ)WwUNNI0^SKYW+g7FhT+;`)^u{KHc{OvT#$ZZLFZ9~y;BeDWXPwV zv@ow{GA8eu{R^K%Q;H5ro_wvN*-N{bLscs8(1KLHXpE|V0Ri>^k`u@N>}29KZZN3W z+s56Cx-ln&(?px^OmD7H+?}phF1f3yM9GF|)^TBCJkXn0Nphpq_j8_MB4xH@z8 zx@3;H?)xm{z4z{ljefeW;&%h~M|MXk!z>SKz|-EC=r%d|)Dx1wtv2TwBJhQJ2PyXx zTCtbnsIRM|*36}&qqd7mg5z{WThrkbd$K?#?y*Rvqf_e6OPP|ELt{@)d5+Dm%>kY% zlY=NVS=~i?;5@o2bKhxrg|y@Q_B}d2c)WxKL|4lmOqWG{i7Qxps-J&;dyPeSV5~{< zp8(SDhhTxE&ngl<%U5HUoHxy2xe(WjxG?zT~5>fQ=p)?4i zxI#9BP>cMn24pGYKg^^CIO}wnstXuk*XH!ShK#tj`IT@jw#ZBh*Il z|DNIbAggEZ9Ij5vB@;DWQ&s92LE_8pEd%{ymSR!VO(CvAA1p_-noY5yeKtlTGgq#cEQ$fV1#MN&DovIiSNi=HqiHAHb@fkT5bs(IwwB^faoo^3q z)g_Q2ec{1K-zf17T&OJI=Lk^UX}^t>3I`A2SgNsmYI%%FE;_TYt`g4p!ndqdyWiez zAP2&L$PaZDCRr7(P#w(PeD0L=p*xtLvn+Wv=b**E$?;Y%CG{HHm$OwH(KW9TZXKch zT%eyViSS^}`t<$R_ib2A13eA$=h|B=>YVD4n0n@qHP*M@W-MWcj0lNwPcT(5JI9h! zm;E)a#uJpue@*`0J)us`4dS45&qjt|4ocb=04u~>AQ-iH!4}Rsr`^jeFv!bgvmaMYl0-8=4}#`_}7O*9A+N zH$3CcGtSaja2qe-5JNL}Es+ajG2ViB{_}!0J1kfH8w;>QW3h+DDIAqwGybWvesF{O zqTrc6tmQN^<4*)G4e@~O7a=0d%I zH>6I?_2w9UJ#c(NS0m^SDnq@gHGw1Px;dxk2VA zS}MeGBC;_}^1_#5M>Q_v9EhTd_1V0fdmJj)CiNm!%LGn3l-Y%tT;Is>@houk^9{4i(2a=Gx%>F2K*UIn;bIvDCxWwod7r_}R> z4QG~c%sb1fEx#h_!@pd;;4I5Lw8VqqC;VBW8`FPTjyoiB`3GUc!8IOsprrB(`xcT! ze3XGr&+#)0}e!qb|nK)2Bs>5g<84FhIQYvWF6~6bq}px;GLA=!8U{R zTVvStC*&699IVkpYSx%aw5I20q*vnkx z)10G2G_pwKg1qHDq84=C*qF~Mnn~Eb6DZI@H1IN&IO6Aei z=}EVfmma^_9>0lUoF5(}O3nzGT1JR^W$cLC6a9uXl%)V-9z)=N!I$sNVoS}g_;yJe zyZ^4L$%(yV_b$2syV0g`OZ8K|dkE}U_Hky+BRk0PvHq&{0sTMi|w(>?V?=vMtSJ z=9*bGPj~&4qFsUKc5+1PVBGW;qGcOoQbNC!n8vQ}o>|y$PN|i?2`!_owYs)r;_j?6 znJ|(OjK^krZVF?QZ=3JXs%huH<;g5>44)l!qV$dyY*A^aNL@zlPl`^E3V&Y9B!;4I z(+!ylj|2wzBf_$r8X&jAkzh_Yd8A}bXRMsClC`^0ywh1f+8JBv2GR@UOXO0iAHvKu z%x-(pCPc4cu{hp&v`Hk92i0*n5)V*76jT@3$*g+Oz&4*Den6(uAvVHjOt3t(qnXE=(!_+=fTdr&TysN0fG8m8mms@dg$Vqf8Dg@Uci_9z>D zUyX3qBV9zd{m?sBX&)3$T^`t^4FrLUPHbj|KsvH1V%;9aA`xYhf1^MCu!sF-ML~m+vtI|CQ0I>++J{kd{ZZQaZe#x({V2A zgJ7J&J*(k81M^bwPLy$BY^_r3o1eNID3RwXGVX2d zUP4~n_|~}^nMXds!CirJ?%dThzo&;Xlx?$L&pLQjuc|QQbhUJ=e4f@wlDW&s@!g3w z$#J5Qz=9*zQf!9>D)(B2BY28{MbrW#%J8M1Wyw*l+?16dAwM}Zf@#@V`Kwf~U4PV1 zAw{4qEks}Iq8FZ*yYD7Q(2%ff0S=C4RLtQmf-$0I>*q$r zQq!XQwh!L8KDVgkQ;Psm1yu{`e&OkwO;TNd*hHzLDQ^o$|0V$=+>1|3(GG9n+=G6} zgi974ceSdXaRoT(4510J!83f6FM`4n_5sTU1bKf(5fOdiz#2nsk3095Lj6PA7q@*M zB2zWN{@mhaJ_w0{?~^hj>6lvRTNciumbBTXJ6;bA8AWWlrtlU|h=#FJw-H~%Qa4*2 z@^JY^L}3(DGjK@^F&*jQ0tMyzN(QtjzIn|UjSUl{zP9L%+l9lATl$)*Z0Bl~CLn(34oY*Mm9Rm&oc{nf= z^Lr>8VyP{#;^C4YgiJ2&A;;k&EUpXV1NE{Zt~2bG46p}*8_;b<5`0{Y41{B^O+W{v z$^F6iIzUl*xE7Dpx2z{aC3dXJ#{)+#H7V>bP!=Ci;*l3m92ahtwK zkyxQ+3f27blhcXeHan{37%v<9M9A7xL;qq(UM-k@rCb=kUd%X-r*(^^s`{Rau+YXM zgnp+}KdDPYvg?WcxPEhEeqk5>nFRPnqjK|eiJ2%BSx%wA*lV(zdF%IhhD)W)Aj~O- zk!6jB7w1LrZ{NYpSx>uIlsb>Uw+{#udmh*7)76R6SR3u|t$0Tg~mmHL+tX z_2gS8dA>j#eR(VDoH@~UvB52eFj0R_GYYxrgzl0``&k;_wqtj=VS|yV{mV!^px}mx z~9xXG2f>uw@bU^%wvyN7{DsK(mixVI2bg>??mIfT5uGw$+#u0UEBb&C&;uF40 zTN%h(03|3zh{Id4Lm-aEOjtp`&=>v*u(n^MU=R5udqDHq7N+}x3=RmlXD zpWJ0?9@L2Zv*T!CEp-Z#U`|$UH_?imG!J&TG4)fXFZ{x$RBGsi@%LH*^h#Sm?>g!( zXq`+eC0-yJTZ;D@^;RLux4}ZWzeY}}>HA~5;|lDnPF(ZY;;~lj!--nYPX>6mg>1=d zV=W{R0U2yoCP}nSsF@`C?pbMO>zo{<$>nxedsM9pr_N)Yk8xf+RuhnS;4^*)?aIJX z=}A9{IL?d&OmTyZ&1KvQA3veE6VJT80c>b z>M!pR3)3I9%OB4V(;sS(S(k}HoBdDo>OUU3%zvamY=5zX?0-G|x9ErYkILwu>>$%$ z{mTCdfBh?Vu=w?c$9Wco+pxi;fp!U2N+)=v62%iS|X6jjv zNQHZv>Z!a(>xtE&w7{Vw+X3O~W3!!U><;I6_UCPv8Zrv-ovEWO)AFGtMskk`*Qmrg7U3) zYMv~r?RmP%tF$Ta(!8y}l7lM~k{7?fekiJoqkL@*fh%*U(BnK@YL8 zKm$4P#tMQ?%VWr4eRy z%l~tZiWqt6e2MqIBd#c1yfR~T)nc1PV0REMBWG}!O<{10VBtB z%P#Nlh4=LykG<|NQUHHvktP1y8kGt#$-^|YJA~M=^ECf9xCwQu-Y)5*qvmC3(9 z<^Q?c{M$_a5ySljt^TV;{}aVOCD(tw`oD=H^M9BQ{#_LRp7vK3nE$Q^{|os3V`Tf& zlKmI={iirv_m6|^uPaW*KU%pz6!;%)8#61zANu>x^sDA?WxQLk}#5W&q(K?p#F6$ zt>v=s$}){4Kt<2iX|J>X3jzy>`hu$0fWTbqk|+x>{D*YJ6C{<9%O`x#1lle+R15xn zmR~}(dZ35E)Ui?|iPedzAa;%7m4D1~q|s;f{HhNiX|y=q6s^+I1$q|1D!>g0KDO5l z`x3OFtfx0{%37p>&Id+dj_%F4-uGt)wPD8UWgjIezaT~!25VeMj_Db83$rh3uug~n z)~=yYK#KjR9ZHYEP<&C|UWpQy;IJF@rhi_`me=iY-O!4CzAW1562xlG={<?l5~L0RVd8U^vOX ze8Zk{dbh6dP<0Ftw3zz<)=8}Ry036M5i}oeGXfv}tOV|nlX;2zKJU(NHt$yPV|4$v zlFle1`o^fkN5~_$wxq&rMMJbbFP`waE%P@eSxdSeN1elB0!W)zORTlKnd3kWOpjR! zMU_EZgx{d+Hr!*&Lxs9_ot%Em#Mp&=?auAVK$7;T3m_rrJ{K$ z!7Z~f#-q=2S%Oo{+|J&qWLe9V@RbP3OA@Ed&KtR7O!eG)Oq8y}H^xGJ$aqQ6KVai=Yv8r@deE|YN#iOA@<<#!7#695oiyNuiEx8 zGR-xEPWmt@_77j|q^ld6ZNeAc+xn{|;W4}#bRGBaH;4xM6@m&lh(E4GyDN>_S!4>Ma8E z5DQr<-fZQ~^hyFXR2Okl&NSo1NUKb|h&b@Yt602uE#n*SI_wMc0n#xsm*Tn04RSjV zQs_9#y+{oo)5upR%q5<VL1RTr(W;{xfnswL5JedmA0;h znW!FyHnHrLH)Xg14g5;R9e&5^?u>gF>i2 zo0GZ z_Q8k_4V`MlSZKL*iidQve8s6F>!oiv08oCGut|s^H)96OpJN;Q3)C3Y(Q(jM9#2#R zDbJZu-qC5>%ps0$+}m=P_EokYUdxIe6R9Y=?iM4<%py^Rfk8s=bd5PeB%NrNkwRcd zua@_R(d(u(xTFpzfE~WY&o_vPsFc5?1^i3~q;X(G>>``M7B30GU0NJvVDv|3DV&`) z&?;1pfiNvqyfm69a!#%4R`qlmvNm=sGNz%suM4bGHhemMI~qU)OqbO3c9X~`3I4*R z(C}4X&VJ`1153K{SS0Hc-U2~I8%nVsSOco*dHP`vF$ZvXJYV{I_E#XpYtRfpZaMEY zb-gGWJab9dNK}Aa*gcN#U2`)kiPETTQ6Ln? zu{cRy;G{I>GjI*%un_L*2IkIg?oZ|@Ho!%o!I^q-WupKvqfiskUR6^ra$_=ymCxN( zR}1YD>p<0(dxF-sT$uMaejh$83`K5ReAe7!G&4-ea?knz;{0W`?FJj@_Go1{XGvP} z>>@Gh1XM|>O#w6QgoDMQXjmPn0s{;9gWxEQM;VDa{mP*>#`x!Vz%*heo{w#$)GWc( zSYjl&;xFog9u^UvpGTmd3h8I?8`f~hUP_4Urte(IG$K<@j5M%~!sf*pj;U*+rGPbnu8!OP$a2(OVM?=nQ4wclFEw zhm?68FPNU9H62ej84`1iD{4(w50Azk<1BY#ohiR`w#8 z!0V6ZS&cZq?}yc8ZR`8G+{UqvAm;Y(g;>?ijC7=^hdg3LkxYRV;-9ST5>$#~W@M(8 z>!EcrfhmO$Nis@(M+-;27%F{RCWwnKWZaiCkK>(U@oa&(C6m7ZcV>^Nx?5NmIs~Z% zud)rL?j+I%L$tnTrwQ<`juG+T$+n?Am?a`Qx+_zPqpN;8IuE*_Ge#%I*xLO02e(=_ zDVGXj=h$~e*9*kZ91QmXf;l=X?DA=o1;O>40^^wu2ST*lu$u`BMF`$~Im3}6KSsT3^7 z`Y9`POsm&~6f^GqV?fJ6x35OyfbJ+i(Hgkbn}&P7{91BKOlNayx!wyoVxPDzBH?um z8{4S#gG}{ap@W)Tdf;@X#LwvNc8Wx6kCLRQC+)5|<}(RVM7yZwP8eVRn_k6YI9k3l ztZp}uO+BP%h@#yEWb~S7?x&}^g|S^Hbk&=*Z!u&X6-;=*qNmnt$VfUZnre{_?Kk(- znr}MaPY$F^BP-U9wmd8Vy4TRgl2{e;VRE05zFXpsE44?2NNPhs8tpyQtk^QI+apS33*yONeYH}wmy z*Bl7tihHiFiI7yjeghFNK5?kbtXtxtaj^#*nC~i^Wuhs!O>zmMzE9?tqc07AC0n?K zX;Am(R9~Ktm`fBCc1}39hjh+=h~p-4qe)$|ZmUj+i-2rVHwi017|47s&da2!? z-*bxSIV5jJ@)_5>!L}F2+14qKH7wUD5{t%r} zhv;`U3Z9fKlkspFLH2;5f+7r&NU*ED)tZ8-ydIX%$JBiN>Djm;B*7cIT%A4t{^}}X zxoWEgMxhk63KgVkF0MkR|WSD2=zo%-WF*Bq9i%Cb)+;I z)K(hvF=|t1&?dXh_i0aM1?ps(N5T!WiKbbQp|_QnZv&PDX7%vMNwj02?*Q8BfMe0Pp+MjMOFgHZ=CMmhqYX zW^E)+$B$|#ffT-;q74AtmBc~35Rg(w`?IBZenG5m%^c6NN}*6R7M%dTrM1=lMb842 zLSzpZ>FMZd?{SdI8?RUZ|6$5RBVvIS8U8DRn$yNgTURo!a*wwJ5p{8;O_vtf{znw) ze2}qh_w|U6PyO4TLVH5A{ z^4Am!D@tpFOn1Th(;`ASC*Zmy$hyyEz|vD=)=N$sMFX+leZb{Y(Li6=q(<~-cXAEp zI#abjNH2+{&JQBA@fBMjBI&Mssc5vK`41&!Ds1Z1(_3h)9X~+@VQ~Oo!VT(Ju~!Bn zteH5db5QW}^n^iFnr5WVz5zkxTOD6bv)zul_`7$IE4pYNda$P`&|kBCLj48T?SrM` z+ndC=LWwAj#J@`fv&VbFXYf!Spp%^vID8(d)p!>}lpxBB=V5Mhs-(F*ZJc^u=-O~$ z`^M@*i3|*7H9`s}Zo@l5d-suPrE4UiiGy!EDx3HK085Lssw|*Hyx))%)Qm5L8dFZE z+VIJ;jG3H_^GF%O;MeIX8!G(@7b=>GdUY9az%__Si(gp2q+uzYEH0|SHd>i8oMyKR zL(gM*LVvHrS#gqOH}uYHj&~q4iRItIhY&bPQ<66Wo&-x`^Ep51Xi?^`6dvW~de~r> ze8&N?X|Hf0O=9qFT6KAA=^n4EYwgp+aG0`e)9qP~cd)min3-UX3zkF>Z)%^V~!L2v~WBw?|6YW%&f4DdKBL zksV>@%|M`ot-rZ2+EC-(=rV5DdDve5WOZGOZ`QyAhN~;enQ*w?ov1*}Wz*5`Gp2&x zFB`LPLVturecgbK!|rr>pw3Cf7H5Y*n!x(4$47eZdgaRHEXqX|9U)*~`qG)0szR=(Uxup(2X5HY#x+_c-07XM8=0*^8` z!gIu@oR)ziZY~}58l!0>BqB3aYQ~5x3Gav-2eteMPX;m##~g79CjFgRW>MCC;Bmk; zBH`5?>V^v2$j&LX^m*8MHS?jl8lZD-UG)N54up{B;~9FIR4}D=?{js^wqHj?;3tg5 zVRqJ>fnP_`!goYaDj=A(I)QO|vOvS5MrCcAYqlUMe)L|zV2Tk-!}?}9w`n?v4W`fg zk@Y3gNTdyNJn@qtxhi46` zgbY!%TG$W#@c~W<$Lxp9ixgu$Ov7OPG~g#(tQ5hLIsDLAVq3^=m@DBz&F>xdfu~ZN zJ^POE&t)?_eKE}Hk~6D#8~5Pum)s#xtEadDO~%G`gT5)?VGi-2R=NqN?6OI@mqBA` zvL9RZFjkp7RNrq5!;6~YH+w$?cG<5t%_K}xM@*p5O>Kg<>tmys`&y%zfKB1lv!-fK z6#Y9V&h=q`$1w!8@EcvLbgN03dAw&Rp1%`-9-cFon?@QSi;XkVJbZN(Ll>w?|r&^w-o-WAt?B!HVLH2(17c1wBAfnBF*#gGF z$BZP&KYnnob^G5UtP`Y^Kysorvdm@gxX4J&OBRAu-8(get?$iXfkBl7CZ3p$H~UU{}MZLuzOk8 z#!KO|FCZ*%Iy7dA1}i6Sd|Jbk(7q-+tdEKGOAua6as~=gEqlZPqej(!Z&baF(-2%28?fBNiC^D_9)ViVvo;+^O=mukDxG^l5>)uCT{t zX(+eRPmnEC551f+(KrnIK@|nZG8zJ{a5qFMz^{RrIEvwQudI3OTC-8#@{y^Yw&W`w zQ{M>Ps#sx|t0*o;{VWm`yjA?er#KXbSvE7Fgw-$!(SSw)bv}HfFviyF%^OYFn29j8 zx=|9nSU*)d)x&Bxg&ERp-;xE3X{xtMUg97AFO+fWv4pQNcPA?!TJ>>HH$Plyoo;x0 zbz7i;DE47XMETjzV8lain045Wl2NVLCb_yJcL1@BNUg_fXdlO*RIt;S1|L1?s|Mx@ zD56c+H3ein;if=kdqB12StAa_&->0ltD;x1wE~II($B&&8=AhM)XyO7Hvl^#0I%=s z2%{){?cjnX3n}(seDxj`1LX+!B2<3XU6+qfv*A-ryOa&DY|@Lo zaSjtSz44L8arYcEMK?Ez4)?IC$Ws*%H6}h_xXJSbjX#JFop{FWpvajvDk*~8zg8Ru zQ!UL!wQ~0j(cuF62jA^d^hIM)xB*XG=a?*2Y>lZMdQ5LF-vCa%*%-783cz)^z2%RGw zrj|w+)SM_F-DUQ$WZU;{qddKVXUNY=pD?} zG3I_+T~3b#bdUy+eeD1&DyvKmW@f=vbjoPhfca!jtGVD-xfSnA`q>X-a)15%m5H) zE)?O6;3aEz{Oku3=R>50vV^DWgAr8L)dY~{t7s@rwyhztc54Qi!;ZfD_*xxoexPiP3m8=(;Q zD%FBip&M=XUa7wx{+d`tjy1Yf1D+%`a^A|Bbk%g zL`CtZKc4S4QR}o={IDb3s9|@fcxGfkMB+z2nIA+0=q7O}?;6(y$!ng25mPSHdzLQl zH#)+BW;wb`sY)nBtSoGRK1QRA&m0C`m|!FL3_CXw-+-eeZpiLUA#JX03rYlMo8M?+ zMQe#x428}$0UKcjbVBNmd}GNE#VTb&N->3ANA(n$v z5Ml3tgOT59FrPMLA6$K3Y%ONdv$dhLTi{$+e^4**NTKP|DI*`VRuWFB>6Y88ZX7T3 z8B4>cXzV?b};LG{df&m8tpz+rZ+0LwSRrl=b0Km-&{-bPy6Q3}_V zNb6lPKJo0a zKAY&{6mToASLR{~UCyQJOmmHtV+TXugg&XH)HYvKLD8yv)(_D)=L0XxWrl{TK{7Lb ze!l=G%uSt-yXWNM5Tk%yIntI-m7c9bvTh0hvnq!fa)US?2j~HhPt%8U8C`*XxYXAo zR*5pU-6?YWjP+|X_!K^tAy4;V9|&)h;VDD7NWQFeNm{!si>=YFGL|ya-JQASIdHbA z@|c}NL8FvoF*6)fAVI?GK<-AY3u9gkyuT5J9eyQ8sB;~-P~oNR~0HK zvvgkH*icdwUFdj^(X9iSO?uf<-kU*u;AbGJQ=Rcpn2|U6edN_gd{=p-G;j&ERIAY| zL&7KZ)CQ*Zh&IW>u0`i=gc#gjAlE~mwN0BlxnKOn-KJkgOpX57o5IU)$-sLlw+bj* z96w@#w!&v*$Y4t+ryubF)~?->C`!~^fNYSAIWN-32>r}>-4LV z6oYyZ3bdy~JJ3s5h=a4!HIy%67o1oDFJv>gbCl>RBPMM7aEq4hQehL-*(D5E2 zWL-hw%xQ>DoJK7)ABBg6!j}3TM|Hs$+o9+3j(%Xsma&cOy#Wz=ktuBAgi_L(ngBVFHVT{qpj(%xu&{qr}x^S2~ ze5wC+SgeP)-?%anu(dPlcinv@I$(E`7m)>v<(O~S;mD&XZ3=LH@+(OSS#4_a8rH~b zc1n^11D95t(6?7|-w~qpWfVa+HdZqop5>PuDd5(rlEvyIG$yWhXM{cPb9F^J>8*%w zCZe2+^DrOrZ~)a7wJ4^Z?o&I;?>S@K8st@a)dd~d@-q`cPyq!SuX#E|7myGM5(`d_S3)`C`ixE5?YcYqRZLkTdD(mfbQv(6~l+3=04 zzmur<$ma+BMc;|c*WIR9*DkHd<>O)1j!Q7iR%ZEUA_ZH&T;|AgGyIMzk+!=P_u6wD zXxBlmu$22-g-P0MG^_@Qq?mevr=_J*?)$hk#*-At&T}%bxmfqAsDW;hJh*$cz0n7v zc7SLx^|OXx`ir90hkbLwrj~~%0FepZ60swi<`lz4GTu{QF7BK}6FM6rty-U;@-6h9 zJiFycVMf_$D6pg9B33J%ONDXs5~6`2-+tyd5)N+747Mu;o*<@3PU8)vD*EM*TEBiw z|KtlM?mB6qtc2-=9EvIJlWR0DwX=n1uG+SA)=2Bj%>1J876IGRoZ)VDAzHaL-@9sq zs|2NL)HD9%pw36*9M3(_biH0j+Q&`YywglJF=OH(Q?7r5EO@K6ex9q%iMTq{ue|Z* zmfd_EpDh3cn=iFIcEbxlaTi~G6^2n}dQ@`sBGZ&}{+%?>$TCg=(mTlX%ZSxjx*|u%lwr$(CZS$7xs<{t6?~9lh6W!7OP8{UP$R9g) zVy`vax6Zkc&HMuJ9tXbkvR!`u7A8R6x-9EztL&1&HmVwCMDO+#w1@hWn^#~tF!$IUhVRt?Z5CaunW%m*Rtb9C%(xGJaEe$@&^eZ=5fK!iNe&)&obUedC_o)7 z96QI*4q%6L3YJKZH#FLo(*d(zu>`W-Z_(=&R}zW+29?}41qWp|q&6bfs!|qYxgp7L+`IP=1HU8l7793id9aj;Will>{@hNS8CrKp#+=;&B)Z%d>njX_2`8t! zK59hanOdt9o@HmT(Je+4n)5Z?{F;Nj{`fw@O#1Ko&OhFdRT(<6f%D2tzwPzT&ClKAVy1Adooy^6(JY`;)5EMAUMtXaCVT)0uJZiPPs`pX_LRn4lZQoAE8Ik{(cE`SJF4iQ3+s-R7b<}Cp z4po&+fL#klt@B_4NCD9@oiO7))(&eVi-w$opMP6`ekl0ksg7uSB4Z~$9%=^MyxpMv@ar@QCa-z z(9FkD@DP@pWa)7(OG8aQUpY!A0<~g8ztA4vM%F$=0o$yk1W$Eu;&hP$+4ehNDWvV0Z#)*!y87Ho($2`EN z0=#t?j!Wv^3|eak9+qS1UY#jZk?@0IReco)B{WPqe{tMl=1E}{yndH5{S}5Km?!HR zNXVw1XkNfw1tET6xtAwgfE~Gdl|C?+xRea1e8I|XiW>B?Huq+z^^&?)FKcMW>;j0b z92g(zXyq{poO6roxG<5jGP;yykFh%T2(3{03sUK8S4nB>kZs}I@HghOer(~>eDJT} zp-{eNKoPOMk|lk5`vTNOv_(YyFsE*6ib&5r-2Dy4l-QznPrVSrIDzAGVv$GmG&?L3 z)G8wG>?$p+wA!WU5Lbp%eo!RI?^@xjg>kn!pZkclg5paw$7`(@9XxL?V#}GBM#AE6 zqHxBoq=s^inQsp6U5ZV20ObLslpk`7%8*95ZTxG~Mb~9N#o{!lYSk4wOVwVO#L04N-0$i=4Zf@gRU7?bKpqbYuqk;q#(; zHPPP+`y@7@pf@!a1vLm)9LBWt7yhaSsa-i0)T+HkVrjrHQp&?zQpBtwa zf=DM-_a5C+=Y3M`)L3+g=&q!**z{sQT#vE1&v{AAFf^7a+yL1_l_(jZ=-6T*_E!ar zmosQw%})9(&n37B^)ZekNEhHlzLGdFqy%}-ql0>Pd>Hap*O2ytQyZ&eXZ$DZ;rq(z z0xuLLkVn61<4KIg+;YmQtUw2SN~=yQCax^@{fM6l^lQiqRT!J)#8ZhKLePgeAWuaY zhYanT6pGmPYqkpG)VSM1NxR0{N)sW8i(++L;_f$gwoM?CnWLKbcy$<#)(07)U)7L$ zM6dWM*vfv1*!~TAGBsi=D|Lb_S-f4*_Depjq>#@^J>h&0weT!-N!tjO%rNnV`mzS` z)y8IJ-K5(%W4Hc=vz1azyiEackA?7qF|qWqO|xTIK@~HA^n$2 z4F==U1&MMo;kT8IdnA?N#F2|N{_bKGzk~Ol1CiFMDZGL-XN;;^8~T6`xkEaZPWL@~>(epcWtG`|E%f3&HaW}^~W5F4wK zy}j7Ti6Ct!u%U5V3t!mL?{jwDG#Yvv$7p%){YRm@pn<^nJGU<#s(EYgTm;@Cn(nQ=M=(i{N|9O9vpmUMZ^&O?8Fl^nbT1~X3ds@WRt z%>L;aJ}ws`5q99#>T5=yBTAqPl777j|N6qExPCL{Oj}e}!@? zBbPhf-+YQ(jKPlv$NDI_2hi75jdKUDBkoUauX_x;Ot_A}+a650qr#^{x{wG1C7o$z zanpa~^JTs|7ydIu4bl>sWK0I3;9==Ain>F!(h5%Lc`S;UI4+ENfg-j?Z2#zQVY0sO z&13o)f-+K1Q?#WrQDU3a?vU`D?EZ7D3yI)-uFw@AS!*TJMWXuNv3l3^#}=3C*i7w4 zBHG^kgLLfXsTqBcTt~SrTpQ~41+6hg2wXf~|C+`3tCNOfx3PzqEIM!BU#?hrXFD@B zrVvDGMf~8VB>8qZaf3`Ay0@vpBaD;i8;V4$j=lhl!&5p5Nbm_y?ks%?gmZ3d-NSY^V{T<%SfeE&5fz?1-%%v*+@SK-T2{&r&;}OxB*xTM z>MDA0k+x2#NP~Ozl@g0D?5?B9YYE4|I(O?UGA149K4^C+^iFw*abDgRydgSIH`1E}I zr}@&OFSSD88jg)Tc8qksEe|o;5Ok0gyb%0C-}7R=YiuunrEFp@NzGc?DV|M4CGQS5ZsS;MgMDTx~iLX-(*SdaF8((0?rb7lyG;CV4Aqvz+ix@ zdH@b>s`;QuP$5{&M}0dvt)S`0xbg-eyS5U2mmU?+qlpt({Nn>?ZW?$)Mt=UgjHQJ1 zPJBe#5Z1WD!qU^c!SNa^wqI?E`pL=Yqs`;GuArSafkR^FVstV*Abs@fZXVNB2gB`! z{Wb!z+rl>~sIRB2&l?Z_-NW7q0sOV#ao-5l#kD&CGZ=}5xnL93ZaW$Veq z{gM|b!n`B@py&2GNxPR&Q31(#{>>$u`0=F-euS2cV=V=-h1O=B7?7*C7Ga0Z4JYtD&(+Q6q2gVwcZY_oEJVSkeV#CB`0UGHy+xb_ZBn%7H0&oH zr4D6`zLWpoWev_n0Wa@#o2uDq(ykF+bXGnl;F|A*yBe*iWHG}(VQJP#o4-xt?M{he z0Gl}r^exvFC78D1oA%O}+jsHLdF_KZg$pbnAc;YEz68UZZ0bje%1L0I2q%w{0S=bs zbK}hl!VPAWMt_cx7g&vx08bQ#SzU@_7h03squGL_@xR9(IlLC{k|riBXG!gW1x`Yz zds)_RtatN)J(JYhY~Q}3&JZW0dm}X0i^N%dU+`r74akIvv0rIEadBT>@m|9mkwBVg z?1M<|j$4IrOeF@8+1v#1*zNb~Cm7!;g~j#i&^fux!9OEm^V~z|*^(@N6`aEa{$X(z zvcbh4L!UHyG)zi})7)Up0kS|gD0lk8JrI4R#uJx&_=JS|_0_=*Ache}b{ubRP68XW zQh>koD9Juaz8Za(KDkn5=LDR$Utr1zc28PM0arq4HMk|NRhGoAGe0MKQA26zh$2BW zY*TM?G3lhc2Fwy-(15&z(LqkeVR(M>NbntyoV8AL$i*1$LM zXIL`WhD6`A#7PSN;@jSlKP|7>v~0KP$X1Lc)(#5iUrFi|w-MO_09;1;>-Y81$5pnwwoKA_^M_wC{@sb`U4 zj8os8xKz&m#c<^T|8t_dV4DyiT!Ak>r@~?=yd|oTmt(aQ?9<(waB9yCxr;XT&B)ya zvXL-p(VDry1G)PQd}828>N-p$>FW|4D+aMP9DhNaP0D7;4w;?39&Or~PH+g5?8#`h zC;bB%XEyzxc<=ED)l{;1Qu3rq34_(8U^Zbxrjk=sCkt@=m%Lq_>`q4kvCrVXD3Y<0 z5aBOb-RlVL^0ZAKH!l1db^>*`Q=7u7>2=Up_bXXx0Y$6L;dQ|2_{hYuKLU9`)MX-c6i9vG9Zj49Vs+CN_6o)k8?YyiXvCnNS$mEh5i{>>5_T1c$BP zcQM#n8$K2gJ*^*oCPE;Un7)v>d{MgQNh=;7wa73#!scrD`Vs*TV6SMD#c#!=8i=-^ zF5Q7slQOy4&5oS&Zn?w8=3bWsVElM-4gOBTYz9GfsJ1{hWLp)4x1S2W$fNmJVxCvh z=&M(6>N{ks$PymwhJUA&B^Xn*{+c3D39=|9vtYB=RFO+m4m+uaS2W zI7s)d0$B|yqx|<&{tB{Xpr)^>G!w8_4Y@>oxcrxY1#_R-qi+FHvIidx&`W+E?^_I1 z->>TG75EHbwj{!=68Ul3&74xDm=4BRN$D6^<+BhtXkdeHxqgHNICOd`z+eqtmG>AB z!G+08On$_QSf>NFIrMgmF6}g*NNSQB&YbJ|ae}8pVDFJe#XmTQbx95LlEHALZqBiJ z3n=fu0LYxbqF9Iw;Ctxoc5CWu7qW!jDLetvj73k2!k}fBkFnQ z!S0#i35bHNa{mrtLQ4K-nNoVe>y``I{1Jc)>1?cHY#7$QUcFr!LG0Jvmfk@jF2+Nz zd*;bGb7}vhoD*j0xPDokHLl0y2wU;;_31&bI`GH6(%&8pp~=xDL^jY`|8}0NQZi6``Gd+O$-j}{>fvm+apC| z*d&$QjsZp+mAYErK9wDBe`L(A22-ZY#)X4ra#x|o5yH&(bE1>zte2|_KQ{5X&mA@s z4^hj;o6Sq(j`{5HNeK$NLV~(no*W;L{;=PB1AMvnOzvICx&r|yW!+BhI8~m~W=%zV z;g4dW0H*CUy+0UB$GY5H`^!2VwU2^~&wZ|*;8K#nry~EciA&imqut*}omY?wl7~syI&k7Va>lHh zsZ_+54O}=C%lth`41p_qV%{<`bY*7zrxyNOo^b$#i~#aTRF@Lh*r7Ep)QckcfkiIK z6;QOL-;Y!Tx1@Y>Ni@6AC3052*})dZsI5Bf!tbI)?A7z>7E{_*{*&(u4yH}JNG!q} z^@Ig7rFaeSK$l)5#YvNlw2;(J^QkybWx!Q}+&}}1K>gL0e;6VOk_(^}f-xX^HGAn+ zw#8{*@tz8~AHT7hoSsS%L%93-cbGi01-+c$jzuc!=N%Vg@CS(3-px)hz-^DMiIJaI z?=tb3EG)xLr? zqwi4fAc{D9=|S}g#?oo9JCj8sUd`UxrpjuF?C4lP6m2`%0OQdEIeJN_O`-~Zaym0o zU?m;=(feJ1@Zjgzu0x|QzUghHlF-;0{O7Bka#>cB-~psIyEJ&5(E+zsyMUh2z_8H% zewueCy>Wr=OMrxj1J*qbDwZ>9;n?OrWTvAu?Wio|gmvbiIvD>85O>wc$&R?WSW@*> z+#=1$J~Z2kJ`mj)00!A_W_Xnq{3F%ixzS~Khb%vfME@5UBjM!JZfTi`UxkWvswg<0 z{cE5+<*#{qsfpTm7FnaYA6}!(TT^e3o7O+??tg-(5hr8RmsDyRr4sl~CyKn^P1OOiZpWLAud9>n4v2jgBmh5t3HQZZN$Ys9$86;15Ir~`bY9LXC9&li zhJjQI!~%$uU-8${rZp9n0Sf5n5YSMYfk@A-y}8E9_9ER-rGA>M$KV@X^Qpvy$unRH zhlOowy9S}q1mPSqE z2L8gOTfhA_QJ-X;eKnqUhDGkI4ToWjG)sooPI_YYDI3`1fG)+ik9mG^)ZrxxrtCVkF}xoO>dJd8$J) zgB3{2(m>WkMvSf46_#m)M>n(;x_O?-jdbPb#si`sK<7a&dTLkQ0=A;`)+8ycTFqe7 z04_76*^15l5^o34Ra^Gw#N9C$>{2boU-2X{?;poJ^`@ z0G1a)(7Gev;u)ePe@P)FT)uXfaLb(Q9H*6ZaFE%35%nTNFCQFCC!%ZXJnodTL&hIp zv9Vb#1g}??LJcd-E)ISQqy%3tEX%O0Q^lxDS)X+Ol^&_GD~&AyBxn3#Uz6s~CZk+N1_!Y^%t@80Z8AAxq>}7ivs`I^Yj{d1X+%PLZ?+^mG z|7ZFl--XDWGuGliKSf7U`>HgU0H$YI3;38n@__ z4}s|MfCa^N*UR-FkAVBKMB!Uz@lT+<61Ae@^kRkirF@iVs|sglV%p>kobPbUm-6`$ zyL-%1(XOCApz`0sjm%rjjlh|7IwCWt;FHhLqODj?p8Hq@35E8c=0l0PAoJ1CVwVVZ zib`{ll>%Q8DC(bg<)~IaHSNB-K=6*5j=G=;`HfXFrD?~#y9BO87DG#@q zx%)Z%5rmlr58z0M&N_|;$12H6Wtm1j8`T%IUw9S$hW)*YAXQZWW;)|AReqQ~q=D*Y zV(+FbdxOLa#^xtVr1e6(wF`3ftGr@Olj!yVONmN=yj-`T&U=<*p&B)K2T>HuBr4YY zQM<2&W^@3UZ6L?N%2!{=Nw|joFBMiZaZEa-7pHNh*R;7)yoll0f>B_G}711#DdR<+uIht=T-A|F!c!W6&qK&Ym2*pp5;RbT9} zf)u(vHYiTZ=SJDZ zO1(sCmX35&7au}DM0qAATu%uKa7DTgx}NIKBeRQy5CRo?X0g9~zQXNStwSNDw7Yd+C-#Dd=@` zSrDzci!hy%HHCd&w;{zaI%$s8Z}iN=I+T`|w&^|pjy~W!244E-&3=Pd=E`LDl?SEUl5l{@96;Q(grO!3J@tLM*J8R4xBAUrEDUNGeif=cCUD`iwj{f>GHb>Tnr^}SpS2Ekzmc_S z%iE5G-!gGsCH$tGKFK&4F%1OVu7*`eru(Xa4JN`9(;_~`E6O&1Uo$@Aw?H1u+sPkIGYU5Ef zkd*4@TRko?nY~z-u&}st^_mJzW{@<7-;3*GjI?15F-y0=WO(@+w0b^>*94@PH!AVt zU;7Kzg!q1;C;OUMJv6hPh3fmDTJACmuJemC7gDcNK$;$>8SN_GDQ&lGzb30cz;AWd z0QY>e5!a0Iu$@Q`j68^~5f){Rd3PvUdQ40ykl*5&CH0xBkD=ZZ5GPFGR_z*=r=6^kJ^EM{ZrH7pSM!r-+~m*^dw6R?~^W{P=0*yr`(?HY1F@9xSE zgZ^~(1dVl@^S>NWM*adrDw@HirE=j3qwg>v7hWC(5}jBjdw?_N`=WKe@@$H%uBjkx zq8DUY0rlhqdrpf{+h-IYGN`fYX}M>)805AIj5`6KE=9y07LXr6GaO@-ohEc7# zH9qbPVrac#cP`3WgNY;}j6pjc1AS)u{(ewgL=L+r`CVQH?^(;>e_scuQQe&WMKaW< z;-d0ivVV@&%J5xCVs>~^Ypef_h_@q^`e3eq*}lg*C6k=%h`iIe#B%YXdXVzP#;` z3O(PUszhHMV4j3OH!6=Uzh&Cqy2o6`#Hm0}NW93`$KCm@= zu~O@PI7OJdiJb=V7_zmeEOHi~(XA(Us=n9LZ}0;f5jdi$((L(?Y!IF}bClvLxWtjk zXNfk`Aa5f2GN`J<1ht_MRgjEWcbco3uC!#D^@lh82Ab=~yM(uSh@lNXNq3X6M_<$e zD8Z6&d8=vdj`Uv}-6%QUO!b1VW=6bDA>dmiaZqRx0)DX~oTUt`Pv|PtChGt=P9&!T zq~v?RnX`n1`ykS6AL$4iVpC;LW|E2$u_VJh1CCQO^R@J#9$j~nz_3*)66$0Ws{8wO z62dfZpoNxCi)t=WgMqkxNF&KA=z zC{zGsaapX>IT2ws<}d(FmMlZkc_@8V%8KITy$g84u@}7DMJ6+q&`MWO2`$rpP)~Ez zaOpo57~X#VLbVyo#qVJ84R4xSINVZ|N=Wtv^Iq$uwYn=`@j=0Fh97chZm7S3tQ>{n zrK6poM#0jtu*2R$f?*DjsM@(zwI8OtyTU)qaHMX7qK*K)$zQb4u2Kzoi^n?S*-rk5 z(<1{4PqQG8FjiM$yThPL{_?$1b?<@d;${PM>x8X@i?Zpg+bvANm@xqRj6G1w4CD%K zoNfPzYu`D{BFY6#?57N>C4;1r+K0B?ZC;wihJ_bX*VWup^z2z%Y!BnkP}?Rk@SG}3 ztFd%0oRno1E9qufYao_kYVKP6uA&WaJh6S84_6YMC+gtX!?M}#)16DXT{3+OIUawm#8mY^h10KX6y-#s- z8dM{R_I-QEmoC99#eQ*AYkGS)cf;;P95`1I!(EGb_1a%Ft_@v40QE_cqmsVo>Oxhi z=r3jF)g)>;s3A(VIC;*cw+m@m8w@{#flSvHuhTe9H`3DotQy6T2VUHpx{(w+X?$eU zFF91&^Vtbf_wiR<-&}U{FYL(Tp>2m2BMYK_s$K#U3_chHtZ`w05kGigOldW<7qFsVh^J0zx9-Gvt0eWO)u6Jq~wbJMLK>>pu0T*<|SVeM1p{O(vT{ zliJ6jb?D3!=Q|nXl-og%g3*)C$w%R9%UYq?Acv?wwM8LbPP{$XG(EpFL5D-Gsw0V9 z98>{Qfe%b@8zw))>X2hX4#iK>Zv9lA&!`y=srk)?$JSfV%{0JX7;+l)ly8tf{&(EA z!vndeY#K0}$aycga#g8Q1 z@K&<~AH}8c@(Z)s@DatRv@Y^Skw1>~qm(Hovib{BprEsOtQlHL#%IC1o9m*A7I;P> z?F|J@wU9p}t>EMSTW;VTM$OVf*@6A47JABGIinF>s}H8@ov2&(Ose6Y2*OobZdt2j zm2;+_ecFHE0*e3L!+Y+d3GMCgLebhmkhH6X`AkIZW71GxkV!xynmm;y$-6z=iif_t z;eWbE&?^l=9duF*|hyl4iWPNim~7;ApLE~b)7?P@*po)A4P(z zpYhl3`Cx9Jb13TOTK=u;91lDcdnZXMm5>5|>QeyiU^7sWrP|1uz2&#|UTZ2qLFjc^ zg!J0Tu4=}$)t*5Gd0Fo&+xfQCkRqyQn32?pHyy4sH>0GLLk8==#qHzD`QBnG>K%K0 zC_VgV2OyQ+|Hme(yb&%fPw@v}6=$VKR-lWjFy~fIDiajny3#iuT6y=s!nXbm z{o~=G|L@k}^FUk$fSBXK|3MDi4@B2S{Ga5&e-gOryh6SK8( z`nSdPpWLhe4T~$&U)B}9h_R#LKV-)S~fo12pkrktU}j*U`-?GSV`8HF+o}IW){`-}v7{IJ{dcHU2^jeJ=mq~? zDJx1+Mx7O73>X^n!*?=C(F} zKNTZjq5tjV;B4q5ukY}Wptts;ifJz`pGrD10qa z4^FVF4)wlZ!9b#pvT)VK%vKd~Zq{qYeRyqQBBfFHq_gYYC2{o^0Q^Fb-c;G)D-Nq% zc*_lqd29zlSAHV*TUEY*h%yCJ8DI;8;LWv_lM@B1>W0#M7!OZyAW}N;EiS0AcP5d3 zy?Lmr@alequEp#-Q>&f1BP#k+B=zuCvEZt_o0TVL)>5S*SYVXZb1phsMFQb^XQR>M zB?H_6|D`SdMMw;ojm8(Io49$`&%JH~!?O-^vKq=!_S^TSHbB%B5^kJ$&dM&rs6U`w z;_;{1SFfal^n@ncnNs1WT{eghcVF{)JRYPHseA?-xxw?rNP}SxBig9(As#hO(x|4rYy9y zyEG>j8=~In!-(;6txv0aL|_b>B^rRn(;)UcV?#(MxNk*Q%N83Q5eAnleq=H_vSoZJ zzUrr(($w67FKbC#5^w?hdTB>$D7+guJ!k@J!J>}OXz?vvGU#wxR>eZ9w3TWy7jhQc z20v+qZDgpa{QW(O%$+%vi`ip)%YD2-UG+6GSh_1R<#>tou)%gl!xX6)ql!!qh8DzB zXI{nks;N(Oxqv9ux|N#U8#E-Mu6Eohr}$LCZS`tTXOLhftN`6FK|F7>iSsl3XE}b0 zr@ImPw|%to})yWhitK0l#%fWN|{e2l#K%P+X3?@dy4+H6&wR#p)t!F<)Pa>bok zgiw1=0}3s7L4}53P+5KiuhJ6qoPL@k%>$~f5D8v4B}j*^jqQ;xf`wY_jC5)rj^LY( ziHewzWiuqMZD>JTACtOCQ z^Fm$l2I>OISuEN!yU!gZW(uKTVnZ0!`7M3DFRWOdIy4r+XsWnJ_8Xq4ztK5W^4`O3vfeo!^!1@zOfzSM2UyG+Pk+-@mZ zeLBhA^^}5~&3qhRsme$V{1p`JdTM^~W@oo1ZIL&0Hmfb7QU`2Nm`{ZZbksARGI%>s za>z|^;ezV}QB#8Pb-73^pvLf(v*Pq0Sw@XIQvN8&H_(%pz3y7B3{26Js;tUb4DrDJ zp1=z-ulriOX7}!!JZ&kLV;ZtT%^Nn&)dKNfvhA^QxV+!f0qXW3H96!^f$6N0$HA~1 zR6(}aA<8x_Sq*t-e;aH#vn}$!=m#|x%JukBZ$rpjqsVB@!nAa8=tZ<)34B!h0*O|miRf#xF ze4THR*!txkJ^_J7!pw}C4XfKL0rgs(|8XeiAj=+#dvPUDi%Cl3&I&g;+!nKDu#he= zKB%Oy6LBsiRm8ekNER5u&xF*GNz0;jk<54*&b#LT&g)Crdah7S>c!ul3=QEfdVM~WYeL+93srqK-Gs$xCgb29x>kSm8RgzGua}l<}F%G{g z=@S|gZf)~Lcdmj-Fn$V<7rz`ll~b7znd{)f~1@3iAD4fo$vQ%?G1 zZv7{O`afAnaZp6)>(7@k|1i)*R6gG{TPWalHqvkG*V$$F$Jk3|@Ybh7T0^E-+J{!g z4aM*gjkn@2M6^VP(wLrmy`anxlBOb|gHNyYM`$EmwRWhkhKczGIm!NDW6 z9DhVrOb``v3*)oTi0iw|ZWGCzKrBKrNIWby)sAO-@kG5aW(3UZRK|_=1p@(o1K}mL z^EJ}2t&r?4)11pZt9Odi2=aqD;*Y~3jCH^jBd-Zr+Uet$3vQzFWAF^y*PR}u@n|IF zvwnCnaN)~AEs=|zuv;AQSIx1~CH@i**Lmkfy1+rSXbL`WWpLG*xtC|yoJ-72hz$u) zK*{~?Sqgnq2Y=V1mE-xMthfYhO&EIjun4#5?QJZjNjDkQt>2U-V|gUO3%U;Fv?q2P zTr=|}=={mivBrBRWiNsRG@m&Os`N|-w&FsdPaL^~7{{Maz)wP*w3!dhK>i3ChaHwb zU6o(gNox0k?ip4g+&_U*XKi4s*2Qwh#d9x$5m%R>%Th3H{%2hTqmK%pcu%!m0x=4E ziScZ0)WcqE`C%e7)dz!zH0<#Z1z5}B!W~xR@EKb%-x&Sf5PiSmak;WDA;R6OqG75_ za}xJ$6}@)lQARB>;K<9%LCbcHufIVM1Js5Vboq2K|Lz%7k=>j{d{OGz?~rlV0o=1A zE8v-FQ~z4V&JAbElGtaK*JDD|UcyBoFmIbMB8NA2V3oD?wjW$_zRWm)CnvF)Z^fJm z(OA-tUDNmi7Ik{&-ALOknqBbD$u1&*RoKJaqbK_u%u!TNc0GyU&?H44UfWB;eAPGr zVdz|*QR$_$c2i&&jK5~kftV1+^}L;~&!`%R?p#xeQcw0@sUQ%y)Y@}%`2N-CQHRjX zjOjb)4gmD+cbJ*5yBj5E$_&*&LxV}I`ML{6Humv!T#f#eO8{VDRfmWW zznBF3+@hTbMglz#Y90q4N)N^$)AMB>G>T2-k8L`?O0R{PskQQVnG388+6E`l#^pNy z6%eW+dJDMhHGk0MkC~=U)t`JMfCP#2;V#>iGXC4Z%f~SnJK)_XavrR@IAUa_-0WQ+ zZjN0q&AN$cgZ_z3h@8gR5EWfwE~QC~QIt{$AEGn+9Ld{lpXHv&^XXOD^5ZxXTKk z1$MB5k_~AuHU%V2_%=7)F&7Ihw|UIm8@!or^w8N@R9n>e$ug8xX5!RalB#VA>`KIb ze>?HEzUESLi4>bV;-#bkTXfFoHZq7HXo}tg zpmyMS0O7Vjh?p#eElsbSylH_ufsJf`63}U6{Z0A<_`D>3;ji81EUstdB9vxG&QKxI z$)KdCKb5%+i56RzbxN&0Fwy4ymR_nJYt$NJn@4O(6Sq#_=YpL!%XF*4BTGLXr#qX! zM(j`|13JDDF-LEd!n-+aYP$>1M0%(@KU4mAptds8((Q)e11}k9Z1+)P0+&v1VI?18 z5;w(tm>0@20Swf-K=zF%qI!HqS!j5|!so-m$(oVT7*9Fv$-|@zn6L~ui()X(&j(U} zMgaP$x%-mHa6TsV;@YN2+xHsNvl1fl)t71Ji8|3(7&#B14TUs7=xX4}R6N)M!4JBB z-4Ut6vq@;;o^4#G$s4!v4*a5J-_B6^rcuEdQE?NFuH*&M=`O(laRXyfdP2%yImtHd#;UowfQ4r0@HyNiIV0?Ox20qQ?ZTA0^8n(XnJB=zk2N+rX9jwAgJ$ zfU+Fy{GXMq4?H4BDycmfZI-FLht6rRhaP6GjjqjKEWvHfqsGJXFP|MpEO<*u&Gtp) zEfC{O@lPZnQ*VUQGwv*wOQ-Zy^xYqQ&`$QIC-W_a?@K2(I_XALzzG?wG5`gHyH_l7 zUqX4vmy5Tsgtu^%d%XdHA~T*oxNo6U7MEG>)n!R?|7*}={Qn7h49txGmqBla+)3z> z1NqcX#0qW!xd)Qm`;beE8x#;oknpJ#?MJCZf#621Y!r!ecD)K!7Y`!d2{^zP25J2$ z)wPfp)~RB|#vOrK86L7%y4jk-&hl-e@r15A8f5=i?a&hpwQkph=KEs~L^LI|gzG(w z8%Z6rAxM~j@XG@=$4RLZVR|R1KP+0GN!9MviKrc;{3m*>1n0L?D=h>a74c;+S2*8O zq7hRI#mFm8VY437&J-UgWXV^pc!UYQ_6#}rd?{~&#j{KvJ(ds1IrDC%E=w3`;+q*2 zK!~Nm%t*Xr4zG04nq+2N6ucty(rA#i{Bb);GVH3>uS3T3NFPlol8$4&c{ng`#k!_j#s#)`6bQCJ$ zWVbC#PJNL@toCRYho(ir<6Km60WOA=2AWp`XK^`)?&ocV(<+*R`>rl}tB_YC z&5ub^GWvUbhcuqGtJTMKi{B-;+zu1px+hybyzor*H8XIv+;mWR-7=?yYl4h+EHrk> z7C3-~LZcM{lPHV$aF9!*Gf!0*h*O6*^^!0qQROvqVouP*HTOo<&4nLR>;CGRT={l{SENMoYH?#V1Yo?tKcYjg%p;_c%plZwfmOXJ z5nnRuq5Zi(ZdzV1OTaw<*PkGs@(91+YBZ!u5q!YT#AG;u!jIt2d9*Q5BPF8Yo51$6 zRz~E-yPZ^@G^(a18uHu)4Xy~W8Wq=RU`q4?;{X*l6h|u3YB<6|)uvg_wBGxO*fMggGYDmUHv?l+b_OALbs;%pT2m;b2h*ywCYUWH!Nl2qKl1fQP3s{6msDPk|gwjZg zgou=gN{h6V(%njfh`wjw`aG92_x(Koz|1cL-`V@Dy;pqqKI`n6^{AEI(1{FIVk`30 zYeM!~$+x85bGN)t>aX=}XZ$Pk;Omn7bGrpcq5o{R0K~slBmr-{z#FpNobq0__y51| za^@{U^OmgTmxNzpKQ*q|dMbEpbzV+J9CM(RrPA!+2!}`mmn>Uf)KyD;t96_A%gwX( z=h)R4vkWuNYLa%E23+lZQ>`NWEF|G~B#C6l``VpXqmMnUN{i7^Q>6owxY(h}D^IguhRd2s6cDIqwoMjg?>b=Q1eEY;0t?PI;39lumbcA;2 z<<7BkVFwMPCt zk~pua@yAgRXz;1cu19Fvcvx6lcv$@R-rMApJ$os;*rpAoEFY7v(`v@}wasn;RRvN< zs;A9I<}BHr;Y@u)P2)ZETJ0p;yps(=2C@Nfg;WwEUkq}PTv($!S)7B-e$8<$OR}xU zTc%i`W|mJRuI2cm-nuhx%Y3t$tkbXG_IrL{$5F{I(Uzu*Uanej&+*M)DRYY7%vhUK z#&GC`z~thfaQfyL(+>gF>aAiKq0^pchZ@qFd0xs5M3Ze(m47WOTH=q*hY51fRL~=y zB-Um(@yq^NPBWpLm(6>icI3^fE^K(z-*R5}r|d7P`YW%5A1)f4XbTuIU6{)xx2H(v zn(wu?6EkN1)vX#{7VD#{feHX^^bcBS~T zxC}c@Q?B$F8ND#FQ~$BkoS>R!VNKysR?1;+yAN_{ruE0eHj33~0uAMQk4l;@RP0B9KIK3}M@kCKc^r;w9MLEA3A*tpmlZVGLX547Am|5VY-jc$h->6PJ zGhjO4!rd*{$iS$sbt$H~tpu~&;O=gxf=yHvO$cDDr7*2Y3G_>Jx zZQAej;`QDFLtwi3o;_#Cced%smFw5VoiGqm* zTO!{hilgmcbEX_%p#DARlk>Q}qV4L!#g(lQYScmg70dSe(6zr-xh&#Wh7ah_y>IT3 z{Mir}d~!v{btjL1TD3J()qp=&Cfrx5CvMfNqLNO-Jw9P>{)5u}!ul8iyC;0LxZK8k zCB}dwT4PFv>W>8vXK<5Y>R7ej>Ys6`?P;4wuJ?PqG*c&`w6MmMRG(8hL{FanO4~Bo zDK4Y&7$5ud8yhZGg}#~8zK6xcf?hR_nx;?o)N%DcVXNW#I@)w3p#S(pfUFPe*-N5@ z1KyMhtFf;i(jVN|ROr}gHdF1S)rt;}#I!lKkDPZF6uXS+hR>PBAA0coZjU5$w!bT_ z=#v)Xw_a4!dC7@YzQ**pN1A3oFf%qs{l={u{rU6RXo8QJhFm)pXcS4pING$}AKH|= zT3XJVL>p6vx=>n$&|RXQ>Fa{MY%HTcR}?Ext;er)Ek}ZE`M@G|@I_fqezlzPo<5}< zCWTR^L~nH8kdc{S4}UW~LZ>X#2s5?y+e}W;stuVvdNa9}j?|*+T~H{l<+V7@`@Irf zOI}q$-RBQZgJtX&AJ@m6MeDS_H?bFq85((@t0Kig5%(&eUO%PbS6*_nv{P29PR@m_ zq4JXy$A$}l<1)=bLN8!<9DXG@Z!Ju~rxs%Jx>6|^>u!G6G%onTVKGT$i#++;c~475V#c>$ zCB&1xKL47L75R)!a%rQ2qW%&hVwRFWp?3Hib9p5AQ=p#9EMGnq-+4ts@ii=2(3u|w zv&dGapVa@JL#^NZa3iYCFE^GV%{YZ4iK>`H&M!tJn$45>B`ulK*(e=aCZVCWBs*#r zxo@<$a1U=<_7~fKIjT18gmesUuUaIMTaH^Lr}?h)W-?qGwSCi?BBxMuszg3S^tMl^ z-L~W9))m>6t+#4xA2a9E6!q=2$=+5R_THdLg{3+?_;Nz6Jg8ue%Rb_zNUKaoxuu4P z^KUXsb*$7tbt}fvpf;aD$tlKK{RT_mp!fxhpQZGZIE5hhQlIu?*N3#VjngQ4#4@9M0HZd)ci#?Q-rTh#`9}&Q+G!tYieuw zwiI3kYd$l+B=nGNOKnH2{D*lVoQae!SP%83%atmh1<{MU2*es>Mdy+5g0VN$K* z{;s^>gQ{(c`$7Iaxve|zFk`)u`{eIo#Z+!kVk{c z)Jggs*^#g#7<5oLQl7I*B09pO_H9IX)a)Yeh>2H&kL;5t^Am-0I>s_QBag0k{bD^~ zzMMDf;cczgKXm%;r&;}`6N*>p2fh1gc-ji<4?ZEYSyEB0vLY|9uwK3f{un#s63ber zb~Z_nr(sm4>=eKXN0CTaISKmq8|0i@DYm6g;-;6Lw%L-3Q%KYswE7#6e~vn>o1pE*&8iX2=tanz$d>-B{%n!THy7+6gLP`;nhqPGHY+WOqoHCcrUlF6K| zPuF6P4h4>Lzki^#Q?St#;3-_sy3l3N9UI`$V{+@kC6C9VEOKAJ(M!f;A!rRa(=W}c zJNrADDtO(~&O%^M5Qs_jaYVnXWQ7@Pg(5_3%y*MPky|gKtzilTXD_%HNN+6QFQdteI%5 zzy00h(m8QUEnYQ8MDma8W|K1_aRZN!oX_{{Y2v0@pRuH_l>R1pqlIri^y6LC{@}cJ1=(RRUU;$95w zj--g;UpL#h%8x$!5n{k~0XuObX9mEA>l_-t#t=K6hdEttjk0-(`t_qo-uhdI{;{87 zk4A-96veqth}tQ%oQXHLqd23iHrbloefwyn+as7+y=vykWwKR0D;JN9X$}6*kKfV1 z6RxEAG+ezY_6;Z3LQ|V_h2+IjV9WAn$}QLG8Dna5BcEH*B{y}fxtJe*HOx5wKD)Fc zBEkl<(#2E6_F6_XT~}i)$cu#Xlbe;Ry=w>4v(3O^K8h(fwqf1Y+_6Vo5|>}NbluNV zYL_+=)%Yf0A!n!Yxb_!=8z-B{^{}6zdLM<#f=L2p+6NxII&dO5>C4s2HOl&rCq?9R zj7@eF7<#QN*$xILSBcKL%ja~8=9w{?DNj!Im`Mtfx~FP#Pfz)|P8Tf4xz3SJUAq(B z^j(e4k}vI3r-1C(#7giz&9E0_`O#t>bPV1iA1NRCF##7C_*5*&h72`*){pI$8RkkH{)2%*&9NM7`O58!^#2! zH^(PEt!{t#7$~$PK;?Vz$dN$R@do+C_Zf;cxh7=?QV=Llihh#<+&r0|$W(AZ6}rqO zlQk@gLUeqyBU!t9GLie>B<|^I!WX4u90EeLf#rc=r=+JK>E+n9^doiykllw4z1%owydrqZ*h+ULI`eTCO3f%HVZJ*ckBxQge zdGf3?#hl#-hcWDwLbOHzuj?Uf>v&^JKMZ%Fg?EsW?4AkpMpRP^?Z4hy|M%dbg1e0c z{#=_P_*_`%ywn0J_dQ)quS$b#Y#)1}sgSUQoTrDKi@T7%-Sdk}!V(t@ljp9l5b1Q4+BY=e|w3%?=1lXt}#sds^B2k5-y4*87F3f0TUMd$i<2;OVvy z&S_x@J$nyF8zE!cT(`=XjuQ>iF}8hCrlunl14rVXXeMV`L?x-3It%7zhA{`Z7DTWN z*h=uMJ~!YnG|0I~rK7$<<0sKpoZ8oK>fGuS`&E^@a;b@ zZZrx7RwBiJgnwb+XgHW)z`wYi|AXQ16?XSy00IXl3?LW=2Hx}U$51dVL0=Ro650-f z#epXJXJ0rRhr#C`AQ%n{kqgJ4$0WoMFfjG8uP*@L@Y#+17y`gT5PJY{(A6L|2k?`F zUJn4kWESLlAcTgF84MZl%Auyin31%Chd5TK6}$i<;BP+cM6NEpSUY&v@={2dV(7 z7c>^sDzqII1LYFX;NSou?J!`ud8of&FmQtSz`>Bvm(;u|1_gF)I&2Y(O-x6bk10o*~`QT495ckSNJ|OY|kq?M`@J9ngJ|OY|kq`bv195*q z. + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1951.txt b/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1951.txt new file mode 100644 index 000000000..403c8c722 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1952.txt b/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1952.txt new file mode 100644 index 000000000..14c0c72eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See https://www.iso.org/ for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/doc/txtvsbin.txt b/internal-complibs/zlib-ng-2.1.1-beta2/doc/txtvsbin.txt new file mode 100644 index 000000000..3d0f0634f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The white list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The black list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the white list and +no byte that belongs to the black list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more black-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of black-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.1-beta2/fallback_builtins.h new file mode 100644 index 000000000..447f9ac19 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/fallback_builtins.h @@ -0,0 +1,133 @@ +#ifndef FALLBACK_BUILTINS_H +#define FALLBACK_BUILTINS_H + +#if defined(_MSC_VER) && !defined(__clang__) +#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM64) + +#include +#ifdef X86_FEATURES +# include "arch/x86/x86_features.h" +#endif + +/* This is not a general purpose replacement for __builtin_ctz. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + * Tzcnt and bsf give identical results except when input value is 0, therefore this can not be allowed. + * If tzcnt instruction is not supported, the cpu will itself execute bsf instead. + * Performance tzcnt/bsf is identical on Intel cpu, tzcnt is faster than bsf on AMD cpu. + */ +static __forceinline int __builtin_ctz(unsigned int value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u32(value); +# else + unsigned long trailing_zero; + _BitScanForward(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZ + +#ifdef _M_AMD64 +/* This is not a general purpose replacement for __builtin_ctzll. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + */ +static __forceinline int __builtin_ctzll(unsigned long long value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u64(value); +# else + unsigned long trailing_zero; + _BitScanForward64(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZLL +#endif // Microsoft AMD64 + +#endif // Microsoft AMD64/IA64/x86/ARM/ARM64 test +#endif // _MSC_VER & !clang + +/* Unfortunately GCC didn't support these things until version 10. + * Similarly, AppleClang didn't support them in Xcode 9.2 but did in 9.3. + */ +#ifdef __AVX2__ +#include + +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 10) \ + || (defined(__apple_build_version__) && __apple_build_version__ < 9020039) +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm256_castsi128_si256(r); +} + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm512_castsi128_si512(r); +} +#endif // __AVX512F__ +#endif // gcc/AppleClang version test + +#endif // __AVX2__ + +/* GCC <9 is missing some AVX512 intrinsics. + */ +#ifdef __AVX512F__ +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 9) +#include + +#define PACK(c0, c1, c2, c3) (((int)(unsigned char)(c0) << 24) | ((int)(unsigned char)(c1) << 16) | \ + ((int)(unsigned char)(c2) << 8) | ((int)(unsigned char)(c3))) + +static inline __m512i _mm512_set_epi8(char __q63, char __q62, char __q61, char __q60, + char __q59, char __q58, char __q57, char __q56, + char __q55, char __q54, char __q53, char __q52, + char __q51, char __q50, char __q49, char __q48, + char __q47, char __q46, char __q45, char __q44, + char __q43, char __q42, char __q41, char __q40, + char __q39, char __q38, char __q37, char __q36, + char __q35, char __q34, char __q33, char __q32, + char __q31, char __q30, char __q29, char __q28, + char __q27, char __q26, char __q25, char __q24, + char __q23, char __q22, char __q21, char __q20, + char __q19, char __q18, char __q17, char __q16, + char __q15, char __q14, char __q13, char __q12, + char __q11, char __q10, char __q09, char __q08, + char __q07, char __q06, char __q05, char __q04, + char __q03, char __q02, char __q01, char __q00) { + return _mm512_set_epi32(PACK(__q63, __q62, __q61, __q60), PACK(__q59, __q58, __q57, __q56), + PACK(__q55, __q54, __q53, __q52), PACK(__q51, __q50, __q49, __q48), + PACK(__q47, __q46, __q45, __q44), PACK(__q43, __q42, __q41, __q40), + PACK(__q39, __q38, __q37, __q36), PACK(__q35, __q34, __q33, __q32), + PACK(__q31, __q30, __q29, __q28), PACK(__q27, __q26, __q25, __q24), + PACK(__q23, __q22, __q21, __q20), PACK(__q19, __q18, __q17, __q16), + PACK(__q15, __q14, __q13, __q12), PACK(__q11, __q10, __q09, __q08), + PACK(__q07, __q06, __q05, __q04), PACK(__q03, __q02, __q01, __q00)); +} + +#undef PACK + +#endif // gcc version test +#endif // __AVX512F__ + +/* Missing zero-extension AVX and AVX512 intrinsics. + * Fixed in Microsoft Visual Studio 2017 version 15.7 + * https://developercommunity.visualstudio.com/t/missing-zero-extension-avx-and-avx512-intrinsics/175737 + */ +#if defined(_MSC_VER) && _MSC_VER < 1914 +#ifdef __AVX2__ +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + return _mm256_inserti128_si256(_mm256_setzero_si256(), a, 0); +} +#endif // __AVX2__ + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + return _mm512_inserti32x4(_mm512_setzero_si512(), a, 0); +} +#endif // __AVX512F__ +#endif // defined(_MSC_VER) && _MSC_VER < 1914 + +#endif // include guard FALLBACK_BUILTINS_H diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/functable.c b/internal-complibs/zlib-ng-2.1.1-beta2/functable.c new file mode 100644 index 000000000..d20098292 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/functable.c @@ -0,0 +1,336 @@ +/* functable.c -- Choose relevant optimized functions at runtime + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "crc32_braid_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "cpu_features.h" + +static void init_functable(void) { + struct functable_s ft; + struct cpu_features cf; + + cpu_check_features(&cf); + + // Generic code + ft.adler32 = &adler32_c; + ft.adler32_fold_copy = &adler32_fold_copy_c; + ft.chunkmemset_safe = &chunkmemset_safe_c; + ft.chunksize = &chunksize_c; + ft.crc32 = &PREFIX(crc32_braid); + ft.crc32_fold = &crc32_fold_c; + ft.crc32_fold_copy = &crc32_fold_copy_c; + ft.crc32_fold_final = &crc32_fold_final_c; + ft.crc32_fold_reset = &crc32_fold_reset_c; + ft.inflate_fast = &inflate_fast_c; + ft.insert_string = &insert_string_c; + ft.quick_insert_string = &quick_insert_string_c; + ft.slide_hash = &slide_hash_c; + ft.update_hash = &update_hash_c; + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +# if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) + ft.longest_match = &longest_match_unaligned_64; + ft.longest_match_slow = &longest_match_slow_unaligned_64; + ft.compare256 = &compare256_unaligned_64; +# elif defined(HAVE_BUILTIN_CTZ) + ft.longest_match = &longest_match_unaligned_32; + ft.longest_match_slow = &longest_match_slow_unaligned_32; + ft.compare256 = &compare256_unaligned_32; +# else + ft.longest_match = &longest_match_unaligned_16; + ft.longest_match_slow = &longest_match_slow_unaligned_16; + ft.compare256 = &compare256_unaligned_16; +# endif +#else + ft.longest_match = &longest_match_c; + ft.longest_match_slow = &longest_match_slow_c; + ft.compare256 = &compare256_c; +#endif + + + // Select arch-optimized functions + + // X86 - SSE2 +#ifdef X86_SSE2 +# if !defined(__x86_64__) && !defined(_M_X64) && !defined(X86_NOCHECK_SSE2) + if (cf.x86.has_sse2) +# endif + { + ft.chunkmemset_safe = &chunkmemset_safe_sse2; + ft.chunksize = &chunksize_sse2; + ft.inflate_fast = &inflate_fast_sse2; + ft.slide_hash = &slide_hash_sse2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_sse2; + ft.longest_match = &longest_match_sse2; + ft.longest_match_slow = &longest_match_slow_sse2; +# endif + } +#endif + // X86 - SSSE3 +#ifdef X86_SSSE3 + if (cf.x86.has_ssse3) { + ft.adler32 = &adler32_ssse3; +# ifdef X86_SSE2 + ft.chunkmemset_safe = &chunkmemset_safe_ssse3; + ft.inflate_fast = &inflate_fast_ssse3; +# endif + } +#endif + // X86 - SSE4.2 +#ifdef X86_SSE42 + if (cf.x86.has_sse42) { + ft.adler32_fold_copy = &adler32_fold_copy_sse42; + ft.insert_string = &insert_string_sse42; + ft.quick_insert_string = &quick_insert_string_sse42; + ft.update_hash = &update_hash_sse42; + } +#endif + // X86 - PCLMUL +#ifdef X86_PCLMULQDQ_CRC + if (cf.x86.has_pclmulqdq) { + ft.crc32 = &crc32_pclmulqdq; + ft.crc32_fold = &crc32_fold_pclmulqdq; + ft.crc32_fold_copy = &crc32_fold_pclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_pclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_pclmulqdq_reset; + } +#endif + // X86 - AVX +#ifdef X86_AVX2 + if (cf.x86.has_avx2) { + ft.adler32 = &adler32_avx2; + ft.adler32_fold_copy = &adler32_fold_copy_avx2; + ft.chunkmemset_safe = &chunkmemset_safe_avx2; + ft.chunksize = &chunksize_avx2; + ft.inflate_fast = &inflate_fast_avx2; + ft.slide_hash = &slide_hash_avx2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_avx2; + ft.longest_match = &longest_match_avx2; + ft.longest_match_slow = &longest_match_slow_avx2; +# endif + } +#endif +#ifdef X86_AVX512 + if (cf.x86.has_avx512) { + ft.adler32 = &adler32_avx512; + ft.adler32_fold_copy = &adler32_fold_copy_avx512; + } +#endif +#ifdef X86_AVX512VNNI + if (cf.x86.has_avx512vnni) { + ft.adler32 = &adler32_avx512_vnni; + ft.adler32_fold_copy = &adler32_fold_copy_avx512_vnni; + } +#endif + // X86 - VPCLMULQDQ +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + if (cf.x86.has_pclmulqdq && cf.x86.has_avx512 && cf.x86.has_vpclmulqdq) { + ft.crc32 = &crc32_vpclmulqdq; + ft.crc32_fold = &crc32_fold_vpclmulqdq; + ft.crc32_fold_copy = &crc32_fold_vpclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_vpclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_vpclmulqdq_reset; + } +#endif + + + // ARM - NEON +#ifdef ARM_NEON +# ifndef ARM_NOCHECK_NEON + if (cf.arm.has_neon) +# endif + { + ft.adler32 = &adler32_neon; + ft.chunkmemset_safe = &chunkmemset_safe_neon; + ft.chunksize = &chunksize_neon; + ft.inflate_fast = &inflate_fast_neon; + ft.slide_hash = &slide_hash_neon; +# ifdef HAVE_BUILTIN_CTZLL + ft.compare256 = &compare256_neon; + ft.longest_match = &longest_match_neon; + ft.longest_match_slow = &longest_match_slow_neon; +# endif + } +#endif + // ARM - ACLE +#ifdef ARM_ACLE + if (cf.arm.has_crc32) { + ft.crc32 = &crc32_acle; + ft.insert_string = &insert_string_acle; + ft.quick_insert_string = &quick_insert_string_acle; + ft.update_hash = &update_hash_acle; + } +#endif + + + // Power - VMX +#ifdef PPC_VMX + if (cf.power.has_altivec) { + ft.adler32 = &adler32_vmx; + ft.slide_hash = &slide_hash_vmx; + } +#endif + // Power8 - VSX +#ifdef POWER8_VSX + if (cf.power.has_arch_2_07) { + ft.adler32 = &adler32_power8; + ft.chunkmemset_safe = &chunkmemset_safe_power8; + ft.chunksize = &chunksize_power8; + ft.inflate_fast = &inflate_fast_power8; + ft.slide_hash = &slide_hash_power8; + } +#endif +#ifdef POWER8_VSX_CRC32 + if (cf.power.has_arch_2_07) + ft.crc32 = &crc32_power8; +#endif + // Power9 +#ifdef POWER9 + if (cf.power.has_arch_3_00) { + ft.compare256 = &compare256_power9; + ft.longest_match = &longest_match_power9; + ft.longest_match_slow = &longest_match_slow_power9; + } +#endif + + + // S390 +#ifdef S390_CRC32_VX + if (cf.s390.has_vx) + ft.crc32 = crc32_s390_vx; +#endif + + // Assign function pointers individually for atomic operation + functable.adler32 = ft.adler32; + functable.adler32_fold_copy = ft.adler32_fold_copy; + functable.chunkmemset_safe = ft.chunkmemset_safe; + functable.chunksize = ft.chunksize; + functable.compare256 = ft.compare256; + functable.crc32 = ft.crc32; + functable.crc32_fold = ft.crc32_fold; + functable.crc32_fold_copy = ft.crc32_fold_copy; + functable.crc32_fold_final = ft.crc32_fold_final; + functable.crc32_fold_reset = ft.crc32_fold_reset; + functable.inflate_fast = ft.inflate_fast; + functable.insert_string = ft.insert_string; + functable.longest_match = ft.longest_match; + functable.longest_match_slow = ft.longest_match_slow; + functable.quick_insert_string = ft.quick_insert_string; + functable.slide_hash = ft.slide_hash; + functable.update_hash = ft.update_hash; +} + +/* stub functions */ +static uint32_t adler32_stub(uint32_t adler, const uint8_t* buf, size_t len) { + init_functable(); + return functable.adler32(adler, buf, len); +} + +static uint32_t adler32_fold_copy_stub(uint32_t adler, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + return functable.adler32_fold_copy(adler, dst, src, len); +} + +static uint8_t* chunkmemset_safe_stub(uint8_t* out, unsigned dist, unsigned len, unsigned left) { + init_functable(); + return functable.chunkmemset_safe(out, dist, len, left); +} + +static uint32_t chunksize_stub(void) { + init_functable(); + return functable.chunksize(); +} + +static uint32_t compare256_stub(const uint8_t* src0, const uint8_t* src1) { + init_functable(); + return functable.compare256(src0, src1); +} + +static uint32_t crc32_stub(uint32_t crc, const uint8_t* buf, size_t len) { + init_functable(); + return functable.crc32(crc, buf, len); +} + +static void crc32_fold_stub(crc32_fold* crc, const uint8_t* src, size_t len, uint32_t init_crc) { + init_functable(); + functable.crc32_fold(crc, src, len, init_crc); +} + +static void crc32_fold_copy_stub(crc32_fold* crc, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + functable.crc32_fold_copy(crc, dst, src, len); +} + +static uint32_t crc32_fold_final_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_final(crc); +} + +static uint32_t crc32_fold_reset_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_reset(crc); +} + +static void inflate_fast_stub(PREFIX3(stream) *strm, uint32_t start) { + init_functable(); + functable.inflate_fast(strm, start); +} + +static void insert_string_stub(deflate_state* const s, uint32_t str, uint32_t count) { + init_functable(); + functable.insert_string(s, str, count); +} + +static uint32_t longest_match_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match(s, cur_match); +} + +static uint32_t longest_match_slow_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match_slow(s, cur_match); +} + +static Pos quick_insert_string_stub(deflate_state* const s, const uint32_t str) { + init_functable(); + return functable.quick_insert_string(s, str); +} + +static void slide_hash_stub(deflate_state* s) { + init_functable(); + functable.slide_hash(s); +} + +static uint32_t update_hash_stub(deflate_state* const s, uint32_t h, uint32_t val) { + init_functable(); + return functable.update_hash(s, h, val); +} + +/* functable init */ +Z_INTERNAL Z_TLS struct functable_s functable = { + adler32_stub, + adler32_fold_copy_stub, + chunkmemset_safe_stub, + chunksize_stub, + compare256_stub, + crc32_stub, + crc32_fold_stub, + crc32_fold_copy_stub, + crc32_fold_final_stub, + crc32_fold_reset_stub, + inflate_fast_stub, + insert_string_stub, + longest_match_stub, + longest_match_slow_stub, + quick_insert_string_stub, + slide_hash_stub, + update_hash_stub +}; diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/functable.h b/internal-complibs/zlib-ng-2.1.1-beta2/functable.h new file mode 100644 index 000000000..1cdfd4df4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/functable.h @@ -0,0 +1,41 @@ +/* functable.h -- Struct containing function pointers to optimized functions + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef FUNCTABLE_H_ +#define FUNCTABLE_H_ + +#include "deflate.h" +#include "crc32_fold.h" +#include "adler32_fold.h" + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +struct functable_s { + uint32_t (* adler32) (uint32_t adler, const uint8_t *buf, size_t len); + uint32_t (* adler32_fold_copy) (uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + uint8_t* (* chunkmemset_safe) (uint8_t *out, unsigned dist, unsigned len, unsigned left); + uint32_t (* chunksize) (void); + uint32_t (* compare256) (const uint8_t *src0, const uint8_t *src1); + uint32_t (* crc32) (uint32_t crc, const uint8_t *buf, size_t len); + void (* crc32_fold) (struct crc32_fold_s *crc, const uint8_t *src, size_t len, uint32_t init_crc); + void (* crc32_fold_copy) (struct crc32_fold_s *crc, uint8_t *dst, const uint8_t *src, size_t len); + uint32_t (* crc32_fold_final) (struct crc32_fold_s *crc); + uint32_t (* crc32_fold_reset) (struct crc32_fold_s *crc); + void (* inflate_fast) (PREFIX3(stream) *strm, uint32_t start); + void (* insert_string) (deflate_state *const s, uint32_t str, uint32_t count); + uint32_t (* longest_match) (deflate_state *const s, Pos cur_match); + uint32_t (* longest_match_slow) (deflate_state *const s, Pos cur_match); + Pos (* quick_insert_string)(deflate_state *const s, uint32_t str); + void (* slide_hash) (deflate_state *s); + uint32_t (* update_hash) (deflate_state *const s, uint32_t h, uint32_t val); +}; + +Z_INTERNAL extern Z_TLS struct functable_s functable; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/gzguts.h b/internal-complibs/zlib-ng-2.1.1-beta2/gzguts.h new file mode 100644 index 000000000..fe0927063 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/gzguts.h @@ -0,0 +1,145 @@ +#ifndef GZGUTS_H_ +#define GZGUTS_H_ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#include +#include +#include +#include +#include + +#if defined(ZLIB_COMPAT) +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#ifdef _WIN32 +# include +#endif + +#if defined(_WIN32) +# include +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +#if !defined(STDC99) && !defined(__CYGWIN__) && !defined(__MINGW__) && defined(_WIN32) +# if !defined(vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c + where the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +/* get errno and strerror definition */ +#ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +#else +# define zstrerror() "stdio error (consult errno)" +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#ifndef GZBUFSIZE +# define GZBUFSIZE 131072 +#endif + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + PREFIX3(stream) strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state *gz_statep; + +/* shared functions */ +void Z_INTERNAL gz_error(gz_state *, int, const char *); + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) + +#endif /* GZGUTS_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/gzlib.c b/internal-complibs/zlib-ng-2.1.1-beta2/gzlib.c new file mode 100644 index 000000000..e1290fc61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/gzlib.c @@ -0,0 +1,525 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +#if defined(_WIN32) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +static void gz_reset(gz_state *); +static gzFile gz_open(const void *, int, const char *); + +/* Reset gzip file state */ +static void gz_reset(gz_state *state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +static gzFile gz_open(const void *path, int fd, const char *mode) { + gz_state *state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_state *)zng_alloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') { + state->level = *mode - '0'; + } else { + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + zng_free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + {} + } + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + zng_free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + zng_free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, (const wchar_t *)path, 0); + if (len == (size_t)-1) + len = 0; + } else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + zng_free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) { + wcstombs(state->path, (const wchar_t *)path, len + 1); + } else { + *(state->path) = 0; + } + else +#endif + (void)snprintf(state->path, len + 1, "%s", (const char *)path); + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#if defined(_WIN32) + fd == -2 ? _wopen((const wchar_t *)path, oflag, 0666) : +#elif __CYGWIN__ + fd == -2 ? open(state->path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + zng_free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +#ifdef ZLIB_COMPAT +gzFile Z_EXPORT PREFIX4(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} +#endif + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzdopen)(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile Z_EXPORT PREFIX(gzopen_w)(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +int Z_EXPORT PREFIX(gzclose)(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_state *state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + return state->mode == GZ_READ ? PREFIX(gzclose_r)(file) : PREFIX(gzclose_w)(file); +#else + return PREFIX(gzclose_r)(file); +#endif +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzbuffer)(gzFile file, unsigned size) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzrewind)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzseek)(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (PREFIX(gzrewind)(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzseek)(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = PREFIX4(gzseek)(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gztell)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gztell)(gzFile file) { + + z_off64_t ret; + + ret = PREFIX4(gztell)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzoffset)(gzFile file) { + z_off64_t offset; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzoffset)(gzFile file) { + z_off64_t ret; + + ret = PREFIX4(gzoffset)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzeof)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * Z_EXPORT PREFIX(gzerror)(gzFile file, int *errnum) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void Z_EXPORT PREFIX(gzclearerr)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void Z_INTERNAL gz_error(gz_state *state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + return; + } + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, "%s%s%s", state->path, ": ", msg); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/gzread.c.in b/internal-complibs/zlib-ng-2.1.1-beta2/gzread.c.in new file mode 100644 index 000000000..67a21a3e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/gzread.c.in @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +/* Local functions */ +static int gz_load(gz_state *, unsigned char *, unsigned, unsigned *); +static int gz_avail(gz_state *); +static int gz_look(gz_state *); +static int gz_decomp(gz_state *); +static int gz_fetch(gz_state *); +static int gz_skip(gz_state *, z_off64_t); +static size_t gz_read(gz_state *, void *, size_t); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +static int gz_load(gz_state *state, unsigned char *buf, unsigned len, unsigned *have) { + ssize_t ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +static int gz_avail(gz_state *state) { + unsigned got; + PREFIX3(stream) *strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +static int gz_look(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)zng_alloc(state->want); + state->out = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = NULL; + state->strm.zfree = NULL; + state->strm.opaque = NULL; + state->strm.avail_in = 0; + state->strm.next_in = NULL; + if (PREFIX(inflateInit2)(&(state->strm), MAX_WBITS + 16) != Z_OK) { /* gunzip */ + zng_free(state->out); + zng_free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + PREFIX(inflateReset)(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +static int gz_decomp(gz_state *state) { + int ret = Z_OK; + unsigned had; + PREFIX3(stream) *strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = PREFIX(inflate)(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +static int gz_fetch(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + do { + switch (state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +static int gz_skip(gz_state *state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } else if (state->eof && state->strm.avail_in == 0) { + /* output buffer empty -- return if we're at the end of the input */ + break; + } else { + /* need more data to skip -- load up output buffer */ + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +static size_t gz_read(gz_state *state, void *buf, size_t len) { + size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzread)(gzFile file, void *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfread)(void *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + if (size && SIZE_MAX / size < nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + len = nitems * size; + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#undef @ZLIB_SYMBOL_PREFIX@gzgetc +#undef @ZLIB_SYMBOL_PREFIX@zng_gzgetc +int Z_EXPORT PREFIX(gzgetc)(gzFile file) { + unsigned char buf[1]; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +#ifdef ZLIB_COMPAT +int Z_EXPORT PREFIX(gzgetc_)(gzFile file) { + return PREFIX(gzgetc)(file); +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzungetc)(int c, gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * Z_EXPORT PREFIX(gzgets)(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_state *state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) { + do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + } + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzdirect)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + + state = (gz_state *)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_r)(gzFile file) { + int ret, err; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + + state = (gz_state *)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + PREFIX(inflateEnd)(&(state->strm)); + zng_free(state->out); + zng_free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + zng_free(state); + return ret ? Z_ERRNO : err; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/gzwrite.c b/internal-complibs/zlib-ng-2.1.1-beta2/gzwrite.c new file mode 100644 index 000000000..08e0ce9aa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/gzwrite.c @@ -0,0 +1,526 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include +#include "gzguts.h" + +/* Local functions */ +static int gz_init(gz_state *); +static int gz_comp(gz_state *, int); +static int gz_zero(gz_state *, z_off64_t); +static size_t gz_write(gz_state *, void const *, size_t); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +static int gz_init(gz_state *state) { + int ret; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + memset(state->in, 0, state->want << 1); + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)zng_alloc(state->want); + if (state->out == NULL) { + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = NULL; + strm->zfree = NULL; + strm->opaque = NULL; + ret = PREFIX(deflateInit2)(strm, state->level, Z_DEFLATED, MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +static int gz_comp(gz_state *state, int flush) { + int ret; + ssize_t got; + unsigned have; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + PREFIX(deflateReset)(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, (unsigned long)have)) < 0 || (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = PREFIX(deflate)(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +static int gz_zero(gz_state *state, z_off64_t len) { + int first; + unsigned n; + PREFIX3(stream) *strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* 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. */ +static size_t gz_write(gz_state *state, void const *buf, size_t len) { + size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const unsigned char *) buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzwrite)(gzFile file, void const *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfwrite)(void const *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputc)(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputs)(gzFile file, const char *s) { + size_t len, put; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +/* -- see zlib.h -- */ +int Z_EXPORTVA PREFIX(gzvprintf)(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; + len = vsnprintf(next, state->size, format, va); + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int Z_EXPORTVA PREFIX(gzprintf)(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = PREFIX(gzvprintf)(file, format, va); + va_end(va); + return ret; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzflush)(gzFile file, int flush) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzsetparams)(gzFile file, int level, int strategy) { + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + PREFIX(deflateParams)(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_w)(gzFile file) { + int ret = Z_OK; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)PREFIX(deflateEnd)(&(state->strm)); + zng_free(state->out); + } + zng_free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + zng_free(state); + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/infback.c b/internal-complibs/zlib-ng-2.1.1-beta2/infback.c new file mode 100644 index 000000000..9f5042b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/infback.c @@ -0,0 +1,511 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateBackInit +#endif + +/* + strm provides memory allocation functions in zalloc and zfree, or + NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + + This function is hidden in ZLIB_COMPAT builds. + */ +int32_t ZNG_CONDEXPORT PREFIX(inflateBackInit)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window) { + struct inflate_state *state; + + if (strm == NULL || window == NULL || windowBits < MIN_WBITS || windowBits > MAX_WBITS) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->dmax = 32768U; + state->wbits = (unsigned int)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + state->chunksize = functable.chunksize(); + return Z_OK; +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateBackInit_)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window, + const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateBackInit)(strm, windowBits, window); +} + +/* + Private macros for inflateBack() + Look in inflate_p.h for macros shared with inflate() +*/ + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is NULL or the state was not initialized. + */ +int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in_desc, out_func out, void *out_desc) { + struct inflate_state *state; + z_const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == NULL || strm->state == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* Reset the state */ + strm->msg = NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + copy = MIN(copy, have); + copy = MIN(copy, left); + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && + left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + functable.inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (here.op & MAX_BITS); + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } else { + from = put - state->offset; + copy = left; + } + copy = MIN(copy, state->length); + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && (ret == Z_STREAM_END)) { + ret = Z_BUF_ERROR; + } + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateBackEnd)(PREFIX3(stream) *strm) { + if (strm == NULL || strm->state == NULL || strm->zfree == NULL) + return Z_STREAM_ERROR; + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inffast_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/inffast_tpl.h new file mode 100644 index 000000000..9ddd187d8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inffast_tpl.h @@ -0,0 +1,326 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= INFLATE_FAST_MIN_HAVE + strm->avail_out >= INFLATE_FAST_MIN_LEFT + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - On some architectures, it can be significantly faster (e.g. up to 1.2x + faster on x86_64) to load from strm->next_in 64 bits, or 8 bytes, at a + time, so INFLATE_FAST_MIN_HAVE == 8. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { + /* start: inflate()'s starting value for strm->avail_out */ + struct inflate_state *state; + z_const unsigned char *in; /* local strm->next_in */ + const unsigned char *last; /* have enough input while in < last */ + unsigned char *out; /* local strm->next_out */ + unsigned char *beg; /* inflate()'s initial strm->next_out */ + unsigned char *end; /* while out < end, enough space available */ + unsigned char *safe; /* can use chunkcopy provided out < safe */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if wsize != 0 */ + + /* hold is a local copy of strm->hold. By default, hold satisfies the same + invariants that strm->hold does, namely that (hold >> bits) == 0. This + invariant is kept by loading bits into hold one byte at a time, like: + + hold |= next_byte_of_input << bits; in++; bits += 8; + + If we need to ensure that bits >= 15 then this code snippet is simply + repeated. Over one iteration of the outermost do/while loop, this + happens up to six times (48 bits of input), as described in the NOTES + above. + + However, on some little endian architectures, it can be significantly + faster to load 64 bits once instead of 8 bits six times: + + if (bits <= 16) { + hold |= next_8_bytes_of_input << bits; in += 6; bits += 48; + } + + Unlike the simpler one byte load, shifting the next_8_bytes_of_input + by bits will overflow and lose those high bits, up to 2 bytes' worth. + The conservative estimate is therefore that we have read only 6 bytes + (48 bits). Again, as per the NOTES above, 48 bits is sufficient for the + rest of the iteration, and we will not need to load another 8 bytes. + + Inside this function, we no longer satisfy (hold >> bits) == 0, but + this is not problematic, even if that overflow does not land on an 8 bit + byte boundary. Those excess bits will eventually shift down lower as the + Huffman decoder consumes input, and when new input bits need to be loaded + into the bits variable, the same input bits will be or'ed over those + existing bits. A bitwise or is idempotent: (a | b | b) equals (a | b). + Note that we therefore write that load operation as "hold |= etc" and not + "hold += etc". + + Outside that loop, at the end of the function, hold is bitwise and'ed + with (1<hold >> state->bits) == 0. + */ + uint64_t hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const *lcode; /* local strm->lencode */ + code const *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + const code *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char *from; /* where to copy match from */ + unsigned extra_safe; /* copy chunks safely in all cases */ + + /* copy state to local variables */ + state = (struct inflate_state *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - (INFLATE_FAST_MIN_HAVE - 1)); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - (INFLATE_FAST_MIN_LEFT - 1)); + safe = out + strm->avail_out; +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* Detect if out and window point to the same memory allocation. In this instance it is + necessary to use safe chunk copy functions to prevent overwriting the window. If the + window is overwritten then future matches with far distances will fail to copy correctly. */ + extra_safe = (wsize != 0 && out >= window && out + INFLATE_FAST_MIN_LEFT <= window + wsize); + +#define REFILL() do { \ + hold |= load_64_bits(in, bits); \ + in += 7; \ + in -= ((bits >> 3) & 7); \ + bits |= 56; \ + } while (0) + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + REFILL(); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + } + } + dolen: + DROPBITS(here->bits); + op = here->op; + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } else if (op & 16) { /* length base */ + len = here->val; + op &= MAX_BITS; /* number of extra bits */ + len += BITS(op); + DROPBITS(op); + Tracevv((stderr, "inflate: length %u\n", len)); + here = dcode + (hold & dmask); + if (bits < MAX_BITS + MAX_DIST_EXTRA_BITS) { + REFILL(); + } + dodist: + DROPBITS(here->bits); + op = here->op; + if (op & 16) { /* distance base */ + dist = here->val; + op &= MAX_BITS; /* number of extra bits */ + dist += BITS(op); +#ifdef INFLATE_STRICT + if (dist > dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + DROPBITS(op); + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + } else if (wnext >= op) { /* contiguous in window */ + from += wnext - op; + } else { /* wrap around window */ + op -= wnext; + from += wsize - op; + if (op < len) { /* some from end of window */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + from = window; /* more from start of window */ + op = wnext; + /* This (rare) case can create a situation where + the first chunkcopy below must be checked. + */ + } + } + if (op < len) { /* still need some from output */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + out = CHUNKUNROLL(out, &dist, &len); + out = chunkcopy_safe(out, out - dist, len, safe); + } else { + out = chunkcopy_safe(out, from, len, safe); + } + } else if (extra_safe) { + /* Whole reference is in range of current output. */ + if (dist >= len || dist >= state->chunksize) + out = chunkcopy_safe(out, out - dist, len, safe); + else + out = CHUNKMEMSET_SAFE(out, dist, len, (unsigned)((safe - out) + 1)); + } else { + /* Whole reference is in range of current output. No range checks are + necessary because we start with room for at least 258 bytes of output, + so unroll and roundoff operations can write beyond `out+len` so long + as they stay within 258 bytes of `out`. + */ + if (dist >= len || dist >= state->chunksize) + out = CHUNKCOPY(out, out - dist, len); + else + out = CHUNKMEMSET(out, dist, len); + } + } else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + BITS(op); + goto dodist; + } else { + SET_BAD("invalid distance code"); + break; + } + } else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + BITS(op); + goto dolen; + } else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } else { + SET_BAD("invalid literal/length code"); + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (UINT64_C(1) << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? (INFLATE_FAST_MIN_HAVE - 1) + (last - in) + : (INFLATE_FAST_MIN_HAVE - 1) - (in - last)); + strm->avail_out = (unsigned)(out < end ? (INFLATE_FAST_MIN_LEFT - 1) + (end - out) + : (INFLATE_FAST_MIN_LEFT - 1) - (out - end)); + + Assert(bits <= 32, "Remaining bits greater than 32"); + state->hold = (uint32_t)hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inffixed_tbl.h b/internal-complibs/zlib-ng-2.1.1-beta2/inffixed_tbl.h new file mode 100644 index 000000000..7292fa06e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inffixed_tbl.h @@ -0,0 +1,94 @@ +/* inffixed_tbl.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + +/* WARNING: this file should *not* be used by applications. + * It is part of the implementation of this library and is + * subject to change. Applications should only use zlib.h. + */ + +static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} +}; + +static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} +}; diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inflate.c b/internal-complibs/zlib-ng-2.1.1-beta2/inflate.c new file mode 100644 index 000000000..0cbed041d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inflate.c @@ -0,0 +1,1408 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "inffixed_tbl.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateInit +# undef inflateInit2 +#endif + +/* function prototypes */ +static int inflateStateCheck(PREFIX3(stream) *strm); +static int updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum); +static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len); + +static inline void inf_chksum_cpy(PREFIX3(stream) *strm, uint8_t *dst, + const uint8_t *src, uint32_t copy) { + if (!copy) return; + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold_copy(&state->crc_fold, dst, src, copy); + } else +#endif + { + strm->adler = state->check = functable.adler32_fold_copy(state->check, dst, src, copy); + } +} + +static inline void inf_chksum(PREFIX3(stream) *strm, const uint8_t *src, uint32_t len) { + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold(&state->crc_fold, src, len, 0); + } else +#endif + { + strm->adler = state->check = functable.adler32(state->check, src, len); + } +} + +static int inflateStateCheck(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->zalloc == NULL || strm->zfree == NULL) + return 1; + state = (struct inflate_state *)strm->state; + if (state == NULL || state->strm != strm || state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int32_t Z_EXPORT PREFIX(inflateResetKeep)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->check = ADLER32_INITIAL_VALUE; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + INFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateReset)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return PREFIX(inflateResetKeep)(strm); +} + +int32_t Z_EXPORT PREFIX(inflateReset2)(PREFIX3(stream) *strm, int32_t windowBits) { + int wrap; + struct inflate_state *state; + + /* get the state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= MAX_WBITS; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < MIN_WBITS || windowBits > MAX_WBITS)) + return Z_STREAM_ERROR; + if (state->window != NULL && state->wbits != (unsigned)windowBits) { + ZFREE_WINDOW(strm, state->window); + state->window = NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return PREFIX(inflateReset)(strm); +} + +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(inflateInit2)(PREFIX3(stream) *strm, int32_t windowBits) { + int32_t ret; + struct inflate_state *state; + + if (strm == NULL) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->strm = strm; + state->window = NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + state->chunksize = functable.chunksize(); + ret = PREFIX(inflateReset2)(strm, windowBits); + if (ret != Z_OK) { + ZFREE_STATE(strm, state); + strm->state = NULL; + } + return ret; +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(inflateInit)(PREFIX3(stream) *strm) { + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit_)(PREFIX3(stream) *strm, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit2_)(PREFIX3(stream) *strm, int32_t windowBits, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, windowBits); +} + +int32_t Z_EXPORT PREFIX(inflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + INFLATE_PRIME_HOOK(strm, bits, value); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (unsigned int)bits > 32) + return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (unsigned int)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. This returns fixed tables from inffixed_tbl.h. + */ + +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state) { + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state) { + /* if it hasn't been done already, allocate space for the window */ + if (state->window == NULL) { + unsigned wsize = 1U << state->wbits; + state->window = (unsigned char *)ZALLOC_WINDOW(state->strm, wsize + state->chunksize, sizeof(unsigned char)); + if (state->window == NULL) + return Z_MEM_ERROR; +#ifdef Z_MEMORY_SANITIZER + /* This is _not_ to subvert the memory sanitizer but to instead unposion some + data we willingly and purposefully load uninitialized into vector registers + in order to safely read the last < chunksize bytes of the window. */ + __msan_unpoison(state->window + wsize, state->chunksize); +#endif + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + return Z_OK; +} + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +static int32_t updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum) { + struct inflate_state *state; + uint32_t dist; + + state = (struct inflate_state *)strm->state; + + if (PREFIX(inflate_ensure_window)(state)) return 1; + + /* len state->wsize or less output bytes into the circular window */ + if (len >= state->wsize) { + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * it (s/390 being the primary exception to this. Also, for now, do the adler checksums + * if not a gzip based header. The inline adler checksums will come in the near future, + * possibly the next commit */ + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + /* We have to split the checksum over non-copied and copied bytes */ + if (len > state->wsize) + inf_chksum(strm, end - len, len - state->wsize); + inf_chksum_cpy(strm, state->window, end - state->wsize, state->wsize); + } else { + memcpy(state->window, end - state->wsize, state->wsize); + } + + state->wnext = 0; + state->whave = state->wsize; + } else { + dist = state->wsize - state->wnext; + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * We need to maintain the correct order here for the checksum */ + dist = MIN(dist, len); + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window + state->wnext, end - len, dist); + } else { + memcpy(state->window + state->wnext, end - len, dist); + } + len -= dist; + if (len) { + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window, end - len, len); + } else { + memcpy(state->window, end - len, len); + } + + state->wnext = len; + state->whave = state->wsize; + } else { + state->wnext += dist; + if (state->wnext == state->wsize) + state->wnext = 0; + if (state->whave < state->wsize) + state->whave += dist; + } + } + return 0; +} + +/* + Private macros for inflate() + Look in inflate_p.h for macros shared with inflateBack() +*/ + +/* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) { + struct inflate_state *state; + const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + uint32_t in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == NULL || + (strm->next_in == NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state *)strm->state; + if (state->mode == TYPE) /* skip check */ + state->mode = TYPEDO; + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = MAX_WBITS; + state->check = CRC32_INITIAL_VALUE; + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + SET_BAD("incorrect header check"); + break; + } + if (BITS(4) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > MAX_WBITS || len > state->wbits) { + SET_BAD("invalid window size"); + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + if (state->flags & 0xe000) { + SET_BAD("unknown header flags set"); + break; + } + if (state->head != NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + Z_FALLTHROUGH; + + case TIME: + NEEDBITS(32); + if (state->head != NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + Z_FALLTHROUGH; + + case OS: + NEEDBITS(16); + if (state->head != NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + Z_FALLTHROUGH; + + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (uint16_t)hold; + if (state->head != NULL) + state->head->extra_len = (uint16_t)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } else if (state->head != NULL) { + state->head->extra = NULL; + } + state->mode = EXTRA; + Z_FALLTHROUGH; + + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) + copy = have; + if (copy) { + if (state->head != NULL && state->head->extra != NULL) { + len = state->head->extra_len - state->length; + if (len < state->head->extra_max) { + memcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + } + if ((state->flags & 0x0200) && (state->wrap & 4)) { + state->check = PREFIX(crc32)(state->check, next, copy); + } + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) + goto inf_leave; + } + state->length = 0; + state->mode = NAME; + Z_FALLTHROUGH; + + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->name != NULL && state->length < state->head->name_max) + state->head->name[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->name = NULL; + } + state->length = 0; + state->mode = COMMENT; + Z_FALLTHROUGH; + + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->comment != NULL + && state->length < state->head->comm_max) + state->head->comment[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->comment = NULL; + } + state->mode = HCRC; + Z_FALLTHROUGH; + + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + SET_BAD("header crc mismatch"); + break; + } + INITBITS(); + } + if (state->head != NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + /* compute crc32 checksum if not in raw mode */ + if ((state->wrap & 4) && state->flags) + strm->adler = state->check = functable.crc32_fold_reset(&state->crc_fold); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + Z_FALLTHROUGH; + + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = TYPE; + Z_FALLTHROUGH; + + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case TYPEDO: + /* determine and dispatch block type */ + INFLATE_TYPEDO_HOOK(strm, flush); /* hook for IBM Z DFLTCC */ + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case COPY_: + state->mode = COPY; + Z_FALLTHROUGH; + + case COPY: + /* copy stored block from input to output */ + copy = state->length; + if (copy) { + copy = MIN(copy, have); + copy = MIN(copy, left); + if (copy == 0) + goto inf_leave; + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + Z_FALLTHROUGH; + + case LENLENS: + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + Z_FALLTHROUGH; + + case CODELENS: + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case LEN_: + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + functable.inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code */ + state->extra = (here.op & MAX_BITS); + state->mode = LENEXT; + Z_FALLTHROUGH; + + case LENEXT: + /* get extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + Z_FALLTHROUGH; + + case DIST: + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + state->mode = DISTEXT; + Z_FALLTHROUGH; + + case DISTEXT: + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + Z_FALLTHROUGH; + + case MATCH: + /* copy match from window to output */ + if (left == 0) + goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + copy = MIN(copy, state->length); + copy = MIN(copy, left); + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) + state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } else { + from = state->window + (state->wnext - copy); + } + copy = MIN(copy, state->length); + copy = MIN(copy, left); + + put = chunkcopy_safe(put, from, copy, put + left); + } else { + copy = MIN(state->length, left); + + put = functable.chunkmemset_safe(put, state->offset, copy, left); + } + left -= copy; + state->length -= copy; + if (state->length == 0) + state->mode = LEN; + break; + + case LIT: + if (left == 0) + goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + + /* compute crc32 checksum if not in raw mode */ + if (INFLATE_NEED_CHECKSUM(strm) && state->wrap & 4) { + if (out) { + inf_chksum(strm, put - out, out); + } +#ifdef GUNZIP + if (state->flags) + strm->adler = state->check = functable.crc32_fold_final(&state->crc_fold); +#endif + } + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + SET_BAD("incorrect data check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + Z_FALLTHROUGH; + + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + SET_BAD("incorrect length check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + Z_FALLTHROUGH; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + case MEM: + return Z_MEM_ERROR; + + case SYNC: + + default: /* can't happen, but makes compilers happy */ + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (INFLATE_NEED_UPDATEWINDOW(strm) && + (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH)))) { + /* update sliding window with respective checksum if not in "raw" mode */ + if (updatewindow(strm, strm->next_out, out - strm->avail_out, state->wrap & 4)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateEnd)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->window != NULL) + ZFREE_WINDOW(strm, state->window); + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary */ + if (state->whave && dictionary != NULL) { + memcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); + memcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); + } + if (dictLength != NULL) + *dictLength = state->whave; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + struct inflate_state *state; + unsigned long dictid; + int32_t ret; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = functable.adler32(ADLER32_INITIAL_VALUE, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength, 0); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if ((state->wrap & 2) == 0) + return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +static uint32_t syncsearch(uint32_t *have, const uint8_t *buf, uint32_t len) { + uint32_t got, next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int32_t Z_EXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + size_t in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state *state; + + /* check parameters */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) + return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) + return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; + out = strm->total_out; + PREFIX(inflateReset)(strm); + strm->total_in = (z_uintmax_t)in; /* Can't use z_size_t here as it will overflow on 64-bit Windows */ + strm->total_out = (z_uintmax_t)out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int32_t Z_EXPORT PREFIX(inflateSyncPoint)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + INFLATE_SYNC_POINT_HOOK(strm); + state = (struct inflate_state *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int32_t Z_EXPORT PREFIX(inflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + struct inflate_state *state; + struct inflate_state *copy; + unsigned char *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)source->state; + + /* allocate space */ + copy = ZALLOC_INFLATE_STATE(source); + if (copy == NULL) + return Z_MEM_ERROR; + window = NULL; + if (state->window != NULL) { + wsize = 1U << state->wbits; + window = (unsigned char *)ZALLOC_WINDOW(source, wsize, sizeof(unsigned char)); + if (window == NULL) { + ZFREE_STATE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + ZCOPY_INFLATE_STATE(copy, state); + copy->strm = dest; + if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != NULL) { + ZCOPY_WINDOW(window, state->window, (size_t)1U << state->wbits); + } + copy->window = window; + dest->state = (struct internal_state *)copy; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateUndermine)(PREFIX3(stream) *strm, int32_t subvert) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + Z_UNUSED(subvert); + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int32_t Z_EXPORT PREFIX(inflateValidate)(PREFIX3(stream) *strm, int32_t check) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long Z_EXPORT PREFIX(inflateMark)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return -65536; + INFLATE_MARK_HOOK(strm); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long Z_EXPORT PREFIX(inflateCodesUsed)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->state == NULL) + return (unsigned long)-1; + state = (struct inflate_state *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inflate.h b/internal-complibs/zlib-ng-2.1.1-beta2/inflate.h new file mode 100644 index 000000000..39cdf5d68 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inflate.h @@ -0,0 +1,140 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef INFLATE_H_ +#define INFLATE_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). + NO_GZIP would be used to avoid linking in the crc code when it is not needed. + For shared libraries, gzip decoding should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + PREFIX(gz_headerp) head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + uint32_t wsize; /* window size or zero if not using window */ + uint32_t whave; /* valid bytes in the window */ + uint32_t wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if needed */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* bit accumulator */ + uint32_t hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + uint32_t length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const *lencode; /* starting table for length/literal codes */ + code const *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + uint32_t have; /* number of code lengths in lens[] */ + code *next; /* next available space in codes[] */ + uint16_t lens[320]; /* temporary storage for code lengths */ + uint16_t work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ + uint32_t chunksize; /* size of memory copying chunk */ +}; + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state); +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state); + +#endif /* INFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inflate_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/inflate_p.h new file mode 100644 index 000000000..a007cd05d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inflate_p.h @@ -0,0 +1,225 @@ +/* inflate_p.h -- Private inline functions and macros shared with more than one deflate method + * + */ + +#ifndef INFLATE_P_H +#define INFLATE_P_H + +#include + +/* Architecture-specific hooks. */ +#ifdef S390_DFLTCC_INFLATE +# include "arch/s390/dfltcc_inflate.h" +#else +/* Memory management for the inflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_INFLATE_STATE(strm) ((struct inflate_state *)ZALLOC(strm, 1, sizeof(struct inflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_INFLATE_STATE(dst, src) memcpy(dst, src, sizeof(struct inflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define ZCOPY_WINDOW(dest, src, n) memcpy(dest, src, n) +# define ZFREE_WINDOW(strm, addr) ZFREE(strm, addr) +/* Invoked at the end of inflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflatePrime(). Useful for updating arch-specific buffers. */ +# define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0) +/* Invoked at the beginning of each block. Useful for plugging arch-specific inflation code. */ +# define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_UPDATEWINDOW(strm) 1 +/* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */ +# define INFLATE_MARK_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */ +# define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSetDictionary(). Useful for checking arch-specific window data. */ +# define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of inflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +#endif + +/* + * Macros shared by inflate() and inflateBack() + */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? PREFIX(crc32)(check, buf, len) : functable.adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) functable.adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = PREFIX(crc32)(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = PREFIX(crc32)(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = (z_const unsigned char *)next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Ensure that there is at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate()/inflateBack(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + (hold & ((1U << (unsigned)(n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Set mode=BAD and prepare error message */ +#define SET_BAD(errmsg) \ + do { \ + state->mode = BAD; \ + strm->msg = (char *)errmsg; \ + } while (0) + +#define INFLATE_FAST_MIN_HAVE 15 +#define INFLATE_FAST_MIN_LEFT 260 + +/* Load 64 bits from IN and place the bytes at offset BITS in the result. */ +static inline uint64_t load_64_bits(const unsigned char *in, unsigned bits) { + uint64_t chunk; + memcpy(&chunk, in, sizeof(chunk)); + +#if BYTE_ORDER == LITTLE_ENDIAN + return chunk << bits; +#else + return ZSWAP64(chunk) << bits; +#endif +} + +/* Behave like chunkcopy, but avoid writing beyond of legal output. */ +static inline uint8_t* chunkcopy_safe(uint8_t *out, uint8_t *from, uint64_t len, uint8_t *safe) { + uint64_t safelen = (safe - out) + 1; + len = MIN(len, safelen); + int32_t olap_src = from >= out && from < out + len; + int32_t olap_dst = out >= from && out < from + len; + uint64_t tocopy; + + /* For all cases without overlap, memcpy is ideal */ + if (!(olap_src || olap_dst)) { + memcpy(out, from, (size_t)len); + return out + len; + } + + /* We are emulating a self-modifying copy loop here. To do this in a way that doesn't produce undefined behavior, + * we have to get a bit clever. First if the overlap is such that src falls between dst and dst+len, we can do the + * initial bulk memcpy of the nonoverlapping region. Then, we can leverage the size of this to determine the safest + * atomic memcpy size we can pick such that we have non-overlapping regions. This effectively becomes a safe look + * behind or lookahead distance. */ + uint64_t non_olap_size = llabs(from - out); // llabs vs labs for compatibility with windows + + memcpy(out, from, (size_t)non_olap_size); + out += non_olap_size; + from += non_olap_size; + len -= non_olap_size; + + /* So this doesn't give use a worst case scenario of function calls in a loop, + * we want to instead break this down into copy blocks of fixed lengths */ + while (len) { + tocopy = MIN(non_olap_size, len); + len -= tocopy; + + while (tocopy >= 32) { + memcpy(out, from, 32); + out += 32; + from += 32; + tocopy -= 32; + } + + if (tocopy >= 16) { + memcpy(out, from, 16); + out += 16; + from += 16; + tocopy -= 16; + } + + if (tocopy >= 8) { + memcpy(out, from, 8); + out += 8; + from += 8; + tocopy -= 8; + } + + if (tocopy >= 4) { + memcpy(out, from, 4); + out += 4; + from += 4; + tocopy -= 4; + } + + if (tocopy >= 2) { + memcpy(out, from, 2); + out += 2; + from += 2; + tocopy -= 2; + } + + if (tocopy) { + *out++ = *from++; + } + } + + return out; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.c b/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.c new file mode 100644 index 000000000..f04d65f86 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.c @@ -0,0 +1,295 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" + +const char PREFIX(inflate_copyright)[] = " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int Z_INTERNAL zng_inflate_table(codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code *next; /* next available space in table */ + const uint16_t *base; /* base value table to use */ + const uint16_t *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + uint16_t count[MAX_BITS+1]; /* number of codes of each length */ + uint16_t offs[MAX_BITS+1]; /* offsets in table for each length */ + static const uint16_t lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const uint16_t lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + static const uint16_t dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const uint16_t dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAX_BITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAX_BITS; max >= 1; max--) + if (count[max] != 0) break; + root = MIN(root, max); + if (UNLIKELY(max == 0)) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (uint16_t)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + root = MAX(root, min); + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAX_BITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAX_BITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (uint16_t)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (LIKELY(work[sym] >= match)) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } else if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) + break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) + break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (uint16_t)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (UNLIKELY(huff != 0)) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (uint16_t)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.h b/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.h new file mode 100644 index 000000000..eeae9c6ac --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/inftrees.h @@ -0,0 +1,66 @@ +#ifndef INFTREES_H_ +#define INFTREES_H_ + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + uint16_t val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1924, which is the sum of 1332 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distributions. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 10 15" for literal/length codes + returns returns 1332, and "enough 30 9 15" for distance codes returns 592. + The initial root table size (10 or 9) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 1332 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int Z_INTERNAL zng_inflate_table (codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work); + +#endif /* INFTREES_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/insert_string.c b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string.c new file mode 100644 index 000000000..cfe39837f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string.c @@ -0,0 +1,21 @@ +/* insert_string.c -- insert_string integer hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 16 + +#define HASH_CALC(s, h, val) h = ((val * 2654435761U) >> HASH_SLIDE); +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_c +#define INSERT_STRING insert_string_c +#define QUICK_INSERT_STRING quick_insert_string_c + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_roll.c b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_roll.c new file mode 100644 index 000000000..dfea347bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_roll.c @@ -0,0 +1,24 @@ +/* insert_string_roll.c -- insert_string rolling hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 5 + +#define HASH_CALC(s, h, val) h = ((h << HASH_SLIDE) ^ ((uint8_t)val)) +#define HASH_CALC_VAR s->ins_h +#define HASH_CALC_VAR_INIT +#define HASH_CALC_READ val = strstart[0] +#define HASH_CALC_MASK (32768u - 1u) +#define HASH_CALC_OFFSET (STD_MIN_MATCH-1) + +#define UPDATE_HASH update_hash_roll +#define INSERT_STRING insert_string_roll +#define QUICK_INSERT_STRING quick_insert_string_roll + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_tpl.h new file mode 100644 index 000000000..4acd67fd6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/insert_string_tpl.h @@ -0,0 +1,108 @@ +#ifndef INSERT_STRING_H_ +#define INSERT_STRING_H_ + +/* insert_string.h -- Private insert_string functions shared with more than + * one insert string implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef HASH_CALC_OFFSET +# define HASH_CALC_OFFSET 0 +#endif +#ifndef HASH_CALC_MASK +# define HASH_CALC_MASK HASH_MASK +#endif +#ifndef HASH_CALC_READ +# if BYTE_ORDER == LITTLE_ENDIAN +# define HASH_CALC_READ \ + memcpy(&val, strstart, sizeof(val)); +# else +# define HASH_CALC_READ \ + val = ((uint32_t)(strstart[0])); \ + val |= ((uint32_t)(strstart[1]) << 8); \ + val |= ((uint32_t)(strstart[2]) << 16); \ + val |= ((uint32_t)(strstart[3]) << 24); +# endif +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +Z_INTERNAL uint32_t UPDATE_HASH(deflate_state *const s, uint32_t h, uint32_t val) { + (void)s; + HASH_CALC(s, h, val); + return h & HASH_CALC_MASK; +} + +/* =========================================================================== + * Quick insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + */ +Z_INTERNAL Pos QUICK_INSERT_STRING(deflate_state *const s, uint32_t str) { + Pos head; + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + head = s->head[hm]; + if (LIKELY(head != str)) { + s->prev[str & s->w_mask] = head; + s->head[hm] = (Pos)str; + } + return head; +} + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first STD_MIN_MATCH bytes of str are valid + * (except for the last STD_MIN_MATCH-1 bytes of the input file). + */ +Z_INTERNAL void INSERT_STRING(deflate_state *const s, uint32_t str, uint32_t count) { + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint8_t *strend = strstart + count; + + for (Pos idx = (Pos)str; strstart < strend; idx++, strstart++) { + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + Pos head = s->head[hm]; + if (LIKELY(head != idx)) { + s->prev[idx & s->w_mask] = head; + s->head[hm] = idx; + } + } +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/match_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/match_tpl.h new file mode 100644 index 000000000..d07679852 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/match_tpl.h @@ -0,0 +1,289 @@ +/* match_tpl.h -- find longest match template for compare256 variants + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Portions copyright (C) 2014-2021 Konstantin Nosov + * Fast-zlib optimized longest_match + * https://github.com/gildor2/fast_zlib + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "functable.h" + +#ifndef MATCH_TPL_H +#define MATCH_TPL_H + +#define EARLY_EXIT_TRIGGER_LEVEL 5 + +#endif + +/* Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is garbage. + * + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >=1 + * OUT assertion: the match length is not greater than s->lookahead + */ +Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) { + unsigned int strstart = s->strstart; + const unsigned wmask = s->w_mask; + unsigned char *window = s->window; + unsigned char *scan = window + strstart; + Z_REGISTER unsigned char *mbase_start = window; + Z_REGISTER unsigned char *mbase_end; + const Pos *prev = s->prev; + Pos limit; +#ifdef LONGEST_MATCH_SLOW + Pos limit_base; +#else + int32_t early_exit; +#endif + uint32_t chain_length, nice_match, best_len, offset; + uint32_t lookahead = s->lookahead; + Pos match_offset = 0; +#ifdef UNALIGNED_OK + uint8_t scan_start[8]; +#endif + uint8_t scan_end[8]; + +#define GOTO_NEXT_CHAIN \ + if (--chain_length && (cur_match = prev[cur_match & wmask]) > limit) \ + continue; \ + return best_len; + + /* The code is optimized for STD_MAX_MATCH-2 multiple of 16. */ + Assert(STD_MAX_MATCH == 258, "Code too clever"); + + best_len = s->prev_length ? s->prev_length : STD_MIN_MATCH-1; + + /* Calculate read offset which should only extend an extra byte + * to find the next best match length. + */ + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_start, scan, sizeof(uint64_t)); + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_start, scan, sizeof(uint32_t)); + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + mbase_end = (mbase_start+offset); + + /* Do not waste too much time if we already have a good match */ + chain_length = s->max_chain_length; + if (best_len >= s->good_match) + chain_length >>= 2; + nice_match = (uint32_t)s->nice_match; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0 + */ + limit = strstart > MAX_DIST(s) ? (Pos)(strstart - MAX_DIST(s)) : 0; +#ifdef LONGEST_MATCH_SLOW + limit_base = limit; + if (best_len >= STD_MIN_MATCH) { + /* We're continuing search (lazy evaluation). */ + uint32_t i, hash; + Pos pos; + + /* Find a most distant chain starting from scan with index=1 (index=0 corresponds + * to cur_match). We cannot use s->prev[strstart+1,...] immediately, because + * these strings are not yet inserted into the hash table. + */ + hash = s->update_hash(s, 0, scan[1]); + hash = s->update_hash(s, hash, scan[2]); + + for (i = 3; i <= best_len; i++) { + hash = s->update_hash(s, hash, scan[i]); + + /* If we're starting with best_len >= 3, we can use offset search. */ + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(i - 2); + cur_match = pos; + } + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + if (cur_match <= limit) + goto break_matching; + mbase_start -= match_offset; + mbase_end -= match_offset; + } +#else + early_exit = s->level < EARLY_EXIT_TRIGGER_LEVEL; +#endif + Assert((unsigned long)strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); + for (;;) { + if (cur_match >= strstart) + break; + + /* Skip to next match if the match length cannot increase or if the match length is + * less than 2. Note that the checks below for insufficient lookahead only occur + * occasionally for performance reasons. + * Therefore uninitialized memory will be accessed and conditional jumps will be made + * that depend on those values. However the length of the match is limited to the + * lookahead, so the output of deflate is not affected by the uninitialized values. + */ +#ifdef UNALIGNED_OK + if (best_len < sizeof(uint32_t)) { + for (;;) { + if (zng_memcmp_2(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_2(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# ifdef UNALIGNED64_OK + } else if (best_len >= sizeof(uint64_t)) { + for (;;) { + if (zng_memcmp_8(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_8(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# endif + } else { + for (;;) { + if (zng_memcmp_4(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_4(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } + } +#else + for (;;) { + if (mbase_end[cur_match] == scan_end[0] && mbase_end[cur_match+1] == scan_end[1] && + mbase_start[cur_match] == scan[0] && mbase_start[cur_match+1] == scan[1]) + break; + GOTO_NEXT_CHAIN; + } +#endif + uint32_t len = COMPARE256(scan+2, mbase_start+cur_match+2) + 2; + Assert(scan+len <= window+(unsigned)(s->window_size-1), "wild scan"); + + if (len > best_len) { + uint32_t match_start = cur_match - match_offset; + s->match_start = match_start; + + /* Do not look for matches beyond the end of the input. */ + if (len > lookahead) + return lookahead; + best_len = len; + if (best_len >= nice_match) + return best_len; + + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + +#ifdef LONGEST_MATCH_SLOW + /* Look for a better string offset */ + if (UNLIKELY(len > STD_MIN_MATCH && match_start + len < strstart)) { + Pos pos, next_pos; + uint32_t i, hash; + unsigned char *scan_endstr; + + /* Go back to offset 0 */ + cur_match -= match_offset; + match_offset = 0; + next_pos = cur_match; + for (i = 0; i <= len - STD_MIN_MATCH; i++) { + pos = prev[(cur_match + i) & wmask]; + if (pos < next_pos) { + /* Hash chain is more distant, use it */ + if (pos <= limit_base + i) + goto break_matching; + next_pos = pos; + match_offset = (Pos)i; + } + } + /* Switch cur_match to next_pos chain */ + cur_match = next_pos; + + /* Try hash head at len-(STD_MIN_MATCH-1) position to see if we could get + * a better cur_match at the end of string. Using (STD_MIN_MATCH-1) lets + * us include one more byte into hash - the byte which will be checked + * in main loop now, and which allows to grow match by 1. + */ + scan_endstr = scan + len - (STD_MIN_MATCH+1); + + hash = s->update_hash(s, 0, scan_endstr[0]); + hash = s->update_hash(s, hash, scan_endstr[1]); + hash = s->update_hash(s, hash, scan_endstr[2]); + + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(len - (STD_MIN_MATCH+1)); + if (pos <= limit_base + match_offset) + goto break_matching; + cur_match = pos; + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + mbase_start = window-match_offset; + mbase_end = (mbase_start+offset); + continue; + } +#endif + mbase_end = (mbase_start+offset); + } +#ifndef LONGEST_MATCH_SLOW + else if (UNLIKELY(early_exit)) { + /* The probability of finding a match later if we here is pretty low, so for + * performance it's best to outright stop here for the lower compression levels + */ + break; + } +#endif + GOTO_NEXT_CHAIN; + } + return best_len; + +#ifdef LONGEST_MATCH_SLOW +break_matching: + + if (best_len < s->lookahead) + return best_len; + + return s->lookahead; +#endif +} + +#undef LONGEST_MATCH_SLOW +#undef LONGEST_MATCH +#undef COMPARE256 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/slide_hash.c b/internal-complibs/zlib-ng-2.1.1-beta2/slide_hash.c new file mode 100644 index 000000000..b9fbbdb69 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/slide_hash.c @@ -0,0 +1,52 @@ +/* slide_hash.c -- slide hash table C implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +static inline void slide_hash_c_chain(Pos *table, uint32_t entries, uint16_t wsize) { +#ifdef NOT_TWEAK_COMPILER + table += entries; + do { + unsigned m; + m = *--table; + *table = (Pos)(m >= wsize ? m-wsize : 0); + /* If entries is not on any hash chain, prev[entries] is garbage but + * its value will never be used. + */ + } while (--entries); +#else + { + /* As of I make this change, gcc (4.8.*) isn't able to vectorize + * this hot loop using saturated-subtraction on x86-64 architecture. + * To avoid this defect, we can change the loop such that + * o. the pointer advance forward, and + * o. demote the variable 'm' to be local to the loop, and + * choose type "Pos" (instead of 'unsigned int') for the + * variable to avoid unnecessary zero-extension. + */ + unsigned int i; + Pos *q = table; + for (i = 0; i < entries; i++) { + Pos m = *q; + Pos t = (Pos)wsize; + *q++ = (Pos)(m >= t ? m-t: 0); + } + } +#endif /* NOT_TWEAK_COMPILER */ +} + +Z_INTERNAL void slide_hash_c(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + + slide_hash_c_chain(s->head, HASH_SIZE, wsize); + slide_hash_c_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/.gitignore b/internal-complibs/zlib-ng-2.1.1-beta2/test/.gitignore new file mode 100644 index 000000000..96a3cad07 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/.gitignore @@ -0,0 +1,5 @@ +# ignore Makefiles; they're all automatically generated +Makefile +/switchlevels +/switchlevels.dSYM/ +/switchlevels.exe diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/CMakeLists.txt new file mode 100644 index 000000000..d434ec308 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/CMakeLists.txt @@ -0,0 +1,257 @@ +cmake_minimum_required(VERSION 3.5.1) + +macro(configure_test_executable target) + target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}) + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + if(NOT WITH_GZFILEOP) + target_compile_definitions(${target} PRIVATE -DWITH_GZFILEOP) + target_sources(${target} PRIVATE ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) + endif() +endmacro() + +if(ZLIBNG_ENABLE_TESTS) + add_definitions(-DZLIBNG_ENABLE_TESTS) +endif() + +add_executable(example example.c) +configure_test_executable(example) +target_link_libraries(example zlib) +add_test(NAME example COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minigzip minigzip.c) +configure_test_executable(minigzip) +if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(minigzip zlibstatic) +else() + target_link_libraries(minigzip zlib) +endif() +if(BASEARCH_S360_FOUND) + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + set_source_files_properties(minigzip.c PROPERTIES COMPILE_DEFINITIONS BUFLEN=262144) + endif() +endif() +set(MINIGZIP_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minideflate minideflate.c) +configure_test_executable(minideflate) +target_link_libraries(minideflate zlib) +set(MINIDEFLATE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +if(INSTALL_UTILS) + install(TARGETS minigzip minideflate + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() + +add_executable(switchlevels switchlevels.c) +configure_test_executable(switchlevels) +target_link_libraries(switchlevels zlib) +set(SWITCHLEVELS_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(infcover infcover.c) +configure_test_executable(infcover) +target_link_libraries(infcover zlib) +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + target_sources(infcover PRIVATE ${PROJECT_SOURCE_DIR}/inftrees.c) +endif() +# infcover references zng_inflate_table() and struct inflate_state, which are internal to zlib-ng. +if(ZLIBNG_ENABLE_TESTS) + add_test(NAME infcover COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +add_executable(makefixed ${PROJECT_SOURCE_DIR}/tools/makefixed.c ${PROJECT_SOURCE_DIR}/inftrees.c) +configure_test_executable(makefixed) +set(MAKEFIXED_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(maketrees ${PROJECT_SOURCE_DIR}/tools/maketrees.c ${PROJECT_SOURCE_DIR}/trees.c ${PROJECT_SOURCE_DIR}/zutil.c) +configure_test_executable(maketrees) +set(MAKETREES_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(makecrct ${PROJECT_SOURCE_DIR}/tools/makecrct.c) +configure_test_executable(makecrct) +set(MAKECRCT_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if(NOT BASEARCH_WASM32_FOUND) + # Runs tests targeting CVEs + include(cmake/test-cves.cmake) + + # Run tests with data files + include(cmake/test-data.cmake) + + # Run tests targeting GitHub issues + include(cmake/test-issues.cmake) + + # Run tests targeting tools + include(cmake/test-tools.cmake) +endif() + +if(WITH_FUZZERS) + add_subdirectory(fuzz) +endif() + +if(WITH_GTEST OR WITH_BENCHMARKS) + if(CMAKE_VERSION VERSION_LESS 3.12) + message(WARNING "Minimum cmake version of 3.12 not met for GoogleTest or benchmarks!") + + set(WITH_GTEST OFF) + set(WITH_GTEST OFF PARENT_SCOPE) + + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARKS OFF PARENT_SCOPE) + else() + enable_language(CXX) + endif() +endif() + +if(WITH_BENCHMARKS) + add_subdirectory(benchmarks) +endif() + +if(WITH_GTEST) + include(FetchContent) + + # Google test requires at least C++11 + set(CMAKE_CXX_STANDARD 11) + + # Google test requires MSAN instrumented LLVM C++ libraries + if(WITH_SANITIZER STREQUAL "Memory") + if(NOT DEFINED ENV{LLVM_BUILD_DIR}) + message(FATAL_ERROR "MSAN instrumented C++ libraries required!") + endif() + + # Must set include and compile options before fetching googletest + include_directories($ENV{LLVM_BUILD_DIR}/include $ENV{LLVM_BUILD_DIR}/include/c++/v1) + add_compile_options(-stdlib=libc++ -g) + endif() + + if(NOT TARGET GTest::GTest) + # Prevent overriding the parent project's compiler/linker settings for Windows + set(gtest_force_shared_crt ON CACHE BOOL + "Use shared (DLL) run-time lib even when Google Test is built as static lib." FORCE) + + # Allow specifying alternative Google test repository + if(NOT DEFINED GTEST_REPOSITORY) + set(GTEST_REPOSITORY https://github.com/google/googletest.git) + endif() + if(NOT DEFINED GTEST_TAG) + # Use older version of Google test to support older versions of GCC + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.3) + set(GTEST_TAG release-1.10.0) + else() + set(GTEST_TAG release-1.11.0) + endif() + endif() + + # Fetch Google test source code from official repository + FetchContent_Declare(googletest + GIT_REPOSITORY ${GTEST_REPOSITORY} + GIT_TAG ${GTEST_TAG}) + + FetchContent_GetProperties(googletest) + if(NOT googletest_POPULATED) + FetchContent_Populate(googletest) + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() + add_library(GTest::GTest ALIAS gtest) + add_library(GTest::Main ALIAS gtest_main) + endif() + + set(TEST_SRCS + test_compress.cc + test_compress_bound.cc + test_cve-2003-0107.cc + test_deflate_bound.cc + test_deflate_copy.cc + test_deflate_dict.cc + test_deflate_hash_head_0.cc + test_deflate_header.cc + test_deflate_params.cc + test_deflate_pending.cc + test_deflate_prime.cc + test_deflate_quick_bi_valid.cc + test_deflate_quick_block_open.cc + test_deflate_tune.cc + test_dict.cc + test_inflate_adler32.cc + test_large_buffers.cc + test_raw.cc + test_small_buffers.cc + test_small_window.cc + ) + + if(WITH_GZFILEOP) + list(APPEND TEST_SRCS test_gzio.cc) + endif() + + if(ZLIBNG_ENABLE_TESTS) + list(APPEND TEST_SRCS + test_adler32.cc # adler32_neon(), etc + test_aligned_alloc.cc # zng_alloc_aligned() + test_compare256.cc # compare256_neon(), etc + test_crc32.cc # crc32_acle(), etc + test_inflate_sync.cc # expects a certain compressed block layout + test_main.cc # cpu_check_features() + test_version.cc # expects a fixed version string + ) + endif() + + add_executable(gtest_zlib ${TEST_SRCS}) + configure_test_executable(gtest_zlib) + + if(WITH_SANITIZER STREQUAL "Memory") + target_link_directories(gtest_zlib PRIVATE $ENV{LLVM_BUILD_DIR}/lib) + target_link_options(gtest_zlib PRIVATE + -stdlib=libc++ + -lc++abi + -fsanitize=memory + -fsanitize-memory-track-origins) + endif() + + if(NOT ZLIB_COMPAT AND DEFINED ZLIB_LIBRARIES AND DEFINED ZLIB_INCLUDE_DIRS) + if(NOT IS_ABSOLUTE ${ZLIB_LIBRARIES}) + get_filename_component(ZLIB_ABSOLUTE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_LIBRARIES}" + ABSOLUTE) + else() + set(ZLIB_ABSOLUTE_PATH ${ZLIB_LIBRARIES}) + endif() + + add_library(external_zlib STATIC IMPORTED) + set_property(TARGET external_zlib PROPERTY IMPORTED_LOCATION ${ZLIB_ABSOLUTE_PATH}) + message(STATUS "Added dual linking tests against zlib") + message(STATUS " Zlib include dirs: ${ZLIB_INCLUDE_DIRS}") + message(STATUS " Zlib libraries: ${ZLIB_ABSOLUTE_PATH}") + + target_sources(gtest_zlib PRIVATE test_compress_dual.cc) + target_include_directories(gtest_zlib PRIVATE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(gtest_zlib external_zlib) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + # Link statically in order to test internal zlib-ng functions. + target_link_libraries(gtest_zlib zlibstatic) + else() + target_link_libraries(gtest_zlib zlib) + endif() + + if(BUILD_SHARED_LIBS) + target_link_libraries(gtest_zlib GTest::Main) + endif() + target_link_libraries(gtest_zlib GTest::GTest) + + find_package(Threads) + if(Threads_FOUND AND NOT BASEARCH_WASM32_FOUND) + target_sources(gtest_zlib PRIVATE test_deflate_concurrency.cc) + if(UNIX AND NOT APPLE) + # On Linux, use a workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 + target_link_libraries(gtest_zlib -Wl,--whole-archive -lpthread -Wl,--no-whole-archive) + endif() + target_link_libraries(gtest_zlib Threads::Threads) + endif() + + add_test(NAME gtest_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2002-0059/test.gz b/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2002-0059/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..c5c3e184b1a90692f1c2dc729eb106476d231378 GIT binary patch literal 4610 zcmb2|=3oE==C>CV8G$T;1@EN)&o6EfRlAUMpn;K@jYq;DVU#f%2%{-sG#8BKg3(+s vnhQpA!DucR%>|>mU^Ewu=7P~&Fq#WSbHQjX7-G5L2bCV85!7kBn%P`G%zxAfEl}iz!@q6kpjs906!lM=l}o! literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-1849/test.gz b/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-1849/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..b28f278263c0a3154faeb3c3dd7b083a3a593c8d GIT binary patch literal 52 kcmb2|=3oE==C@ZA85!7kBn%P`G%zxAz!-252m>Ss01LtkQvd(} literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-2096/test.gz b/internal-complibs/zlib-ng-2.1.1-beta2/test/CVE-2005-2096/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..11590aeab9ac844087776ab66eb2f5d2c9f6d013 GIT binary patch literal 52 pcmb2|=3oE==C>CV84oltGP4!m+X9 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-382/defneg3.dat b/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-382/defneg3.dat new file mode 100644 index 000000000..5fa6a0804 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-382/defneg3.dat @@ -0,0 +1 @@ +oÌ™Ì?ÌOÌÃÌḩÌÕÌ>ÌÌÌàÌ̹̘ÌÔÌEÌsÌ—ÌÌ4̢̙̑Ì6ÌÌØÌæÌ\ÌÌÌ5̪̲̕ÌmÌÌ–Ìç̺̜ÌÙ̧ÌÌíÌíÌ–ÌÌëÌmÌìÌÎ̵ÌGÌïÌOÌÛÌ ÌÃÌòÌÎÌôÌ„Ì;Ì”ÌýÌ’ÌÓÌÀÌ×Ì,ÌÑÌ¢ÌáÌAÌ9Ì»ÌæÌ‚ÌÂÌsÌý̼ÌÝÌÌ­ÌeÌòÌÝÌUÌuÌí̱ÌËÌwÌùÌ•ÌDÌß̋̽Ìt̞̣̹ÌöÌôÌOÌîÌíÌ…ÌpÌGÌìÌ°ÌÀÌ(ÌÌÌ̤Ì{Ì“ÌßÌïÌÕÌÌøÌÌMÌ#ÌÌí̵ÌdÌ·ÌIÌßÌhÌ_ÌpÌJÌÇÌ¢ÌÎÌÌoÌÌêÌÁÌ;Ì<̘ÌZÌÈÌÑÌoÌWÌ„Ì¿Ì}ÌáÌÌÌ:Ìá̧̻̕ÌeÌFÌtÌ(ÌEÌoÌàÌpÌÌ¢Ì(Ì;ÌþÌëÌóÌ!̹̹ÌÉÌÌœÌîÌÖÌ4ÌÈÌ3ÌëÌ‹ÌBÌŽÌÆÌuÌPÌ6Ì“ÌþÌ&̦̳̕ÌÁÌðÌ»ÌÌÌTÌÀ̧ÌbÌÌÒÌÕÌëÌ{ÌÆÌ¡ÌÊÌNÌ9ÌÇÌÌBÌÑ \ No newline at end of file diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-751/test.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-751/test.txt new file mode 100644 index 000000000..ef2143ece --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-751/test.txt @@ -0,0 +1 @@ +abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-979/pigz-2.6.tar.gz b/internal-complibs/zlib-ng-2.1.1-beta2/test/GH-979/pigz-2.6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0d76ef8757e36dc5ab02e579a99442c211b6d978 GIT binary patch literal 106840 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 z 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%0A!*@!_1l*%gn{T*uEUOk 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

    TW z_IDONo{|>HAW1G>TyRtpbmwk{?E;Qe^keeoFsDM3S=2db6)SXNcKE5%&&Ar#_N zpb@o8hS`1wgDDbLa&s+bs8dLKx3^4*zmN|i^7+?GCYx*0-1L2GVTM3%-hPWrrhz0e zbXNHB3HfPmGwCS)c;aGu`*;sb-s8nk=U{GPS59ihrvy=D!4Vx`q}533<6z$ck`Pyq z#Wp|O#O4)elSw*QD!!Er{iJ0~8m2>w=uzx@uM&gU0r$C!=YYmjU1aUBHf`trIflpm zFq{>9Y%Ab4N$mgk2oo{wij86SPzFIw|MoSMh>+=?vK%06Ri5?N6y32 zPWFhl#BhsY+gB&zX;_uy28Xzn@#4NH&UCg_=suUja2QPKb-V!m%U6KxcfYDXI(>KVeZLk1dpU8 zJ(yC4l)g7U9lQo+6a{OuE#k*r-jT#E>0I?o6F>I7yPufUqKPKv}ds~3-?2-x{@=kJ>}nO93O zI3+2XM938mPr#0cVU!2=Wwm_oC}TP=y|_@ywlY%`>@9xa$lSI=tkviJnbecM0g6D; z#gnR7xopbk>jjl(OpGP8cT&dDJ^}*|cYn&W;+mV3&0>yf)w#>nwHu1yokd8ym zQAEeQj_R{r_lrFHT8M}S83BAw2~OKeB5i}Q1uX)2R?d&}r0rzF4H>KEf;v|b}({Pj53@@LXZ!rbM&_B91^_?a$7^_jgH z_D&VwOkJ-?ckMq0-)0KKW|}6YyN3ro2heX%gbj1Kpnk|b734y1tAZb=i8QY5bMHOC zbUYV^l|Rp`f6{L!GWTHZr zoJeOTZ>=xYHk|0I*rr{Y?@X3*1y^kuJ3YGuir-S?3uMz24JJ&d@LXC^AIqx2430Mw zxhP8Ewks}5ddx7a%H&Pkvbe{q+$Hm?zRF9aZnQP@uchGsl#Cc}$!-uw4xA^8 zJTo>TdPw1Sw;2$~;fGv{;q(+?rngoV%qxM9sMp!{!D53t zHYX@;Z65KdeOE|7NY41K;ryCh*ITJZc-|E5k=47tbg`vkV>v}>cYd6|SMWCm>(jj> z(Y-IP3MMF`@7?wsDi;HW<_vO~T(l=k={JY>LsPax4pbFHZ{$NzksGQkw&_C{BRM

    ?-Y#xg4rj7}S3taUTj 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

    {LABC35aZ+t^w!fb%kfniC0^^)fHUEz8(f& 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 Cetk@ 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

  • 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 z. + +Abstract + + This specification defines a lossless compressed data format. The + data can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a priori + bounded amount of intermediate storage. The format presently uses + the DEFLATE compression method but can be easily extended to use + other compression methods. It can be implemented readily in a manner + not covered by patents. This specification also defines the ADLER-32 + checksum (an extension and improvement of the Fletcher checksum), + used for detection of data corruption, and provides an algorithm for + computing it. + + + + +Deutsch & Gailly Informational [Page 1] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 3 + 2.1. Overall conventions ....................................... 3 + 2.2. Data format ............................................... 4 + 2.3. Compliance ................................................ 7 + 3. References ..................................................... 7 + 4. Source code .................................................... 8 + 5. Security Considerations ........................................ 8 + 6. Acknowledgements ............................................... 8 + 7. Authors' Addresses ............................................. 8 + 8. Appendix: Rationale ............................................ 9 + 9. Appendix: Sample code ..........................................10 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence can + be used in data communications or similar structures such as + Unix filters; + + * Can use a number of different compression methods; + + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely. + + The data format defined by this specification does not attempt to + allow random access to compressed data. + + + + + + + +Deutsch & Gailly Informational [Page 2] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into zlib format and/or decompress data from zlib + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compressed data format that can be + used for in-memory compression of a sequence of arbitrary bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below, for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + Version 3.1 was the first public release of this specification. + In version 3.2, some terminology was changed and the Adler-32 + sample code was rewritten for clarity. In version 3.3, the + support for a preset dictionary was introduced, and the + specification was converted to RFC style. + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + + + +Deutsch & Gailly Informational [Page 3] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the MOST-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00000010|00001000| + +--------+--------+ + ^ ^ + | | + | + less significant byte = 8 + + more significant byte = 2 x 256 + + 2.2. Data format + + A zlib stream has the following structure: + + 0 1 + +---+---+ + |CMF|FLG| (more-->) + +---+---+ + + + + + + + + +Deutsch & Gailly Informational [Page 4] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + (if FLG.FDICT set) + + 0 1 2 3 + +---+---+---+---+ + | DICTID | (more-->) + +---+---+---+---+ + + +=====================+---+---+---+---+ + |...compressed data...| ADLER32 | + +=====================+---+---+---+---+ + + Any data which may appear after ADLER32 are not part of the zlib + stream. + + CMF (Compression Method and flags) + This byte is divided into a 4-bit compression method and a 4- + bit information field depending on the compression method. + + bits 0 to 3 CM Compression method + bits 4 to 7 CINFO Compression info + + CM (Compression method) + This identifies the compression method used in the file. CM = 8 + denotes the "deflate" compression method with a window size up + to 32K. This is the method used by gzip and PNG (see + references [1] and [2] in Chapter 3, below, for the reference + documents). CM = 15 is reserved. It might be used in a future + version of this specification to indicate the presence of an + extra field before the compressed data. + + CINFO (Compression info) + For CM = 8, CINFO is the base-2 logarithm of the LZ77 window + size, minus eight (CINFO=7 indicates a 32K window size). Values + of CINFO above 7 are not allowed in this version of the + specification. CINFO is not defined in this specification for + CM not equal to 8. + + FLG (FLaGs) + This flag byte is divided as follows: + + bits 0 to 4 FCHECK (check bits for CMF and FLG) + bit 5 FDICT (preset dictionary) + bits 6 to 7 FLEVEL (compression level) + + The FCHECK value must be such that CMF and FLG, when viewed as + a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG), + is a multiple of 31. + + + + +Deutsch & Gailly Informational [Page 5] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + FDICT (Preset dictionary) + If FDICT is set, a DICT dictionary identifier is present + immediately after the FLG byte. The dictionary is a sequence of + bytes which are initially fed to the compressor without + producing any compressed output. DICT is the Adler-32 checksum + of this sequence of bytes (see the definition of ADLER32 + below). The decompressor can use this identifier to determine + which dictionary has been used by the compressor. + + FLEVEL (Compression level) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + 0 - compressor used fastest algorithm + 1 - compressor used fast algorithm + 2 - compressor used default algorithm + 3 - compressor used maximum compression, slowest algorithm + + The information in FLEVEL is not needed for decompression; it + is there to indicate if recompression might be worthwhile. + + compressed data + For compression method 8, the compressed data is stored in the + deflate compressed data format as described in the document + "DEFLATE Compressed Data Format Specification" by L. Peter + Deutsch. (See reference [3] in Chapter 3, below) + + Other compressed data formats are not specified in this version + of the zlib specification. + + ADLER32 (Adler-32 checksum) + This contains a checksum value of the uncompressed data + (excluding any dictionary data) computed according to Adler-32 + algorithm. This algorithm is a 32-bit extension and improvement + of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073 + standard. See references [4] and [5] in Chapter 3, below) + + Adler-32 is composed of two sums accumulated per byte: s1 is + the sum of all bytes, s2 is the sum of all s1 values. Both sums + are done modulo 65521. s1 is initialized to 1, s2 to zero. The + Adler-32 checksum is stored as s2*65536 + s1 in most- + significant-byte first (network) order. + + + + + + + + +Deutsch & Gailly Informational [Page 6] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + 2.3. Compliance + + A compliant compressor must produce streams with correct CMF, FLG + and ADLER32, but need not support preset dictionaries. When the + zlib data format is used as part of another standard data format, + the compressor may use only preset dictionaries that are specified + by this other data format. If this other format does not use the + preset dictionary feature, the compressor must not set the FDICT + flag. + + A compliant decompressor must check CMF, FLG, and ADLER32, and + provide an error indication if any of these have incorrect values. + A compliant decompressor must give an error indication if CM is + not one of the values defined in this specification (only the + value 8 is permitted in this version), since another value could + indicate the presence of new features that would cause subsequent + data to be interpreted incorrectly. A compliant decompressor must + give an error indication if FDICT is set and DICTID is not the + identifier of a known preset dictionary. A decompressor may + ignore FLEVEL and still be compliant. When the zlib data format + is being used as a part of another standard format, a compliant + decompressor must support all the preset dictionaries specified by + the other format. When the other format does not use the preset + dictionary feature, a compliant decompressor must reject any + stream in which the FDICT flag is set. + +3. References + + [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [2] Thomas Boutell, "PNG (Portable Network Graphics) specification", + available in ftp://ftp.uu.net/graphics/png/documents/ + + [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Fletcher, J. G., "An Arithmetic Checksum for Serial + Transmissions," IEEE Transactions on Communications, Vol. COM-30, + No. 1, January 1982, pp. 247-252. + + [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms," + November, 1993, pp. 144, 145. (Available from + gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073. + + + + + + + +Deutsch & Gailly Informational [Page 7] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +4. Source code + + Source code for a C language implementation of a "zlib" compliant + library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +5. Security Considerations + + A decoder that fails to check the ADLER32 checksum value may be + subject to undetected data corruption. + +6. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly and Mark Adler designed the zlib format and wrote + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +7. Authors' Addresses + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + + Jean-Loup Gailly + + EMail: + + Questions about the technical content of this specification can be + sent by email to + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + +Deutsch & Gailly Informational [Page 8] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +8. Appendix: Rationale + + 8.1. Preset dictionaries + + A preset dictionary is specially useful to compress short input + sequences. The compressor can take advantage of the dictionary + context to encode the input in a more compact manner. The + decompressor can be initialized with the appropriate context by + virtually decompressing a compressed version of the dictionary + without producing any output. However for certain compression + algorithms such as the deflate algorithm this operation can be + achieved without actually performing any decompression. + + The compressor and the decompressor must use exactly the same + dictionary. The dictionary may be fixed or may be chosen among a + certain number of predefined dictionaries, according to the kind + of input data. The decompressor can determine which dictionary has + been chosen by the compressor by checking the dictionary + identifier. This document does not specify the contents of + predefined dictionaries, since the optimal dictionaries are + application specific. Standard data formats using this feature of + the zlib specification must precisely define the allowed + dictionaries. + + 8.2. The Adler-32 algorithm + + The Adler-32 algorithm is much faster than the CRC32 algorithm yet + still provides an extremely low probability of undetected errors. + + The modulo on unsigned long accumulators can be delayed for 5552 + bytes, so the modulo operation time is negligible. If the bytes + are a, b, c, the second sum is 3a + 2b + c + 3, and so is position + and order sensitive, unlike the first sum, which is just a + checksum. That 65521 is prime is important to avoid a possible + large class of two-byte errors that leave the check unchanged. + (The Fletcher checksum uses 255, which is not prime and which also + makes the Fletcher check insensitive to single byte changes 0 <-> + 255.) + + The sum s1 is initialized to 1 instead of zero to make the length + of the sequence part of s2, so that the length does not have to be + checked separately. (Any sequence of zeroes has a Fletcher + checksum of zero.) + + + + + + + + +Deutsch & Gailly Informational [Page 9] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + +9. Appendix: Sample code + + The following C code computes the Adler-32 checksum of a data buffer. + It is written for clarity, not for speed. The sample code is in the + ANSI C programming language. Non C users may find it easier to read + with these hints: + + & Bitwise AND operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero bit(s) + at the left. + << Bitwise left shift operator. Left shift inserts zero + bit(s) at the right. + ++ "n++" increments the variable n. + % modulo operator: a % b is the remainder of a divided by b. + + #define BASE 65521 /* largest prime smaller than 65536 */ + + /* + Update a running Adler-32 checksum with the bytes buf[0..len-1] + and return the updated checksum. The Adler-32 checksum should be + initialized to 1. + + Usage example: + + unsigned long adler = 1L; + + while (read_buffer(buffer, length) != EOF) { + adler = update_adler32(adler, buffer, length); + } + if (adler != original_adler) error(); + */ + unsigned long update_adler32(unsigned long adler, + unsigned char *buf, int len) + { + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int n; + + for (n = 0; n < len; n++) { + s1 = (s1 + buf[n]) % BASE; + s2 = (s2 + s1) % BASE; + } + return (s2 << 16) + s1; + } + + /* Return the adler32 of the bytes buf[0..len-1] */ + + + + +Deutsch & Gailly Informational [Page 10] + +RFC 1950 ZLIB Compressed Data Format Specification May 1996 + + + unsigned long adler32(unsigned char *buf, int len) + { + return update_adler32(1L, buf, len); + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch & Gailly Informational [Page 11] + diff --git a/internal-complibs/zlib-ng-2.1.2/doc/rfc1951.txt b/internal-complibs/zlib-ng-2.1.2/doc/rfc1951.txt new file mode 100644 index 000000000..403c8c722 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/doc/rfc1951.txt @@ -0,0 +1,955 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1951 Aladdin Enterprises +Category: Informational May 1996 + + + DEFLATE Compressed Data Format Specification version 1.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that + compresses data using a combination of the LZ77 algorithm and Huffman + coding, with efficiency comparable to the best currently available + general-purpose compression methods. The data can be produced or + consumed, even for an arbitrarily long sequentially presented input + data stream, using only an a priori bounded amount of intermediate + storage. The format can be implemented readily in a manner not + covered by patents. + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................ 3 + 1.6. Changes from previous versions ............................ 4 + 2. Compressed representation overview ............................. 4 + 3. Detailed specification ......................................... 5 + 3.1. Overall conventions ....................................... 5 + 3.1.1. Packing into bytes .................................. 5 + 3.2. Compressed block format ................................... 6 + 3.2.1. Synopsis of prefix and Huffman coding ............... 6 + 3.2.2. Use of Huffman coding in the "deflate" format ....... 7 + 3.2.3. Details of block format ............................. 9 + 3.2.4. Non-compressed blocks (BTYPE=00) ................... 11 + 3.2.5. Compressed blocks (length and distance codes) ...... 11 + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12 + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13 + 3.3. Compliance ............................................... 14 + 4. Compression algorithm details ................................. 14 + 5. References .................................................... 16 + 6. Security Considerations ....................................... 16 + 7. Source code ................................................... 16 + 8. Acknowledgements .............................................. 16 + 9. Author's Address .............................................. 17 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can be produced or consumed, even for an arbitrarily long + sequentially presented input data stream, using only an a + priori bounded amount of intermediate storage, and hence + can be used in data communications or similar structures + such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + + + +Deutsch Informational [Page 2] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + The data format defined by this specification does not attempt to: + + * Allow random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well + as the best currently available specialized algorithms. + + A simple counting argument shows that no lossless compression + algorithm can compress every possible input data set. For the + format defined here, the worst case expansion is 5 bytes per 32K- + byte block, i.e., a size increase of 0.015% for large data sets. + English text usually compresses by a factor of 2.5 to 3; + executable files usually compress somewhat less; graphical data + such as raster images may compress much more. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into "deflate" format and/or decompress data from + "deflate" format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. Familiarity with the technique of Huffman coding + is helpful but not required. + + 1.3. Scope + + The specification specifies a method for representing a sequence + of bytes as a (usually shorter) sequence of bits, and a method for + packing the latter bit sequence into bytes. + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any data set that conforms to all + the specifications presented here; a compliant compressor must + produce data sets that conform to all the specifications presented + here. + + 1.5. Definitions of terms and conventions used + + Byte: 8 bits stored or transmitted as a unit (same as an octet). + For this specification, a byte is exactly 8 bits, even on machines + + + +Deutsch Informational [Page 3] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + which store a character on a number of bits different from eight. + See below, for the numbering of bits within a byte. + + String: a sequence of arbitrary bytes. + + 1.6. Changes from previous versions + + There have been no technical changes to the deflate format since + version 1.1 of this specification. In version 1.2, some + terminology was changed. Version 1.3 is a conversion of the + specification to RFC style. + +2. Compressed representation overview + + A compressed data set consists of a series of blocks, corresponding + to successive blocks of input data. The block sizes are arbitrary, + except that non-compressible blocks are limited to 65,535 bytes. + + Each block is compressed using a combination of the LZ77 algorithm + and Huffman coding. The Huffman trees for each block are independent + of those for previous or subsequent blocks; the LZ77 algorithm may + use a reference to a duplicated string occurring in a previous block, + up to 32K input bytes before. + + Each block consists of two parts: a pair of Huffman code trees that + describe the representation of the compressed data part, and a + compressed data part. (The Huffman trees themselves are compressed + using Huffman encoding.) The compressed data consists of a series of + elements of two types: literal bytes (of strings that have not been + detected as duplicated within the previous 32K input bytes), and + pointers to duplicated strings, where a pointer is represented as a + pair . The representation used in the + "deflate" format limits distances to 32K bytes and lengths to 258 + bytes, but does not limit the size of a block, except for + uncompressible blocks, which are limited as noted above. + + Each type of value (literals, distances, and lengths) in the + compressed data is represented using a Huffman code, using one code + tree for literals and lengths and a separate code tree for distances. + The code trees for each block appear in a compact form just before + the compressed data for that block. + + + + + + + + + + +Deutsch Informational [Page 4] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +3. Detailed specification + + 3.1. Overall conventions In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + 3.1.1. Packing into bytes + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, + since the final data format described here is byte- rather than + + + +Deutsch Informational [Page 5] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + bit-oriented. However, we describe the compressed block format + in below, as a sequence of data elements of various bit + lengths, not a sequence of bytes. We must therefore specify + how to pack these data elements into bytes to form the final + compressed byte sequence: + + * Data elements are packed into bytes in order of + increasing bit number within the byte, i.e., starting + with the least-significant bit of the byte. + * Data elements other than Huffman codes are packed + starting with the least-significant bit of the data + element. + * Huffman codes are packed starting with the most- + significant bit of the code. + + In other words, if one were to print out the compressed data as + a sequence of bytes, starting with the first byte at the + *right* margin and proceeding to the *left*, with the most- + significant bit of each byte on the left as usual, one would be + able to parse the result from right to left, with fixed-width + elements in the correct MSB-to-LSB order and Huffman codes in + bit-reversed order (i.e., with the first bit of the code in the + relative LSB position). + + 3.2. Compressed block format + + 3.2.1. Synopsis of prefix and Huffman coding + + Prefix coding represents symbols from an a priori known + alphabet by bit sequences (codes), one code for each symbol, in + a manner such that different symbols may be represented by bit + sequences of different lengths, but a parser can always parse + an encoded string unambiguously symbol-by-symbol. + + We define a prefix code in terms of a binary tree in which the + two edges descending from each non-leaf node are labeled 0 and + 1 and in which the leaf nodes correspond one-for-one with (are + labeled with) the symbols of the alphabet; then the code for a + symbol is the sequence of 0's and 1's on the edges leading from + the root to the leaf labeled with that symbol. For example: + + + + + + + + + + + +Deutsch Informational [Page 6] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + /\ Symbol Code + 0 1 ------ ---- + / \ A 00 + /\ B B 1 + 0 1 C 011 + / \ D 010 + A /\ + 0 1 + / \ + D C + + A parser can decode the next symbol from an encoded input + stream by walking down the tree from the root, at each step + choosing the edge corresponding to the next input bit. + + Given an alphabet with known symbol frequencies, the Huffman + algorithm allows the construction of an optimal prefix code + (one which represents strings with those symbol frequencies + using the fewest bits of any possible prefix codes for that + alphabet). Such a code is called a Huffman code. (See + reference [1] in Chapter 5, references for additional + information on Huffman codes.) + + Note that in the "deflate" format, the Huffman codes for the + various alphabets must not exceed certain maximum code lengths. + This constraint complicates the algorithm for computing code + lengths from symbol frequencies. Again, see Chapter 5, + references for details. + + 3.2.2. Use of Huffman coding in the "deflate" format + + The Huffman codes used for each alphabet in the "deflate" + format have two additional rules: + + * All codes of a given bit length have lexicographically + consecutive values, in the same order as the symbols + they represent; + + * Shorter codes lexicographically precede longer codes. + + + + + + + + + + + + +Deutsch Informational [Page 7] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + We could recode the example above to follow this rule as + follows, assuming that the order of the alphabet is ABCD: + + Symbol Code + ------ ---- + A 10 + B 0 + C 110 + D 111 + + I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are + lexicographically consecutive. + + Given this rule, we can define the Huffman code for an alphabet + just by giving the bit lengths of the codes for each symbol of + the alphabet in order; this is sufficient to determine the + actual codes. In our example, the code is completely defined + by the sequence of bit lengths (2, 1, 3, 3). The following + algorithm generates the codes as integers, intended to be read + from most- to least-significant bit. The code lengths are + initially in tree[I].Len; the codes are produced in + tree[I].Code. + + 1) Count the number of codes for each code length. Let + bl_count[N] be the number of codes of length N, N >= 1. + + 2) Find the numerical value of the smallest code for each + code length: + + code = 0; + bl_count[0] = 0; + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = code; + } + + 3) Assign numerical values to all codes, using consecutive + values for all codes of the same length with the base + values determined at step 2. Codes that are never used + (which have a bit length of zero) must not be assigned a + value. + + for (n = 0; n <= max_code; n++) { + len = tree[n].Len; + if (len != 0) { + tree[n].Code = next_code[len]; + next_code[len]++; + } + + + +Deutsch Informational [Page 8] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + } + + Example: + + Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3, + 3, 2, 4, 4). After step 1, we have: + + N bl_count[N] + - ----------- + 2 1 + 3 5 + 4 2 + + Step 2 computes the following next_code values: + + N next_code[N] + - ------------ + 1 0 + 2 0 + 3 2 + 4 14 + + Step 3 produces the following code values: + + Symbol Length Code + ------ ------ ---- + A 3 010 + B 3 011 + C 3 100 + D 3 101 + E 3 110 + F 2 00 + G 4 1110 + H 4 1111 + + 3.2.3. Details of block format + + Each block of compressed data begins with 3 header bits + containing the following data: + + first bit BFINAL + next 2 bits BTYPE + + Note that the header bits do not necessarily begin on a byte + boundary, since a block does not necessarily occupy an integral + number of bytes. + + + + + +Deutsch Informational [Page 9] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + BFINAL is set if and only if this is the last block of the data + set. + + BTYPE specifies how the data are compressed, as follows: + + 00 - no compression + 01 - compressed with fixed Huffman codes + 10 - compressed with dynamic Huffman codes + 11 - reserved (error) + + The only difference between the two compressed cases is how the + Huffman codes for the literal/length and distance alphabets are + defined. + + In all cases, the decoding algorithm for the actual data is as + follows: + + do + read block header from input stream. + if stored with no compression + skip any remaining bits in current partially + processed byte + read LEN and NLEN (see next section) + copy LEN bytes of data to output + otherwise + if compressed with dynamic Huffman codes + read representation of code trees (see + subsection below) + loop (until end of block code recognized) + decode literal/length value from input stream + if value < 256 + copy value (literal byte) to output stream + otherwise + if value = end of block (256) + break from loop + otherwise (value = 257..285) + decode distance from input stream + + move backwards distance bytes in the output + stream, and copy length bytes from this + position to the output stream. + end loop + while not last block + + Note that a duplicated string reference may refer to a string + in a previous block; i.e., the backward distance may cross one + or more block boundaries. However a distance cannot refer past + the beginning of the output stream. (An application using a + + + +Deutsch Informational [Page 10] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + preset dictionary might discard part of the output stream; a + distance can refer to that part of the output stream anyway) + Note also that the referenced string may overlap the current + position; for example, if the last 2 bytes decoded have values + X and Y, a string reference with + adds X,Y,X,Y,X to the output stream. + + We now specify each compression method in turn. + + 3.2.4. Non-compressed blocks (BTYPE=00) + + Any bits of input up to the next byte boundary are ignored. + The rest of the block consists of the following information: + + 0 1 2 3 4... + +---+---+---+---+================================+ + | LEN | NLEN |... LEN bytes of literal data...| + +---+---+---+---+================================+ + + LEN is the number of data bytes in the block. NLEN is the + one's complement of LEN. + + 3.2.5. Compressed blocks (length and distance codes) + + As noted above, encoded data blocks in the "deflate" format + consist of sequences of symbols drawn from three conceptually + distinct alphabets: either literal bytes, from the alphabet of + byte values (0..255), or pairs, + where the length is drawn from (3..258) and the distance is + drawn from (1..32,768). In fact, the literal and length + alphabets are merged into a single alphabet (0..285), where + values 0..255 represent literal bytes, the value 256 indicates + end-of-block, and values 257..285 represent length codes + (possibly in conjunction with extra bits following the symbol + code) as follows: + + + + + + + + + + + + + + + + +Deutsch Informational [Page 11] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + Extra Extra Extra + Code Bits Length(s) Code Bits Lengths Code Bits Length(s) + ---- ---- ------ ---- ---- ------- ---- ---- ------- + 257 0 3 267 1 15,16 277 4 67-82 + 258 0 4 268 1 17,18 278 4 83-98 + 259 0 5 269 2 19-22 279 4 99-114 + 260 0 6 270 2 23-26 280 4 115-130 + 261 0 7 271 2 27-30 281 5 131-162 + 262 0 8 272 2 31-34 282 5 163-194 + 263 0 9 273 3 35-42 283 5 195-226 + 264 0 10 274 3 43-50 284 5 227-257 + 265 1 11,12 275 3 51-58 285 0 258 + 266 1 13,14 276 3 59-66 + + The extra bits should be interpreted as a machine integer + stored with the most-significant bit first, e.g., bits 1110 + represent the value 14. + + Extra Extra Extra + Code Bits Dist Code Bits Dist Code Bits Distance + ---- ---- ---- ---- ---- ------ ---- ---- -------- + 0 0 1 10 4 33-48 20 9 1025-1536 + 1 0 2 11 4 49-64 21 9 1537-2048 + 2 0 3 12 5 65-96 22 10 2049-3072 + 3 0 4 13 5 97-128 23 10 3073-4096 + 4 1 5,6 14 6 129-192 24 11 4097-6144 + 5 1 7,8 15 6 193-256 25 11 6145-8192 + 6 2 9-12 16 7 257-384 26 12 8193-12288 + 7 2 13-16 17 7 385-512 27 12 12289-16384 + 8 3 17-24 18 8 513-768 28 13 16385-24576 + 9 3 25-32 19 8 769-1024 29 13 24577-32768 + + 3.2.6. Compression with fixed Huffman codes (BTYPE=01) + + The Huffman codes for the two alphabets are fixed, and are not + represented explicitly in the data. The Huffman code lengths + for the literal/length alphabet are: + + Lit Value Bits Codes + --------- ---- ----- + 0 - 143 8 00110000 through + 10111111 + 144 - 255 9 110010000 through + 111111111 + 256 - 279 7 0000000 through + 0010111 + 280 - 287 8 11000000 through + 11000111 + + + +Deutsch Informational [Page 12] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + The code lengths are sufficient to generate the actual codes, + as described above; we show the codes in the table for added + clarity. Literal/length values 286-287 will never actually + occur in the compressed data, but participate in the code + construction. + + Distance codes 0-31 are represented by (fixed-length) 5-bit + codes, with possible additional bits as shown in the table + shown in Paragraph 3.2.5, above. Note that distance codes 30- + 31 will never actually occur in the compressed data. + + 3.2.7. Compression with dynamic Huffman codes (BTYPE=10) + + The Huffman codes for the two alphabets appear in the block + immediately after the header bits and before the actual + compressed data, first the literal/length code and then the + distance code. Each code is defined by a sequence of code + lengths, as discussed in Paragraph 3.2.2, above. For even + greater compactness, the code length sequences themselves are + compressed using a Huffman code. The alphabet for code lengths + is as follows: + + 0 - 15: Represent code lengths of 0 - 15 + 16: Copy the previous code length 3 - 6 times. + The next 2 bits indicate repeat length + (0 = 3, ... , 3 = 6) + Example: Codes 8, 16 (+2 bits 11), + 16 (+2 bits 10) will expand to + 12 code lengths of 8 (1 + 6 + 5) + 17: Repeat a code length of 0 for 3 - 10 times. + (3 bits of length) + 18: Repeat a code length of 0 for 11 - 138 times + (7 bits of length) + + A code length of 0 indicates that the corresponding symbol in + the literal/length or distance alphabet will not occur in the + block, and should not participate in the Huffman code + construction algorithm given earlier. If only one distance + code is used, it is encoded using one bit, not zero bits; in + this case there is a single code length of one, with one unused + code. One distance code of zero bits means that there are no + distance codes used at all (the data is all literals). + + We can now define the format of the block: + + 5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286) + 5 Bits: HDIST, # of Distance codes - 1 (1 - 32) + 4 Bits: HCLEN, # of Code Length codes - 4 (4 - 19) + + + +Deutsch Informational [Page 13] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + (HCLEN + 4) x 3 bits: code lengths for the code length + alphabet given just above, in the order: 16, 17, 18, + 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 + + These code lengths are interpreted as 3-bit integers + (0-7); as above, a code length of 0 means the + corresponding symbol (literal/length or distance code + length) is not used. + + HLIT + 257 code lengths for the literal/length alphabet, + encoded using the code length Huffman code + + HDIST + 1 code lengths for the distance alphabet, + encoded using the code length Huffman code + + The actual compressed data of the block, + encoded using the literal/length and distance Huffman + codes + + The literal/length symbol 256 (end of data), + encoded using the literal/length Huffman code + + The code length repeat codes can cross from HLIT + 257 to the + HDIST + 1 code lengths. In other words, all code lengths form + a single sequence of HLIT + HDIST + 258 values. + + 3.3. Compliance + + A compressor may limit further the ranges of values specified in + the previous section and still be compliant; for example, it may + limit the range of backward pointers to some value smaller than + 32K. Similarly, a compressor may limit the size of blocks so that + a compressible block fits in memory. + + A compliant decompressor must accept the full range of possible + values defined in the previous section, and must accept blocks of + arbitrary size. + +4. Compression algorithm details + + While it is the intent of this document to define the "deflate" + compressed data format without reference to any particular + compression algorithm, the format is related to the compressed + formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below); + since many variations of LZ77 are patented, it is strongly + recommended that the implementor of a compressor follow the general + algorithm presented here, which is known not to be patented per se. + The material in this section is not part of the definition of the + + + +Deutsch Informational [Page 14] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + + specification per se, and a compressor need not follow it in order to + be compliant. + + The compressor terminates a block when it determines that starting a + new block with fresh trees would be useful, or when the block size + fills up the compressor's block buffer. + + The compressor uses a chained hash table to find duplicated strings, + using a hash function that operates on 3-byte sequences. At any + given point during compression, let XYZ be the next 3 input bytes to + be examined (not necessarily all different, of course). First, the + compressor examines the hash chain for XYZ. If the chain is empty, + the compressor simply writes out X as a literal byte and advances one + byte in the input. If the hash chain is not empty, indicating that + the sequence XYZ (or, if we are unlucky, some other 3 bytes with the + same hash function value) has occurred recently, the compressor + compares all strings on the XYZ hash chain with the actual input data + sequence starting at the current point, and selects the longest + match. + + The compressor searches the hash chains starting with the most recent + strings, to favor small distances and thus take advantage of the + Huffman encoding. The hash chains are singly linked. There are no + deletions from the hash chains; the algorithm simply discards matches + that are too old. To avoid a worst-case situation, very long hash + chains are arbitrarily truncated at a certain length, determined by a + run-time parameter. + + To improve overall compression, the compressor optionally defers the + selection of matches ("lazy matching"): after a match of length N has + been found, the compressor searches for a longer match starting at + the next input byte. If it finds a longer match, it truncates the + previous match to a length of one (thus producing a single literal + byte) and then emits the longer match. Otherwise, it emits the + original match, and, as described above, advances N bytes before + continuing. + + Run-time parameters also control this "lazy match" procedure. If + compression ratio is most important, the compressor attempts a + complete second search regardless of the length of the first match. + In the normal case, if the current match is "long enough", the + compressor reduces the search for a longer match, thus speeding up + the process. If speed is most important, the compressor inserts new + strings in the hash table only when no match was found, or when the + match is not "too long". This degrades the compression ratio but + saves time since there are both fewer insertions and fewer searches. + + + + + +Deutsch Informational [Page 15] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +5. References + + [1] Huffman, D. A., "A Method for the Construction of Minimum + Redundancy Codes", Proceedings of the Institute of Radio + Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101. + + [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data + Compression", IEEE Transactions on Information Theory, Vol. 23, + No. 3, pp. 337-343. + + [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources, + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources, + available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/ + + [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix + encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169. + + [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes," + Comm. ACM, 33,4, April 1990, pp. 449-459. + +6. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data. See + reference [3], for example. + +7. Source code + + Source code for a C language implementation of a "deflate" compliant + compressor and decompressor is available within the zlib package at + ftp://ftp.uu.net/pub/archiving/zip/zlib/. + +8. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Phil Katz designed the deflate format. Jean-Loup Gailly and Mark + Adler wrote the related software described in this specification. + Glenn Randers-Pehrson converted this document to RFC and HTML format. + + + +Deutsch Informational [Page 16] + +RFC 1951 DEFLATE Compressed Data Format Specification May 1996 + + +9. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Deutsch Informational [Page 17] + diff --git a/internal-complibs/zlib-ng-2.1.2/doc/rfc1952.txt b/internal-complibs/zlib-ng-2.1.2/doc/rfc1952.txt new file mode 100644 index 000000000..14c0c72eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/doc/rfc1952.txt @@ -0,0 +1,675 @@ + + + + + + +Network Working Group P. Deutsch +Request for Comments: 1952 Aladdin Enterprises +Category: Informational May 1996 + + + GZIP file format specification version 4.3 + +Status of This Memo + + This memo provides information for the Internet community. This memo + does not specify an Internet standard of any kind. Distribution of + this memo is unlimited. + +IESG Note: + + The IESG takes no position on the validity of any Intellectual + Property Rights statements contained in this document. + +Notices + + Copyright (c) 1996 L. Peter Deutsch + + Permission is granted to copy and distribute this document for any + purpose and without charge, including translations into other + languages and incorporation into compilations, provided that the + copyright notice and this notice are preserved, and that any + substantive changes or deletions from the original are clearly + marked. + + A pointer to the latest version of this and related documentation in + HTML format can be found at the URL + . + +Abstract + + This specification defines a lossless compressed data format that is + compatible with the widely used GZIP utility. The format includes a + cyclic redundancy check value for detecting data corruption. The + format presently uses the DEFLATE method of compression but can be + easily extended to use other compression methods. The format can be + implemented readily in a manner not covered by patents. + + + + + + + + + + +Deutsch Informational [Page 1] + +RFC 1952 GZIP File Format Specification May 1996 + + +Table of Contents + + 1. Introduction ................................................... 2 + 1.1. Purpose ................................................... 2 + 1.2. Intended audience ......................................... 3 + 1.3. Scope ..................................................... 3 + 1.4. Compliance ................................................ 3 + 1.5. Definitions of terms and conventions used ................. 3 + 1.6. Changes from previous versions ............................ 3 + 2. Detailed specification ......................................... 4 + 2.1. Overall conventions ....................................... 4 + 2.2. File format ............................................... 5 + 2.3. Member format ............................................. 5 + 2.3.1. Member header and trailer ........................... 6 + 2.3.1.1. Extra field ................................... 8 + 2.3.1.2. Compliance .................................... 9 + 3. References .................................................. 9 + 4. Security Considerations .................................... 10 + 5. Acknowledgements ........................................... 10 + 6. Author's Address ........................................... 10 + 7. Appendix: Jean-Loup Gailly's gzip utility .................. 11 + 8. Appendix: Sample CRC Code .................................. 11 + +1. Introduction + + 1.1. Purpose + + The purpose of this specification is to define a lossless + compressed data format that: + + * Is independent of CPU type, operating system, file system, + and character set, and hence can be used for interchange; + * Can compress or decompress a data stream (as opposed to a + randomly accessible file) to produce another data stream, + using only an a priori bounded amount of intermediate + storage, and hence can be used in data communications or + similar structures such as Unix filters; + * Compresses data with efficiency comparable to the best + currently available general-purpose compression methods, + and in particular considerably better than the "compress" + program; + * Can be implemented readily in a manner not covered by + patents, and hence can be practiced freely; + * Is compatible with the file format produced by the current + widely used gzip utility, in that conforming decompressors + will be able to read data produced by the existing gzip + compressor. + + + + +Deutsch Informational [Page 2] + +RFC 1952 GZIP File Format Specification May 1996 + + + The data format defined by this specification does not attempt to: + + * Provide random access to compressed data; + * Compress specialized data (e.g., raster graphics) as well as + the best currently available specialized algorithms. + + 1.2. Intended audience + + This specification is intended for use by implementors of software + to compress data into gzip format and/or decompress data from gzip + format. + + The text of the specification assumes a basic background in + programming at the level of bits and other primitive data + representations. + + 1.3. Scope + + The specification specifies a compression method and a file format + (the latter assuming only that a file can store a sequence of + arbitrary bytes). It does not specify any particular interface to + a file system or anything about character sets or encodings + (except for file names and comments, which are optional). + + 1.4. Compliance + + Unless otherwise indicated below, a compliant decompressor must be + able to accept and decompress any file that conforms to all the + specifications presented here; a compliant compressor must produce + files that conform to all the specifications presented here. The + material in the appendices is not part of the specification per se + and is not relevant to compliance. + + 1.5. Definitions of terms and conventions used + + byte: 8 bits stored or transmitted as a unit (same as an octet). + (For this specification, a byte is exactly 8 bits, even on + machines which store a character on a number of bits different + from 8.) See below for the numbering of bits within a byte. + + 1.6. Changes from previous versions + + There have been no technical changes to the gzip format since + version 4.1 of this specification. In version 4.2, some + terminology was changed, and the sample CRC code was rewritten for + clarity and to eliminate the requirement for the caller to do pre- + and post-conditioning. Version 4.3 is a conversion of the + specification to RFC style. + + + +Deutsch Informational [Page 3] + +RFC 1952 GZIP File Format Specification May 1996 + + +2. Detailed specification + + 2.1. Overall conventions + + In the diagrams below, a box like this: + + +---+ + | | <-- the vertical bars might be missing + +---+ + + represents one byte; a box like this: + + +==============+ + | | + +==============+ + + represents a variable number of bytes. + + Bytes stored within a computer do not have a "bit order", since + they are always treated as a unit. However, a byte considered as + an integer between 0 and 255 does have a most- and least- + significant bit, and since we write numbers with the most- + significant digit on the left, we also write bytes with the most- + significant bit on the left. In the diagrams below, we number the + bits of a byte so that bit 0 is the least-significant bit, i.e., + the bits are numbered: + + +--------+ + |76543210| + +--------+ + + This document does not address the issue of the order in which + bits of a byte are transmitted on a bit-sequential medium, since + the data format described here is byte- rather than bit-oriented. + + Within a computer, a number may occupy multiple bytes. All + multi-byte numbers in the format described here are stored with + the least-significant byte first (at the lower memory address). + For example, the decimal number 520 is stored as: + + 0 1 + +--------+--------+ + |00001000|00000010| + +--------+--------+ + ^ ^ + | | + | + more significant byte = 2 x 256 + + less significant byte = 8 + + + +Deutsch Informational [Page 4] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.2. File format + + A gzip file consists of a series of "members" (compressed data + sets). The format of each member is specified in the following + section. The members simply appear one after another in the file, + with no additional information before, between, or after them. + + 2.3. Member format + + Each member has the following structure: + + +---+---+---+---+---+---+---+---+---+---+ + |ID1|ID2|CM |FLG| MTIME |XFL|OS | (more-->) + +---+---+---+---+---+---+---+---+---+---+ + + (if FLG.FEXTRA set) + + +---+---+=================================+ + | XLEN |...XLEN bytes of "extra field"...| (more-->) + +---+---+=================================+ + + (if FLG.FNAME set) + + +=========================================+ + |...original file name, zero-terminated...| (more-->) + +=========================================+ + + (if FLG.FCOMMENT set) + + +===================================+ + |...file comment, zero-terminated...| (more-->) + +===================================+ + + (if FLG.FHCRC set) + + +---+---+ + | CRC16 | + +---+---+ + + +=======================+ + |...compressed blocks...| (more-->) + +=======================+ + + 0 1 2 3 4 5 6 7 + +---+---+---+---+---+---+---+---+ + | CRC32 | ISIZE | + +---+---+---+---+---+---+---+---+ + + + + +Deutsch Informational [Page 5] + +RFC 1952 GZIP File Format Specification May 1996 + + + 2.3.1. Member header and trailer + + ID1 (IDentification 1) + ID2 (IDentification 2) + These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139 + (0x8b, \213), to identify the file as being in gzip format. + + CM (Compression Method) + This identifies the compression method used in the file. CM + = 0-7 are reserved. CM = 8 denotes the "deflate" + compression method, which is the one customarily used by + gzip and which is documented elsewhere. + + FLG (FLaGs) + This flag byte is divided into individual bits as follows: + + bit 0 FTEXT + bit 1 FHCRC + bit 2 FEXTRA + bit 3 FNAME + bit 4 FCOMMENT + bit 5 reserved + bit 6 reserved + bit 7 reserved + + If FTEXT is set, the file is probably ASCII text. This is + an optional indication, which the compressor may set by + checking a small amount of the input data to see whether any + non-ASCII characters are present. In case of doubt, FTEXT + is cleared, indicating binary data. For systems which have + different file formats for ascii text and binary data, the + decompressor can use FTEXT to choose the appropriate format. + We deliberately do not specify the algorithm used to set + this bit, since a compressor always has the option of + leaving it cleared and a decompressor always has the option + of ignoring it and letting some other program handle issues + of data conversion. + + If FHCRC is set, a CRC16 for the gzip header is present, + immediately before the compressed data. The CRC16 consists + of the two least significant bytes of the CRC32 for all + bytes of the gzip header up to and not including the CRC16. + [The FHCRC bit was never set by versions of gzip up to + 1.2.4, even though it was documented with a different + meaning in gzip 1.2.4.] + + If FEXTRA is set, optional extra fields are present, as + described in a following section. + + + +Deutsch Informational [Page 6] + +RFC 1952 GZIP File Format Specification May 1996 + + + If FNAME is set, an original file name is present, + terminated by a zero byte. The name must consist of ISO + 8859-1 (LATIN-1) characters; on operating systems using + EBCDIC or any other character set for file names, the name + must be translated to the ISO LATIN-1 character set. This + is the original name of the file being compressed, with any + directory components removed, and, if the file being + compressed is on a file system with case insensitive names, + forced to lower case. There is no original file name if the + data was compressed from a source other than a named file; + for example, if the source was stdin on a Unix system, there + is no file name. + + If FCOMMENT is set, a zero-terminated file comment is + present. This comment is not interpreted; it is only + intended for human consumption. The comment must consist of + ISO 8859-1 (LATIN-1) characters. Line breaks should be + denoted by a single line feed character (10 decimal). + + Reserved FLG bits must be zero. + + MTIME (Modification TIME) + This gives the most recent modification time of the original + file being compressed. The time is in Unix format, i.e., + seconds since 00:00:00 GMT, Jan. 1, 1970. (Note that this + may cause problems for MS-DOS and other systems that use + local rather than Universal time.) If the compressed data + did not come from a file, MTIME is set to the time at which + compression started. MTIME = 0 means no time stamp is + available. + + XFL (eXtra FLags) + These flags are available for use by specific compression + methods. The "deflate" method (CM = 8) sets these flags as + follows: + + XFL = 2 - compressor used maximum compression, + slowest algorithm + XFL = 4 - compressor used fastest algorithm + + OS (Operating System) + This identifies the type of file system on which compression + took place. This may be useful in determining end-of-line + convention for text files. The currently defined values are + as follows: + + + + + + +Deutsch Informational [Page 7] + +RFC 1952 GZIP File Format Specification May 1996 + + + 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32) + 1 - Amiga + 2 - VMS (or OpenVMS) + 3 - Unix + 4 - VM/CMS + 5 - Atari TOS + 6 - HPFS filesystem (OS/2, NT) + 7 - Macintosh + 8 - Z-System + 9 - CP/M + 10 - TOPS-20 + 11 - NTFS filesystem (NT) + 12 - QDOS + 13 - Acorn RISCOS + 255 - unknown + + XLEN (eXtra LENgth) + If FLG.FEXTRA is set, this gives the length of the optional + extra field. See below for details. + + CRC32 (CRC-32) + This contains a Cyclic Redundancy Check value of the + uncompressed data computed according to CRC-32 algorithm + used in the ISO 3309 standard and in section 8.1.1.6.2 of + ITU-T recommendation V.42. (See https://www.iso.org/ for + ordering ISO documents. See gopher://info.itu.ch for an + online version of ITU-T V.42.) + + ISIZE (Input SIZE) + This contains the size of the original (uncompressed) input + data modulo 2^32. + + 2.3.1.1. Extra field + + If the FLG.FEXTRA bit is set, an "extra field" is present in + the header, with total length XLEN bytes. It consists of a + series of subfields, each of the form: + + +---+---+---+---+==================================+ + |SI1|SI2| LEN |... LEN bytes of subfield data ...| + +---+---+---+---+==================================+ + + SI1 and SI2 provide a subfield ID, typically two ASCII letters + with some mnemonic value. Jean-Loup Gailly + is maintaining a registry of subfield + IDs; please send him any subfield ID you wish to use. Subfield + IDs with SI2 = 0 are reserved for future use. The following + IDs are currently defined: + + + +Deutsch Informational [Page 8] + +RFC 1952 GZIP File Format Specification May 1996 + + + SI1 SI2 Data + ---------- ---------- ---- + 0x41 ('A') 0x70 ('P') Apollo file type information + + LEN gives the length of the subfield data, excluding the 4 + initial bytes. + + 2.3.1.2. Compliance + + A compliant compressor must produce files with correct ID1, + ID2, CM, CRC32, and ISIZE, but may set all the other fields in + the fixed-length part of the header to default values (255 for + OS, 0 for all others). The compressor must set all reserved + bits to zero. + + A compliant decompressor must check ID1, ID2, and CM, and + provide an error indication if any of these have incorrect + values. It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC + at least so it can skip over the optional fields if they are + present. It need not examine any other part of the header or + trailer; in particular, a decompressor may ignore FTEXT and OS + and always produce binary output, and still be compliant. A + compliant decompressor must give an error indication if any + reserved bit is non-zero, since such a bit could indicate the + presence of a new field that would cause subsequent data to be + interpreted incorrectly. + +3. References + + [1] "Information Processing - 8-bit single-byte coded graphic + character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987). + The ISO 8859-1 (Latin-1) character set is a superset of 7-bit + ASCII. Files defining this character set are available as + iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/ + + [2] ISO 3309 + + [3] ITU-T recommendation V.42 + + [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification", + available in ftp://ftp.uu.net/pub/archiving/zip/doc/ + + [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in + ftp://prep.ai.mit.edu/pub/gnu/ + + [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table + Look-Up", Communications of the ACM, 31(8), pp.1008-1013. + + + + +Deutsch Informational [Page 9] + +RFC 1952 GZIP File Format Specification May 1996 + + + [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal, + pp.118-133. + + [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt, + describing the CRC concept. + +4. Security Considerations + + Any data compression method involves the reduction of redundancy in + the data. Consequently, any corruption of the data is likely to have + severe effects and be difficult to correct. Uncompressed text, on + the other hand, will probably still be readable despite the presence + of some corrupted bytes. + + It is recommended that systems using this data format provide some + means of validating the integrity of the compressed data, such as by + setting and checking the CRC-32 check value. + +5. Acknowledgements + + Trademarks cited in this document are the property of their + respective owners. + + Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler, + the related software described in this specification. Glenn + Randers-Pehrson converted this document to RFC and HTML format. + +6. Author's Address + + L. Peter Deutsch + Aladdin Enterprises + 203 Santa Margarita Ave. + Menlo Park, CA 94025 + + Phone: (415) 322-0103 (AM only) + FAX: (415) 322-1734 + EMail: + + Questions about the technical content of this specification can be + sent by email to: + + Jean-Loup Gailly and + Mark Adler + + Editorial comments on this specification can be sent by email to: + + L. Peter Deutsch and + Glenn Randers-Pehrson + + + +Deutsch Informational [Page 10] + +RFC 1952 GZIP File Format Specification May 1996 + + +7. Appendix: Jean-Loup Gailly's gzip utility + + The most widely used implementation of gzip compression, and the + original documentation on which this specification is based, were + created by Jean-Loup Gailly . Since this + implementation is a de facto standard, we mention some more of its + features here. Again, the material in this section is not part of + the specification per se, and implementations need not follow it to + be compliant. + + When compressing or decompressing a file, gzip preserves the + protection, ownership, and modification time attributes on the local + file system, since there is no provision for representing protection + attributes in the gzip file format itself. Since the file format + includes a modification time, the gzip decompressor provides a + command line switch that assigns the modification time from the file, + rather than the local modification time of the compressed input, to + the decompressed output. + +8. Appendix: Sample CRC Code + + The following sample code represents a practical implementation of + the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42 + for a formal specification.) + + The sample code is in the ANSI C programming language. Non C users + may find it easier to read with these hints: + + & Bitwise AND operator. + ^ Bitwise exclusive-OR operator. + >> Bitwise right shift operator. When applied to an + unsigned quantity, as here, right shift inserts zero + bit(s) at the left. + ! Logical NOT operator. + ++ "n++" increments the variable n. + 0xNNN 0x introduces a hexadecimal (base 16) constant. + Suffix L indicates a long value (at least 32 bits). + + /* Table of CRCs of all 8-bit messages. */ + unsigned long crc_table[256]; + + /* Flag: has the table been computed? Initially false. */ + int crc_table_computed = 0; + + /* Make the table for a fast CRC. */ + void make_crc_table(void) + { + unsigned long c; + + + +Deutsch Informational [Page 11] + +RFC 1952 GZIP File Format Specification May 1996 + + + int n, k; + for (n = 0; n < 256; n++) { + c = (unsigned long) n; + for (k = 0; k < 8; k++) { + if (c & 1) { + c = 0xedb88320L ^ (c >> 1); + } else { + c = c >> 1; + } + } + crc_table[n] = c; + } + crc_table_computed = 1; + } + + /* + Update a running crc with the bytes buf[0..len-1] and return + the updated crc. The crc should be initialized to zero. Pre- and + post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the caller. Usage example: + + unsigned long crc = 0L; + + while (read_buffer(buffer, length) != EOF) { + crc = update_crc(crc, buffer, length); + } + if (crc != original_crc) error(); + */ + unsigned long update_crc(unsigned long crc, + unsigned char *buf, int len) + { + unsigned long c = crc ^ 0xffffffffL; + int n; + + if (!crc_table_computed) + make_crc_table(); + for (n = 0; n < len; n++) { + c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; + } + + /* Return the CRC of the bytes buf[0..len-1]. */ + unsigned long crc(unsigned char *buf, int len) + { + return update_crc(0L, buf, len); + } + + + + +Deutsch Informational [Page 12] + diff --git a/internal-complibs/zlib-ng-2.1.2/doc/txtvsbin.txt b/internal-complibs/zlib-ng-2.1.2/doc/txtvsbin.txt new file mode 100644 index 000000000..3d0f0634f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/doc/txtvsbin.txt @@ -0,0 +1,107 @@ +A Fast Method for Identifying Plain Text Files +============================================== + + +Introduction +------------ + +Given a file coming from an unknown source, it is sometimes desirable +to find out whether the format of that file is plain text. Although +this may appear like a simple task, a fully accurate detection of the +file type requires heavy-duty semantic analysis on the file contents. +It is, however, possible to obtain satisfactory results by employing +various heuristics. + +Previous versions of PKZip and other zip-compatible compression tools +were using a crude detection scheme: if more than 80% (4/5) of the bytes +found in a certain buffer are within the range [7..127], the file is +labeled as plain text, otherwise it is labeled as binary. A prominent +limitation of this scheme is the restriction to Latin-based alphabets. +Other alphabets, like Greek, Cyrillic or Asian, make extensive use of +the bytes within the range [128..255], and texts using these alphabets +are most often misidentified by this scheme; in other words, the rate +of false negatives is sometimes too high, which means that the recall +is low. Another weakness of this scheme is a reduced precision, due to +the false positives that may occur when binary files containing large +amounts of textual characters are misidentified as plain text. + +In this article we propose a new, simple detection scheme that features +a much increased precision and a near-100% recall. This scheme is +designed to work on ASCII, Unicode and other ASCII-derived alphabets, +and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.) +and variable-sized encodings (ISO-2022, UTF-8, etc.). Wider encodings +(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however. + + +The Algorithm +------------- + +The algorithm works by dividing the set of bytecodes [0..255] into three +categories: +- The white list of textual bytecodes: + 9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255. +- The gray list of tolerated bytecodes: + 7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC). +- The black list of undesired, non-textual bytecodes: + 0 (NUL) to 6, 14 to 31. + +If a file contains at least one byte that belongs to the white list and +no byte that belongs to the black list, then the file is categorized as +plain text; otherwise, it is categorized as binary. (The boundary case, +when the file is empty, automatically falls into the latter category.) + + +Rationale +--------- + +The idea behind this algorithm relies on two observations. + +The first observation is that, although the full range of 7-bit codes +[0..127] is properly specified by the ASCII standard, most control +characters in the range [0..31] are not used in practice. The only +widely-used, almost universally-portable control codes are 9 (TAB), +10 (LF) and 13 (CR). There are a few more control codes that are +recognized on a reduced range of platforms and text viewers/editors: +7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these +codes are rarely (if ever) used alone, without being accompanied by +some printable text. Even the newer, portable text formats such as +XML avoid using control characters outside the list mentioned here. + +The second observation is that most of the binary files tend to contain +control characters, especially 0 (NUL). Even though the older text +detection schemes observe the presence of non-ASCII codes from the range +[128..255], the precision rarely has to suffer if this upper range is +labeled as textual, because the files that are genuinely binary tend to +contain both control characters and codes from the upper range. On the +other hand, the upper range needs to be labeled as textual, because it +is used by virtually all ASCII extensions. In particular, this range is +used for encoding non-Latin scripts. + +Since there is no counting involved, other than simply observing the +presence or the absence of some byte values, the algorithm produces +consistent results, regardless what alphabet encoding is being used. +(If counting were involved, it could be possible to obtain different +results on a text encoded, say, using ISO-8859-16 versus UTF-8.) + +There is an extra category of plain text files that are "polluted" with +one or more black-listed codes, either by mistake or by peculiar design +considerations. In such cases, a scheme that tolerates a small fraction +of black-listed codes would provide an increased recall (i.e. more true +positives). This, however, incurs a reduced precision overall, since +false positives are more likely to appear in binary files that contain +large chunks of textual data. Furthermore, "polluted" plain text should +be regarded as binary by general-purpose text detection schemes, because +general-purpose text processing algorithms might not be applicable. +Under this premise, it is safe to say that our detection method provides +a near-100% recall. + +Experiments have been run on many files coming from various platforms +and applications. We tried plain text files, system logs, source code, +formatted office documents, compiled object code, etc. The results +confirm the optimistic assumptions about the capabilities of this +algorithm. + + +-- +Cosmin Truta +Last updated: 2006-May-28 diff --git a/internal-complibs/zlib-ng-2.1.2/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.2/fallback_builtins.h new file mode 100644 index 000000000..447f9ac19 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/fallback_builtins.h @@ -0,0 +1,133 @@ +#ifndef FALLBACK_BUILTINS_H +#define FALLBACK_BUILTINS_H + +#if defined(_MSC_VER) && !defined(__clang__) +#if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined(_M_ARM) || defined(_M_ARM64) + +#include +#ifdef X86_FEATURES +# include "arch/x86/x86_features.h" +#endif + +/* This is not a general purpose replacement for __builtin_ctz. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + * Tzcnt and bsf give identical results except when input value is 0, therefore this can not be allowed. + * If tzcnt instruction is not supported, the cpu will itself execute bsf instead. + * Performance tzcnt/bsf is identical on Intel cpu, tzcnt is faster than bsf on AMD cpu. + */ +static __forceinline int __builtin_ctz(unsigned int value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u32(value); +# else + unsigned long trailing_zero; + _BitScanForward(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZ + +#ifdef _M_AMD64 +/* This is not a general purpose replacement for __builtin_ctzll. The function expects that value is != 0. + * Because of that assumption trailing_zero is not initialized and the return value is not checked. + */ +static __forceinline int __builtin_ctzll(unsigned long long value) { + Assert(value != 0, "Invalid input value: 0"); +# if defined(X86_FEATURES) && !(_MSC_VER < 1700) + return (int)_tzcnt_u64(value); +# else + unsigned long trailing_zero; + _BitScanForward64(&trailing_zero, value); + return (int)trailing_zero; +# endif +} +#define HAVE_BUILTIN_CTZLL +#endif // Microsoft AMD64 + +#endif // Microsoft AMD64/IA64/x86/ARM/ARM64 test +#endif // _MSC_VER & !clang + +/* Unfortunately GCC didn't support these things until version 10. + * Similarly, AppleClang didn't support them in Xcode 9.2 but did in 9.3. + */ +#ifdef __AVX2__ +#include + +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 10) \ + || (defined(__apple_build_version__) && __apple_build_version__ < 9020039) +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm256_castsi128_si256(r); +} + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + __m128i r; + __asm__ volatile ("vmovdqa %1,%0" : "=x" (r) : "x" (a)); + return _mm512_castsi128_si512(r); +} +#endif // __AVX512F__ +#endif // gcc/AppleClang version test + +#endif // __AVX2__ + +/* GCC <9 is missing some AVX512 intrinsics. + */ +#ifdef __AVX512F__ +#if (!defined(__clang__) && defined(__GNUC__) && __GNUC__ < 9) +#include + +#define PACK(c0, c1, c2, c3) (((int)(unsigned char)(c0) << 24) | ((int)(unsigned char)(c1) << 16) | \ + ((int)(unsigned char)(c2) << 8) | ((int)(unsigned char)(c3))) + +static inline __m512i _mm512_set_epi8(char __q63, char __q62, char __q61, char __q60, + char __q59, char __q58, char __q57, char __q56, + char __q55, char __q54, char __q53, char __q52, + char __q51, char __q50, char __q49, char __q48, + char __q47, char __q46, char __q45, char __q44, + char __q43, char __q42, char __q41, char __q40, + char __q39, char __q38, char __q37, char __q36, + char __q35, char __q34, char __q33, char __q32, + char __q31, char __q30, char __q29, char __q28, + char __q27, char __q26, char __q25, char __q24, + char __q23, char __q22, char __q21, char __q20, + char __q19, char __q18, char __q17, char __q16, + char __q15, char __q14, char __q13, char __q12, + char __q11, char __q10, char __q09, char __q08, + char __q07, char __q06, char __q05, char __q04, + char __q03, char __q02, char __q01, char __q00) { + return _mm512_set_epi32(PACK(__q63, __q62, __q61, __q60), PACK(__q59, __q58, __q57, __q56), + PACK(__q55, __q54, __q53, __q52), PACK(__q51, __q50, __q49, __q48), + PACK(__q47, __q46, __q45, __q44), PACK(__q43, __q42, __q41, __q40), + PACK(__q39, __q38, __q37, __q36), PACK(__q35, __q34, __q33, __q32), + PACK(__q31, __q30, __q29, __q28), PACK(__q27, __q26, __q25, __q24), + PACK(__q23, __q22, __q21, __q20), PACK(__q19, __q18, __q17, __q16), + PACK(__q15, __q14, __q13, __q12), PACK(__q11, __q10, __q09, __q08), + PACK(__q07, __q06, __q05, __q04), PACK(__q03, __q02, __q01, __q00)); +} + +#undef PACK + +#endif // gcc version test +#endif // __AVX512F__ + +/* Missing zero-extension AVX and AVX512 intrinsics. + * Fixed in Microsoft Visual Studio 2017 version 15.7 + * https://developercommunity.visualstudio.com/t/missing-zero-extension-avx-and-avx512-intrinsics/175737 + */ +#if defined(_MSC_VER) && _MSC_VER < 1914 +#ifdef __AVX2__ +static inline __m256i _mm256_zextsi128_si256(__m128i a) { + return _mm256_inserti128_si256(_mm256_setzero_si256(), a, 0); +} +#endif // __AVX2__ + +#ifdef __AVX512F__ +static inline __m512i _mm512_zextsi128_si512(__m128i a) { + return _mm512_inserti32x4(_mm512_setzero_si512(), a, 0); +} +#endif // __AVX512F__ +#endif // defined(_MSC_VER) && _MSC_VER < 1914 + +#endif // include guard FALLBACK_BUILTINS_H diff --git a/internal-complibs/zlib-ng-2.1.2/functable.c b/internal-complibs/zlib-ng-2.1.2/functable.c new file mode 100644 index 000000000..d20098292 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/functable.c @@ -0,0 +1,336 @@ +/* functable.c -- Choose relevant optimized functions at runtime + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "crc32_braid_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "cpu_features.h" + +static void init_functable(void) { + struct functable_s ft; + struct cpu_features cf; + + cpu_check_features(&cf); + + // Generic code + ft.adler32 = &adler32_c; + ft.adler32_fold_copy = &adler32_fold_copy_c; + ft.chunkmemset_safe = &chunkmemset_safe_c; + ft.chunksize = &chunksize_c; + ft.crc32 = &PREFIX(crc32_braid); + ft.crc32_fold = &crc32_fold_c; + ft.crc32_fold_copy = &crc32_fold_copy_c; + ft.crc32_fold_final = &crc32_fold_final_c; + ft.crc32_fold_reset = &crc32_fold_reset_c; + ft.inflate_fast = &inflate_fast_c; + ft.insert_string = &insert_string_c; + ft.quick_insert_string = &quick_insert_string_c; + ft.slide_hash = &slide_hash_c; + ft.update_hash = &update_hash_c; + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +# if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) + ft.longest_match = &longest_match_unaligned_64; + ft.longest_match_slow = &longest_match_slow_unaligned_64; + ft.compare256 = &compare256_unaligned_64; +# elif defined(HAVE_BUILTIN_CTZ) + ft.longest_match = &longest_match_unaligned_32; + ft.longest_match_slow = &longest_match_slow_unaligned_32; + ft.compare256 = &compare256_unaligned_32; +# else + ft.longest_match = &longest_match_unaligned_16; + ft.longest_match_slow = &longest_match_slow_unaligned_16; + ft.compare256 = &compare256_unaligned_16; +# endif +#else + ft.longest_match = &longest_match_c; + ft.longest_match_slow = &longest_match_slow_c; + ft.compare256 = &compare256_c; +#endif + + + // Select arch-optimized functions + + // X86 - SSE2 +#ifdef X86_SSE2 +# if !defined(__x86_64__) && !defined(_M_X64) && !defined(X86_NOCHECK_SSE2) + if (cf.x86.has_sse2) +# endif + { + ft.chunkmemset_safe = &chunkmemset_safe_sse2; + ft.chunksize = &chunksize_sse2; + ft.inflate_fast = &inflate_fast_sse2; + ft.slide_hash = &slide_hash_sse2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_sse2; + ft.longest_match = &longest_match_sse2; + ft.longest_match_slow = &longest_match_slow_sse2; +# endif + } +#endif + // X86 - SSSE3 +#ifdef X86_SSSE3 + if (cf.x86.has_ssse3) { + ft.adler32 = &adler32_ssse3; +# ifdef X86_SSE2 + ft.chunkmemset_safe = &chunkmemset_safe_ssse3; + ft.inflate_fast = &inflate_fast_ssse3; +# endif + } +#endif + // X86 - SSE4.2 +#ifdef X86_SSE42 + if (cf.x86.has_sse42) { + ft.adler32_fold_copy = &adler32_fold_copy_sse42; + ft.insert_string = &insert_string_sse42; + ft.quick_insert_string = &quick_insert_string_sse42; + ft.update_hash = &update_hash_sse42; + } +#endif + // X86 - PCLMUL +#ifdef X86_PCLMULQDQ_CRC + if (cf.x86.has_pclmulqdq) { + ft.crc32 = &crc32_pclmulqdq; + ft.crc32_fold = &crc32_fold_pclmulqdq; + ft.crc32_fold_copy = &crc32_fold_pclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_pclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_pclmulqdq_reset; + } +#endif + // X86 - AVX +#ifdef X86_AVX2 + if (cf.x86.has_avx2) { + ft.adler32 = &adler32_avx2; + ft.adler32_fold_copy = &adler32_fold_copy_avx2; + ft.chunkmemset_safe = &chunkmemset_safe_avx2; + ft.chunksize = &chunksize_avx2; + ft.inflate_fast = &inflate_fast_avx2; + ft.slide_hash = &slide_hash_avx2; +# ifdef HAVE_BUILTIN_CTZ + ft.compare256 = &compare256_avx2; + ft.longest_match = &longest_match_avx2; + ft.longest_match_slow = &longest_match_slow_avx2; +# endif + } +#endif +#ifdef X86_AVX512 + if (cf.x86.has_avx512) { + ft.adler32 = &adler32_avx512; + ft.adler32_fold_copy = &adler32_fold_copy_avx512; + } +#endif +#ifdef X86_AVX512VNNI + if (cf.x86.has_avx512vnni) { + ft.adler32 = &adler32_avx512_vnni; + ft.adler32_fold_copy = &adler32_fold_copy_avx512_vnni; + } +#endif + // X86 - VPCLMULQDQ +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + if (cf.x86.has_pclmulqdq && cf.x86.has_avx512 && cf.x86.has_vpclmulqdq) { + ft.crc32 = &crc32_vpclmulqdq; + ft.crc32_fold = &crc32_fold_vpclmulqdq; + ft.crc32_fold_copy = &crc32_fold_vpclmulqdq_copy; + ft.crc32_fold_final = &crc32_fold_vpclmulqdq_final; + ft.crc32_fold_reset = &crc32_fold_vpclmulqdq_reset; + } +#endif + + + // ARM - NEON +#ifdef ARM_NEON +# ifndef ARM_NOCHECK_NEON + if (cf.arm.has_neon) +# endif + { + ft.adler32 = &adler32_neon; + ft.chunkmemset_safe = &chunkmemset_safe_neon; + ft.chunksize = &chunksize_neon; + ft.inflate_fast = &inflate_fast_neon; + ft.slide_hash = &slide_hash_neon; +# ifdef HAVE_BUILTIN_CTZLL + ft.compare256 = &compare256_neon; + ft.longest_match = &longest_match_neon; + ft.longest_match_slow = &longest_match_slow_neon; +# endif + } +#endif + // ARM - ACLE +#ifdef ARM_ACLE + if (cf.arm.has_crc32) { + ft.crc32 = &crc32_acle; + ft.insert_string = &insert_string_acle; + ft.quick_insert_string = &quick_insert_string_acle; + ft.update_hash = &update_hash_acle; + } +#endif + + + // Power - VMX +#ifdef PPC_VMX + if (cf.power.has_altivec) { + ft.adler32 = &adler32_vmx; + ft.slide_hash = &slide_hash_vmx; + } +#endif + // Power8 - VSX +#ifdef POWER8_VSX + if (cf.power.has_arch_2_07) { + ft.adler32 = &adler32_power8; + ft.chunkmemset_safe = &chunkmemset_safe_power8; + ft.chunksize = &chunksize_power8; + ft.inflate_fast = &inflate_fast_power8; + ft.slide_hash = &slide_hash_power8; + } +#endif +#ifdef POWER8_VSX_CRC32 + if (cf.power.has_arch_2_07) + ft.crc32 = &crc32_power8; +#endif + // Power9 +#ifdef POWER9 + if (cf.power.has_arch_3_00) { + ft.compare256 = &compare256_power9; + ft.longest_match = &longest_match_power9; + ft.longest_match_slow = &longest_match_slow_power9; + } +#endif + + + // S390 +#ifdef S390_CRC32_VX + if (cf.s390.has_vx) + ft.crc32 = crc32_s390_vx; +#endif + + // Assign function pointers individually for atomic operation + functable.adler32 = ft.adler32; + functable.adler32_fold_copy = ft.adler32_fold_copy; + functable.chunkmemset_safe = ft.chunkmemset_safe; + functable.chunksize = ft.chunksize; + functable.compare256 = ft.compare256; + functable.crc32 = ft.crc32; + functable.crc32_fold = ft.crc32_fold; + functable.crc32_fold_copy = ft.crc32_fold_copy; + functable.crc32_fold_final = ft.crc32_fold_final; + functable.crc32_fold_reset = ft.crc32_fold_reset; + functable.inflate_fast = ft.inflate_fast; + functable.insert_string = ft.insert_string; + functable.longest_match = ft.longest_match; + functable.longest_match_slow = ft.longest_match_slow; + functable.quick_insert_string = ft.quick_insert_string; + functable.slide_hash = ft.slide_hash; + functable.update_hash = ft.update_hash; +} + +/* stub functions */ +static uint32_t adler32_stub(uint32_t adler, const uint8_t* buf, size_t len) { + init_functable(); + return functable.adler32(adler, buf, len); +} + +static uint32_t adler32_fold_copy_stub(uint32_t adler, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + return functable.adler32_fold_copy(adler, dst, src, len); +} + +static uint8_t* chunkmemset_safe_stub(uint8_t* out, unsigned dist, unsigned len, unsigned left) { + init_functable(); + return functable.chunkmemset_safe(out, dist, len, left); +} + +static uint32_t chunksize_stub(void) { + init_functable(); + return functable.chunksize(); +} + +static uint32_t compare256_stub(const uint8_t* src0, const uint8_t* src1) { + init_functable(); + return functable.compare256(src0, src1); +} + +static uint32_t crc32_stub(uint32_t crc, const uint8_t* buf, size_t len) { + init_functable(); + return functable.crc32(crc, buf, len); +} + +static void crc32_fold_stub(crc32_fold* crc, const uint8_t* src, size_t len, uint32_t init_crc) { + init_functable(); + functable.crc32_fold(crc, src, len, init_crc); +} + +static void crc32_fold_copy_stub(crc32_fold* crc, uint8_t* dst, const uint8_t* src, size_t len) { + init_functable(); + functable.crc32_fold_copy(crc, dst, src, len); +} + +static uint32_t crc32_fold_final_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_final(crc); +} + +static uint32_t crc32_fold_reset_stub(crc32_fold* crc) { + init_functable(); + return functable.crc32_fold_reset(crc); +} + +static void inflate_fast_stub(PREFIX3(stream) *strm, uint32_t start) { + init_functable(); + functable.inflate_fast(strm, start); +} + +static void insert_string_stub(deflate_state* const s, uint32_t str, uint32_t count) { + init_functable(); + functable.insert_string(s, str, count); +} + +static uint32_t longest_match_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match(s, cur_match); +} + +static uint32_t longest_match_slow_stub(deflate_state* const s, Pos cur_match) { + init_functable(); + return functable.longest_match_slow(s, cur_match); +} + +static Pos quick_insert_string_stub(deflate_state* const s, const uint32_t str) { + init_functable(); + return functable.quick_insert_string(s, str); +} + +static void slide_hash_stub(deflate_state* s) { + init_functable(); + functable.slide_hash(s); +} + +static uint32_t update_hash_stub(deflate_state* const s, uint32_t h, uint32_t val) { + init_functable(); + return functable.update_hash(s, h, val); +} + +/* functable init */ +Z_INTERNAL Z_TLS struct functable_s functable = { + adler32_stub, + adler32_fold_copy_stub, + chunkmemset_safe_stub, + chunksize_stub, + compare256_stub, + crc32_stub, + crc32_fold_stub, + crc32_fold_copy_stub, + crc32_fold_final_stub, + crc32_fold_reset_stub, + inflate_fast_stub, + insert_string_stub, + longest_match_stub, + longest_match_slow_stub, + quick_insert_string_stub, + slide_hash_stub, + update_hash_stub +}; diff --git a/internal-complibs/zlib-ng-2.1.2/functable.h b/internal-complibs/zlib-ng-2.1.2/functable.h new file mode 100644 index 000000000..1cdfd4df4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/functable.h @@ -0,0 +1,41 @@ +/* functable.h -- Struct containing function pointers to optimized functions + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef FUNCTABLE_H_ +#define FUNCTABLE_H_ + +#include "deflate.h" +#include "crc32_fold.h" +#include "adler32_fold.h" + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +struct functable_s { + uint32_t (* adler32) (uint32_t adler, const uint8_t *buf, size_t len); + uint32_t (* adler32_fold_copy) (uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + uint8_t* (* chunkmemset_safe) (uint8_t *out, unsigned dist, unsigned len, unsigned left); + uint32_t (* chunksize) (void); + uint32_t (* compare256) (const uint8_t *src0, const uint8_t *src1); + uint32_t (* crc32) (uint32_t crc, const uint8_t *buf, size_t len); + void (* crc32_fold) (struct crc32_fold_s *crc, const uint8_t *src, size_t len, uint32_t init_crc); + void (* crc32_fold_copy) (struct crc32_fold_s *crc, uint8_t *dst, const uint8_t *src, size_t len); + uint32_t (* crc32_fold_final) (struct crc32_fold_s *crc); + uint32_t (* crc32_fold_reset) (struct crc32_fold_s *crc); + void (* inflate_fast) (PREFIX3(stream) *strm, uint32_t start); + void (* insert_string) (deflate_state *const s, uint32_t str, uint32_t count); + uint32_t (* longest_match) (deflate_state *const s, Pos cur_match); + uint32_t (* longest_match_slow) (deflate_state *const s, Pos cur_match); + Pos (* quick_insert_string)(deflate_state *const s, uint32_t str); + void (* slide_hash) (deflate_state *s); + uint32_t (* update_hash) (deflate_state *const s, uint32_t h, uint32_t val); +}; + +Z_INTERNAL extern Z_TLS struct functable_s functable; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/gzguts.h b/internal-complibs/zlib-ng-2.1.2/gzguts.h new file mode 100644 index 000000000..fe0927063 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/gzguts.h @@ -0,0 +1,145 @@ +#ifndef GZGUTS_H_ +#define GZGUTS_H_ +/* gzguts.h -- zlib internal header definitions for gz* operations + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef _LARGEFILE64_SOURCE +# ifndef _LARGEFILE_SOURCE +# define _LARGEFILE_SOURCE 1 +# endif +# ifdef _FILE_OFFSET_BITS +# undef _FILE_OFFSET_BITS +# endif +#endif + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#include +#include +#include +#include +#include + +#if defined(ZLIB_COMPAT) +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#ifdef _WIN32 +# include +#endif + +#if defined(_WIN32) +# include +# define WIDECHAR +#endif + +#ifdef WINAPI_FAMILY +# define open _open +# define read _read +# define write _write +# define close _close +#endif + +/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ +#if !defined(STDC99) && !defined(__CYGWIN__) && !defined(__MINGW__) && defined(_WIN32) +# if !defined(vsnprintf) +# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) +# define vsnprintf _vsnprintf +# endif +# endif +#endif + +/* unlike snprintf (which is required in C99), _snprintf does not guarantee + null termination of the result -- however this is only used in gzlib.c + where the result is assured to fit in the space provided */ +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +/* get errno and strerror definition */ +#ifndef NO_STRERROR +# include +# define zstrerror() strerror(errno) +#else +# define zstrerror() "stdio error (consult errno)" +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif + +/* default i/o buffer size -- double this for output when reading (this and + twice this must be able to fit in an unsigned type) */ +#ifndef GZBUFSIZE +# define GZBUFSIZE 131072 +#endif + +/* gzip modes, also provide a little integrity check on the passed structure */ +#define GZ_NONE 0 +#define GZ_READ 7247 +#define GZ_WRITE 31153 +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ + +/* values for gz_state how */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ + +/* internal gzip file state data structure */ +typedef struct { + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer (double-sized when writing) */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + int reset; /* true if a reset is pending after a Z_FINISH */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + PREFIX3(stream) strm; /* stream structure in-place (not a pointer) */ +} gz_state; +typedef gz_state *gz_statep; + +/* shared functions */ +void Z_INTERNAL gz_error(gz_state *, int, const char *); + +/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t + value -- needed when comparing unsigned to z_off64_t, which is signed + (possible z_off64_t types off_t, off64_t, and long are all signed) */ +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) + +#endif /* GZGUTS_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/gzlib.c b/internal-complibs/zlib-ng-2.1.2/gzlib.c new file mode 100644 index 000000000..e1290fc61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/gzlib.c @@ -0,0 +1,525 @@ +/* gzlib.c -- zlib functions common to reading and writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +#if defined(_WIN32) +# define LSEEK _lseeki64 +#else +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 +# define LSEEK lseek64 +#else +# define LSEEK lseek +#endif +#endif + +/* Local functions */ +static void gz_reset(gz_state *); +static gzFile gz_open(const void *, int, const char *); + +/* Reset gzip file state */ +static void gz_reset(gz_state *state) { + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + else /* for writing ... */ + state->reset = 0; /* no deflateReset pending */ + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ +} + +/* Open a gzip file either by name or file descriptor. */ +static gzFile gz_open(const void *path, int fd, const char *mode) { + gz_state *state; + size_t len; + int oflag; +#ifdef O_CLOEXEC + int cloexec = 0; +#endif +#ifdef O_EXCL + int exclusive = 0; +#endif + + /* check input */ + if (path == NULL) + return NULL; + + /* allocate gzFile structure to return */ + state = (gz_state *)zng_alloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ + + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) { + if (*mode >= '0' && *mode <= '9') { + state->level = *mode - '0'; + } else { + switch (*mode) { + case 'r': + state->mode = GZ_READ; + break; +#ifndef NO_GZCOMPRESS + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; +#endif + case '+': /* can't read and write at the same time */ + zng_free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; +#ifdef O_CLOEXEC + case 'e': + cloexec = 1; + break; +#endif +#ifdef O_EXCL + case 'x': + exclusive = 1; + break; +#endif + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + {} + } + } + mode++; + } + + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) { + zng_free(state); + return NULL; + } + + /* can't force transparent read */ + if (state->mode == GZ_READ) { + if (state->direct) { + zng_free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } + + /* save the path name for error messages */ +#ifdef WIDECHAR + if (fd == -2) { + len = wcstombs(NULL, (const wchar_t *)path, 0); + if (len == (size_t)-1) + len = 0; + } else +#endif + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) { + zng_free(state); + return NULL; + } +#ifdef WIDECHAR + if (fd == -2) + if (len) { + wcstombs(state->path, (const wchar_t *)path, len + 1); + } else { + *(state->path) = 0; + } + else +#endif + (void)snprintf(state->path, len + 1, "%s", (const char *)path); + + /* compute the flags for open() */ + oflag = +#ifdef O_LARGEFILE + O_LARGEFILE | +#endif +#ifdef O_BINARY + O_BINARY | +#endif +#ifdef O_CLOEXEC + (cloexec ? O_CLOEXEC : 0) | +#endif + (state->mode == GZ_READ ? + O_RDONLY : + (O_WRONLY | O_CREAT | +#ifdef O_EXCL + (exclusive ? O_EXCL : 0) | +#endif + (state->mode == GZ_WRITE ? + O_TRUNC : + O_APPEND))); + + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( +#if defined(_WIN32) + fd == -2 ? _wopen((const wchar_t *)path, oflag, 0666) : +#elif __CYGWIN__ + fd == -2 ? open(state->path, oflag, 0666) : +#endif + open((const char *)path, oflag, 0666)); + if (state->fd == -1) { + free(state->path); + zng_free(state); + return NULL; + } + if (state->mode == GZ_APPEND) { + LSEEK(state->fd, 0, SEEK_END); /* so gzoffset() is correct */ + state->mode = GZ_WRITE; /* simplify later checks */ + } + + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } + + /* initialize stream */ + gz_reset(state); + + /* return stream */ + return (gzFile)state; +} + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} + +#ifdef ZLIB_COMPAT +gzFile Z_EXPORT PREFIX4(gzopen)(const char *path, const char *mode) { + return gz_open(path, -1, mode); +} +#endif + +/* -- see zlib.h -- */ +gzFile Z_EXPORT PREFIX(gzdopen)(int fd, const char *mode) { + char *path; /* identifier for error messages */ + gzFile gz; + + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; + (void)snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + gz = gz_open(path, fd, mode); + free(path); + return gz; +} + +/* -- see zlib.h -- */ +#ifdef WIDECHAR +gzFile Z_EXPORT PREFIX(gzopen_w)(const wchar_t *path, const char *mode) { + return gz_open(path, -2, mode); +} +#endif + +int Z_EXPORT PREFIX(gzclose)(gzFile file) { +#ifndef NO_GZCOMPRESS + gz_state *state; + + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + return state->mode == GZ_READ ? PREFIX(gzclose_r)(file) : PREFIX(gzclose_w)(file); +#else + return PREFIX(gzclose_r)(file); +#endif +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzbuffer)(gzFile file, unsigned size) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; + + /* check and set requested size */ + if ((size << 1) < size) + return -1; /* need to be able to double it */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzrewind)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; +} + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzseek)(gzFile file, z_off64_t offset, int whence) { + unsigned n; + z_off64_t ret; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; + + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; + + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && state->x.pos + offset >= 0) { + ret = LSEEK(state->fd, offset - (z_off64_t)state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } + + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (PREFIX(gzrewind)(file) == -1) /* rewind, then skip to offset */ + return -1; + } + + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } + + /* request skip (if not zero) */ + if (offset) { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzseek)(gzFile file, z_off_t offset, int whence) { + z_off64_t ret; + + ret = PREFIX4(gzseek)(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gztell)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gztell)(gzFile file) { + + z_off64_t ret; + + ret = PREFIX4(gztell)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +z_off64_t Z_EXPORT PREFIX4(gzoffset)(gzFile file) { + z_off64_t offset; + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; + + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; +} + +/* -- see zlib.h -- */ +#ifdef ZLIB_COMPAT +z_off_t Z_EXPORT PREFIX(gzoffset)(gzFile file) { + z_off64_t ret; + + ret = PREFIX4(gzoffset)(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzeof)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; + + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; +} + +/* -- see zlib.h -- */ +const char * Z_EXPORT PREFIX(gzerror)(gzFile file, int *errnum) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; + + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); +} + +/* -- see zlib.h -- */ +void Z_EXPORT PREFIX(gzclearerr)(gzFile file) { + gz_state *state; + + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_state *)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; + + /* clear error and end-of-file */ + if (state->mode == GZ_READ) { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); +} + +/* Create an error message in allocated memory and set state->err and + state->msg accordingly. Free any previous error message already there. Do + not try to free or allocate space if the error is Z_MEM_ERROR (out of + memory). Simply save the error message as a static string. If there is an + allocation failure constructing the error message, then convert the error to + out of memory. */ +void Z_INTERNAL gz_error(gz_state *state, int err, const char *msg) { + /* free previously allocated message and clear */ + if (state->msg != NULL) { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } + + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; + + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; + + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; + + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) { + state->err = Z_MEM_ERROR; + return; + } + (void)snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, "%s%s%s", state->path, ": ", msg); +} diff --git a/internal-complibs/zlib-ng-2.1.2/gzread.c.in b/internal-complibs/zlib-ng-2.1.2/gzread.c.in new file mode 100644 index 000000000..67a21a3e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/gzread.c.in @@ -0,0 +1,602 @@ +/* gzread.c -- zlib functions for reading gzip files + * Copyright (C) 2004-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "gzguts.h" + +/* Local functions */ +static int gz_load(gz_state *, unsigned char *, unsigned, unsigned *); +static int gz_avail(gz_state *); +static int gz_look(gz_state *); +static int gz_decomp(gz_state *); +static int gz_fetch(gz_state *); +static int gz_skip(gz_state *, z_off64_t); +static size_t gz_read(gz_state *, void *, size_t); + +/* Use read() to load a buffer -- return -1 on error, otherwise 0. Read from + state->fd, and update state->eof, state->err, and state->msg as appropriate. + This function needs to loop on read(), since read() is not guaranteed to + read the number of bytes requested, depending on the type of descriptor. */ +static int gz_load(gz_state *state, unsigned char *buf, unsigned len, unsigned *have) { + ssize_t ret; + + *have = 0; + do { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += (unsigned)ret; + } while (*have < len); + if (ret < 0) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; +} + +/* Load up input buffer and set eof flag if last data loaded -- return -1 on + error, 0 otherwise. Note that the eof flag is set when the end of the input + file is reached, even though there may be unused data in the buffer. Once + that data has been used, no more attempts will be made to read the file. + If strm->avail_in != 0, then the current data is moved to the beginning of + the input buffer, and then the remainder of the buffer is loaded with the + available data from the input file. */ +static int gz_avail(gz_state *state) { + unsigned got; + PREFIX3(stream) *strm = &(state->strm); + + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) { + if (strm->avail_in) { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; +} + +/* Look for gzip header, set up for inflate or copy. state->x.have must be 0. + If this is the first time in, allocate required memory. state->how will be + left unchanged if there is no more input data available, will be set to COPY + if there is no gzip header and direct copying will be performed, or it will + be set to GZIP for decompression. If direct copying, then leftover input + data from the input buffer will be copied to the output buffer. In that + case, all further file reads will be directly to either the output buffer or + a user buffer. If decompressing, the inflate state will be initialized. + gz_look() will return 0 on success or -1 on failure. */ +static int gz_look(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + /* allocate read buffers and inflate memory */ + if (state->size == 0) { + /* allocate buffers */ + state->in = (unsigned char *)zng_alloc(state->want); + state->out = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL || state->out == NULL) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; + + /* allocate inflate memory */ + state->strm.zalloc = NULL; + state->strm.zfree = NULL; + state->strm.opaque = NULL; + state->strm.avail_in = 0; + state->strm.next_in = NULL; + if (PREFIX(inflateInit2)(&(state->strm), MAX_WBITS + 16) != Z_OK) { /* gunzip */ + zng_free(state->out); + zng_free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } + + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } + + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + a logical dilemma here when considering the case of a partially written + gzip file, to wit, if a single 31 byte is written, then we cannot tell + whether this is a single-byte file, or just a partially written gzip + file -- for here we assume that if a gzip file is being written, then + the header will be written in a single operation, so that reading a + single byte is sufficient indication that it is not a gzip file) */ + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) { + PREFIX(inflateReset)(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } + + /* no gzip header -- if we were decoding gzip before, then this is trailing + garbage. Ignore the trailing garbage and finish. */ + if (state->direct == 0) { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } + + /* doing raw i/o, copy any leftover input to output -- this assumes that + the output buffer is larger than the input buffer, which also assures + space for gzungetc() */ + state->x.next = state->out; + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + state->how = COPY; + state->direct = 1; + return 0; +} + +/* Decompress from input to the provided next_out and avail_out in the state. + On return, state->x.have and state->x.next point to the just decompressed + data. If the gzip stream completes, state->how is reset to LOOK to look for + the next gzip stream or raw data, once state->x.have is depleted. Returns 0 + on success, -1 on failure. */ +static int gz_decomp(gz_state *state) { + int ret = Z_OK; + unsigned had; + PREFIX3(stream) *strm = &(state->strm); + + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } + + /* decompress and handle errors */ + ret = PREFIX(inflate)(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { + gz_error(state, Z_STREAM_ERROR, "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); + + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; + + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; + + /* good decompression */ + return 0; +} + +/* Fetch data and put it in the output buffer. Assumes state->x.have is 0. + Data is either copied from the input file or decompressed from the input + file depending on state->how. If state->how is LOOK, then a gzip header is + looked for to determine whether to copy or decompress. Returns -1 on error, + otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the + end of the input file has been reached and all data has been processed. */ +static int gz_fetch(gz_state *state) { + PREFIX3(stream) *strm = &(state->strm); + + do { + switch (state->how) { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) + == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; +} + +/* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ +static int gz_skip(gz_state *state, z_off64_t len) { + unsigned n; + + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? + (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } else if (state->eof && state->strm.avail_in == 0) { + /* output buffer empty -- return if we're at the end of the input */ + break; + } else { + /* need more data to skip -- load up output buffer */ + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; +} + +/* Read len bytes into buf from file, or less than len up to the end of the + input. Return the number of bytes read. If zero is returned, either the + end of file was reached, or there was an error. state->err must be + consulted in that case to determine which. */ +static size_t gz_read(gz_state *state, void *buf, size_t len) { + size_t got; + unsigned n; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return 0; + } + + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do { + /* set n to the maximum amount of len that fits in an unsigned int */ + n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + + /* first just try copying data from the output buffer */ + if (state->x.have) { + if (state->x.have < n) + n = state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } + + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) { + state->past = 1; /* tried to read past end */ + break; + } + + /* need output data -- for small len or new stream load up our output + buffer */ + else if (state->how == LOOK || n < (state->size << 1)) { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return 0; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the + output buffer, allowing at least one gzungetc() to succeed */ + } + + /* large len -- read directly into user buffer */ + else if (state->how == COPY) { /* read directly */ + if (gz_load(state, (unsigned char *)buf, n, &n) == -1) + return 0; + } + + /* large len -- decompress directly into user buffer */ + else { /* state->how == GZIP */ + state->strm.avail_out = n; + state->strm.next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return 0; + n = state->x.have; + state->x.have = 0; + } + + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); + + /* return number of bytes read into user buffer */ + return got; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzread)(gzFile file, void *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in an int"); + return -1; + } + + /* read len or fewer bytes to buf */ + len = (unsigned)gz_read(state, buf, len); + + /* check for an error */ + if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + + /* return the number of bytes read (this is assured to fit in an int) */ + return (int)len; +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfread)(void *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return 0; + + /* compute bytes to read -- error on overflow */ + if (size && SIZE_MAX / size < nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + len = nitems * size; + + /* read len or fewer bytes to buf, return the number of full items read */ + return len ? gz_read(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +#undef @ZLIB_SYMBOL_PREFIX@gzgetc +#undef @ZLIB_SYMBOL_PREFIX@zng_gzgetc +int Z_EXPORT PREFIX(gzgetc)(gzFile file) { + unsigned char buf[1]; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* try output buffer (no need to check for skip request) */ + if (state->x.have) { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } + + /* nothing there -- try gz_read() */ + return gz_read(state, buf, 1) < 1 ? -1 : buf[0]; +} + +#ifdef ZLIB_COMPAT +int Z_EXPORT PREFIX(gzgetc_)(gzFile file) { + return PREFIX(gzgetc)(file); +} +#endif + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzungetc)(int c, gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = (unsigned char)c; + state->x.pos--; + state->past = 0; + return c; +} + +/* -- see zlib.h -- */ +char * Z_EXPORT PREFIX(gzgets)(gzFile file, char *buf, int len) { + unsigned left, n; + char *str; + unsigned char *eol; + gz_state *state; + + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_state *)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; + + /* process a skip request */ + if (state->seek) { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } + + /* copy output bytes up to new line or len - 1, whichever comes first -- + append a terminating zero to the string (we don't check for a zero in + the contents, let the user worry about that) */ + str = buf; + left = (unsigned)len - 1; + if (left) { + do { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } + + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; + + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); + } + + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzdirect)(gzFile file) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + + state = (gz_state *)file; + + /* if the state is not known, but we can find out, then do so (this is + mainly for right after a gzopen() or gzdopen()) */ + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); + + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_r)(gzFile file) { + int ret, err; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + + state = (gz_state *)file; + + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; + + /* free memory and close file */ + if (state->size) { + PREFIX(inflateEnd)(&(state->strm)); + zng_free(state->out); + zng_free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + zng_free(state); + return ret ? Z_ERRNO : err; +} diff --git a/internal-complibs/zlib-ng-2.1.2/gzwrite.c b/internal-complibs/zlib-ng-2.1.2/gzwrite.c new file mode 100644 index 000000000..08e0ce9aa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/gzwrite.c @@ -0,0 +1,526 @@ +/* gzwrite.c -- zlib functions for writing gzip files + * Copyright (C) 2004-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include +#include "gzguts.h" + +/* Local functions */ +static int gz_init(gz_state *); +static int gz_comp(gz_state *, int); +static int gz_zero(gz_state *, z_off64_t); +static size_t gz_write(gz_state *, void const *, size_t); + +/* Initialize state for writing a gzip file. Mark initialization by setting + state->size to non-zero. Return -1 on a memory allocation failure, or 0 on + success. */ +static int gz_init(gz_state *state) { + int ret; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate input buffer (double size for gzprintf) */ + state->in = (unsigned char *)zng_alloc(state->want << 1); + if (state->in == NULL) { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + memset(state->in, 0, state->want << 1); + + /* only need output buffer and deflate state if compressing */ + if (!state->direct) { + /* allocate output buffer */ + state->out = (unsigned char *)zng_alloc(state->want); + if (state->out == NULL) { + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = NULL; + strm->zfree = NULL; + strm->opaque = NULL; + ret = PREFIX(deflateInit2)(strm, state->level, Z_DEFLATED, MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) { + zng_free(state->out); + zng_free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + strm->next_in = NULL; + } + + /* mark state as initialized */ + state->size = state->want; + + /* initialize write buffer if compressing */ + if (!state->direct) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; +} + +/* Compress whatever is at avail_in and next_in and write to the output file. + Return -1 if there is an error writing to the output file or if gz_init() + fails to allocate memory, otherwise 0. flush is assumed to be a valid + deflate() flush value. If flush is Z_FINISH, then the deflate() state is + reset to start a new gzip stream. If gz->direct is true, then simply write + to the output file without compressing, and ignore flush. */ +static int gz_comp(gz_state *state, int flush) { + int ret; + ssize_t got; + unsigned have; + PREFIX3(stream) *strm = &(state->strm); + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; + + /* write directly if requested */ + if (state->direct) { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } + + /* check for a pending reset */ + if (state->reset) { + /* don't start a new gzip member unless there is data to write */ + if (strm->avail_in == 0) + return 0; + PREFIX(deflateReset)(strm); + state->reset = 0; + } + + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do { + /* write out current buffer contents if full, or if flushing, but if + doing Z_FINISH then don't write until we get to Z_STREAM_END */ + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && (flush != Z_FINISH || ret == Z_STREAM_END))) { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, (unsigned long)have)) < 0 || (unsigned)got != have)) { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = state->out; + } + state->x.next = strm->next_out; + } + + /* compress */ + have = strm->avail_out; + ret = PREFIX(deflate)(strm, flush); + if (ret == Z_STREAM_ERROR) { + gz_error(state, Z_STREAM_ERROR, "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); + + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + state->reset = 1; + /* all done, no errors */ + return 0; +} + +/* Compress len zeros to output. Return -1 on a write error or memory + allocation failure by gz_comp(), or 0 on success. */ +static int gz_zero(gz_state *state, z_off64_t len) { + int first; + unsigned n; + PREFIX3(stream) *strm = &(state->strm); + + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; + if (first) { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; +} + +/* 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. */ +static size_t gz_write(gz_state *state, void const *buf, size_t len) { + size_t put = len; + + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; + + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } + + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) { + /* copy to input buffer, compress when full */ + do { + unsigned have, copy; + + if (state->strm.avail_in == 0) + state->strm.next_in = state->in; + have = (unsigned)((state->strm.next_in + state->strm.avail_in) - + state->in); + copy = state->size - have; + if (copy > len) + copy = (unsigned)len; + memcpy(state->in + have, buf, copy); + state->strm.avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } else { + /* consume whatever's left in the input buffer */ + if (state->strm.avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + + /* directly compress user buffer to file */ + state->strm.next_in = (z_const unsigned char *) buf; + do { + unsigned n = (unsigned)-1; + if (n > len) + n = (unsigned)len; + state->strm.avail_in = n; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + len -= n; + } while (len); + } + + /* input was all buffered or compressed */ + return put; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzwrite)(gzFile file, void const *buf, unsigned len) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* since an int is returned, make sure len fits in one, otherwise return + with an error (this avoids a flaw in the interface) */ + if ((int)len < 0) { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } + + /* write len bytes from buf (the return value will fit in an int) */ + return (int)gz_write(state, buf, len); +} + +/* -- see zlib.h -- */ +size_t Z_EXPORT PREFIX(gzfwrite)(void const *buf, size_t size, size_t nitems, gzFile file) { + size_t len; + gz_state *state; + + /* Exit early if size is zero, also prevents potential division by zero */ + if (size == 0) + return 0; + + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; + + /* compute bytes to read -- error on overflow */ + len = nitems * size; + if (len / size != nitems) { + gz_error(state, Z_STREAM_ERROR, "request does not fit in a size_t"); + return 0; + } + + /* write len bytes to buf, return the number of full items written */ + return len ? gz_write(state, buf, len) / size : 0; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputc)(gzFile file, int c) { + unsigned have; + unsigned char buf[1]; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } + + /* try writing to input buffer for speed (state->size == 0 if buffer not + initialized) */ + if (state->size) { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) { + state->in[have] = (unsigned char)c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } + + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = (unsigned char)c; + if (gz_write(state, buf, 1) != 1) + return -1; + return c & 0xff; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzputs)(gzFile file, const char *s) { + size_t len, put; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; + + /* write string */ + len = strlen(s); + if ((int)len < 0 || (unsigned)len != len) { + gz_error(state, Z_STREAM_ERROR, "string length does not fit in int"); + return -1; + } + put = gz_write(state, s, len); + return put < len ? -1 : (int)len; +} + +/* -- see zlib.h -- */ +int Z_EXPORTVA PREFIX(gzvprintf)(gzFile file, const char *format, va_list va) { + int len; + unsigned left; + char *next; + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return state->err; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* do the printf() into the input buffer, put length in len -- the input + buffer is double-sized just for this function, so there is guaranteed to + be state->size bytes available after the current contents */ + if (strm->avail_in == 0) + strm->next_in = state->in; + next = (char *)(state->in + (strm->next_in - state->in) + strm->avail_in); + next[state->size - 1] = 0; + len = vsnprintf(next, state->size, format, va); + + /* check that printf() results fit in buffer */ + if (len == 0 || (unsigned)len >= state->size || next[state->size - 1] != 0) + return 0; + + /* update buffer and position, compress first half if past that */ + strm->avail_in += (unsigned)len; + state->x.pos += len; + if (strm->avail_in >= state->size) { + left = strm->avail_in - state->size; + strm->avail_in = state->size; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return state->err; + memmove(state->in, state->in + state->size, left); + strm->next_in = state->in; + strm->avail_in = left; + } + return len; +} + +int Z_EXPORTVA PREFIX(gzprintf)(gzFile file, const char *format, ...) { + va_list va; + int ret; + + va_start(va, format); + ret = PREFIX(gzvprintf)(file, format, va); + va_end(va); + return ret; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzflush)(gzFile file, int flush) { + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; + + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* compress remaining data with requested flush */ + (void)gz_comp(state, flush); + return state->err; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzsetparams)(gzFile file, int level, int strategy) { + gz_state *state; + PREFIX3(stream) *strm; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + strm = &(state->strm); + + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK || state->direct) + return Z_STREAM_ERROR; + + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return state->err; + } + + /* change compression parameters for subsequent input */ + if (state->size) { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_BLOCK) == -1) + return state->err; + PREFIX(deflateParams)(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; +} + +/* -- see zlib.h -- */ +int Z_EXPORT PREFIX(gzclose_w)(gzFile file) { + int ret = Z_OK; + gz_state *state; + + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_state *)file; + + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; + + /* check for seek request */ + if (state->seek) { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } + + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) { + if (!state->direct) { + (void)PREFIX(deflateEnd)(&(state->strm)); + zng_free(state->out); + } + zng_free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + zng_free(state); + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.2/infback.c b/internal-complibs/zlib-ng-2.1.2/infback.c new file mode 100644 index 000000000..9f5042b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/infback.c @@ -0,0 +1,511 @@ +/* infback.c -- inflate using a call-back interface + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + This code is largely copied from inflate.c. Normally either infback.o or + inflate.o would be linked into an application--not both. The interface + with inffast.c is retained so that optimized assembler-coded versions of + inflate_fast() can be used with either inflate.c or infback.c. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateBackInit +#endif + +/* + strm provides memory allocation functions in zalloc and zfree, or + NULL to use the library memory allocation functions. + + windowBits is in the range 8..15, and window is a user-supplied + window and output buffer that is 2**windowBits bytes. + + This function is hidden in ZLIB_COMPAT builds. + */ +int32_t ZNG_CONDEXPORT PREFIX(inflateBackInit)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window) { + struct inflate_state *state; + + if (strm == NULL || window == NULL || windowBits < MIN_WBITS || windowBits > MAX_WBITS) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->dmax = 32768U; + state->wbits = (unsigned int)windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + state->sane = 1; + state->chunksize = functable.chunksize(); + return Z_OK; +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateBackInit_)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window, + const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateBackInit)(strm, windowBits, window); +} + +/* + Private macros for inflateBack() + Look in inflate_p.h for macros shared with inflate() +*/ + +/* Assure that some input is available. If input is requested, but denied, + then return a Z_BUF_ERROR from inflateBack(). */ +#define PULL() \ + do { \ + if (have == 0) { \ + have = in(in_desc, &next); \ + if (have == 0) { \ + next = NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* Get a byte of input into the bit accumulator, or return from inflateBack() + with an error if there is no input available. */ +#define PULLBYTE() \ + do { \ + PULL(); \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* Assure that some output space is available, by writing out the window + if it's full. If the write fails, return from inflateBack() with a + Z_BUF_ERROR. */ +#define ROOM() \ + do { \ + if (left == 0) { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) + +/* + strm provides the memory allocation functions and window buffer on input, + and provides information on the unused input on return. For Z_DATA_ERROR + returns, strm will also provide an error message. + + in() and out() are the call-back input and output functions. When + inflateBack() needs more input, it calls in(). When inflateBack() has + filled the window with output, or when it completes with data in the + window, it calls out() to write out the data. The application must not + change the provided input until in() is called again or inflateBack() + returns. The application must not change the window/output buffer until + inflateBack() returns. + + in() and out() are called with a descriptor parameter provided in the + inflateBack() call. This parameter can be a structure that provides the + information required to do the read or write, as well as accumulated + information on the input and output such as totals and check values. + + in() should return zero on failure. out() should return non-zero on + failure. If either in() or out() fails, than inflateBack() returns a + Z_BUF_ERROR. strm->next_in can be checked for NULL to see whether it + was in() or out() that caused in the error. Otherwise, inflateBack() + returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format + error, or Z_MEM_ERROR if it could not allocate memory for the state. + inflateBack() can also return Z_STREAM_ERROR if the input parameters + are not correct, i.e. strm is NULL or the state was not initialized. + */ +int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in_desc, out_func out, void *out_desc) { + struct inflate_state *state; + z_const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + /* Check that the strm exists and that the state was initialized */ + if (strm == NULL || strm->state == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* Reset the state */ + strm->msg = NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; + + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) { + case TYPE: + /* determine and dispatch block type */ + if (state->last) { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + + /* copy stored block from input to output */ + while (state->length != 0) { + copy = state->length; + PULL(); + ROOM(); + copy = MIN(copy, have); + copy = MIN(copy, left); + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && + left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + functable.inflate_fast(strm, state->wsize); + LOAD(); + break; + } + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code -- get extra bits, if any */ + state->extra = (here.op & MAX_BITS); + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } +#ifdef INFLATE_STRICT + if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + + /* copy match from window to output */ + do { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) { + from = put + copy; + copy = left - copy; + } else { + from = put - state->offset; + copy = left; + } + copy = MIN(copy, state->length); + state->length -= copy; + left -= copy; + do { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } + + /* Write leftover output and return unused input */ + inf_leave: + if (left < state->wsize) { + if (out(out_desc, state->window, state->wsize - left) && (ret == Z_STREAM_END)) { + ret = Z_BUF_ERROR; + } + } + strm->next_in = next; + strm->avail_in = have; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateBackEnd)(PREFIX3(stream) *strm) { + if (strm == NULL || strm->state == NULL || strm->zfree == NULL) + return Z_STREAM_ERROR; + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.2/inffast_tpl.h b/internal-complibs/zlib-ng-2.1.2/inffast_tpl.h new file mode 100644 index 000000000..9ddd187d8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inffast_tpl.h @@ -0,0 +1,326 @@ +/* inffast.c -- fast decoding + * Copyright (C) 1995-2017 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zendian.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "functable.h" + +/* + Decode literal, length, and distance codes and write out the resulting + literal and match bytes until either not enough input or output is + available, an end-of-block is encountered, or a data error is encountered. + When large enough input and output buffers are supplied to inflate(), for + example, a 16K input buffer and a 64K output buffer, more than 95% of the + inflate execution time is spent in this routine. + + Entry assumptions: + + state->mode == LEN + strm->avail_in >= INFLATE_FAST_MIN_HAVE + strm->avail_out >= INFLATE_FAST_MIN_LEFT + start >= strm->avail_out + state->bits < 8 + + On return, state->mode is one of: + + LEN -- ran out of enough output space or enough available input + TYPE -- reached end of block code, inflate() to interpret next block + BAD -- error in block data + + Notes: + + - The maximum input bits used by a length/distance pair is 15 bits for the + length code, 5 bits for the length extra, 15 bits for the distance code, + and 13 bits for the distance extra. This totals 48 bits, or six bytes. + Therefore if strm->avail_in >= 6, then there is enough input to avoid + checking for available input while decoding. + + - On some architectures, it can be significantly faster (e.g. up to 1.2x + faster on x86_64) to load from strm->next_in 64 bits, or 8 bytes, at a + time, so INFLATE_FAST_MIN_HAVE == 8. + + - The maximum bytes that a single length/distance pair can output is 258 + bytes, which is the maximum length that can be coded. inflate_fast() + requires strm->avail_out >= 258 for each loop to avoid checking for + output space. + */ +void Z_INTERNAL INFLATE_FAST(PREFIX3(stream) *strm, uint32_t start) { + /* start: inflate()'s starting value for strm->avail_out */ + struct inflate_state *state; + z_const unsigned char *in; /* local strm->next_in */ + const unsigned char *last; /* have enough input while in < last */ + unsigned char *out; /* local strm->next_out */ + unsigned char *beg; /* inflate()'s initial strm->next_out */ + unsigned char *end; /* while out < end, enough space available */ + unsigned char *safe; /* can use chunkcopy provided out < safe */ +#ifdef INFLATE_STRICT + unsigned dmax; /* maximum distance from zlib header */ +#endif + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if wsize != 0 */ + + /* hold is a local copy of strm->hold. By default, hold satisfies the same + invariants that strm->hold does, namely that (hold >> bits) == 0. This + invariant is kept by loading bits into hold one byte at a time, like: + + hold |= next_byte_of_input << bits; in++; bits += 8; + + If we need to ensure that bits >= 15 then this code snippet is simply + repeated. Over one iteration of the outermost do/while loop, this + happens up to six times (48 bits of input), as described in the NOTES + above. + + However, on some little endian architectures, it can be significantly + faster to load 64 bits once instead of 8 bits six times: + + if (bits <= 16) { + hold |= next_8_bytes_of_input << bits; in += 6; bits += 48; + } + + Unlike the simpler one byte load, shifting the next_8_bytes_of_input + by bits will overflow and lose those high bits, up to 2 bytes' worth. + The conservative estimate is therefore that we have read only 6 bytes + (48 bits). Again, as per the NOTES above, 48 bits is sufficient for the + rest of the iteration, and we will not need to load another 8 bytes. + + Inside this function, we no longer satisfy (hold >> bits) == 0, but + this is not problematic, even if that overflow does not land on an 8 bit + byte boundary. Those excess bits will eventually shift down lower as the + Huffman decoder consumes input, and when new input bits need to be loaded + into the bits variable, the same input bits will be or'ed over those + existing bits. A bitwise or is idempotent: (a | b | b) equals (a | b). + Note that we therefore write that load operation as "hold |= etc" and not + "hold += etc". + + Outside that loop, at the end of the function, hold is bitwise and'ed + with (1<hold >> state->bits) == 0. + */ + uint64_t hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const *lcode; /* local strm->lencode */ + code const *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + const code *here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char *from; /* where to copy match from */ + unsigned extra_safe; /* copy chunks safely in all cases */ + + /* copy state to local variables */ + state = (struct inflate_state *)strm->state; + in = strm->next_in; + last = in + (strm->avail_in - (INFLATE_FAST_MIN_HAVE - 1)); + out = strm->next_out; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - (INFLATE_FAST_MIN_LEFT - 1)); + safe = out + strm->avail_out; +#ifdef INFLATE_STRICT + dmax = state->dmax; +#endif + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; + + /* Detect if out and window point to the same memory allocation. In this instance it is + necessary to use safe chunk copy functions to prevent overwriting the window. If the + window is overwritten then future matches with far distances will fail to copy correctly. */ + extra_safe = (wsize != 0 && out >= window && out + INFLATE_FAST_MIN_LEFT <= window + wsize); + +#define REFILL() do { \ + hold |= load_64_bits(in, bits); \ + in += 7; \ + in -= ((bits >> 3) & 7); \ + bits |= 56; \ + } while (0) + + /* decode literals and length/distances until end-of-block or not enough + input data or output space */ + do { + REFILL(); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + if (here->op == 0) { + *out++ = (unsigned char)(here->val); + DROPBITS(here->bits); + here = lcode + (hold & lmask); + } + } + dolen: + DROPBITS(here->bits); + op = here->op; + if (op == 0) { /* literal */ + Tracevv((stderr, here->val >= 0x20 && here->val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here->val)); + *out++ = (unsigned char)(here->val); + } else if (op & 16) { /* length base */ + len = here->val; + op &= MAX_BITS; /* number of extra bits */ + len += BITS(op); + DROPBITS(op); + Tracevv((stderr, "inflate: length %u\n", len)); + here = dcode + (hold & dmask); + if (bits < MAX_BITS + MAX_DIST_EXTRA_BITS) { + REFILL(); + } + dodist: + DROPBITS(here->bits); + op = here->op; + if (op & 16) { /* distance base */ + dist = here->val; + op &= MAX_BITS; /* number of extra bits */ + dist += BITS(op); +#ifdef INFLATE_STRICT + if (dist > dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + DROPBITS(op); + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + if (len <= op - whave) { + do { + *out++ = 0; + } while (--len); + continue; + } + len -= op - whave; + do { + *out++ = 0; + } while (--op > whave); + if (op == 0) { + from = out - dist; + do { + *out++ = *from++; + } while (--len); + continue; + } +#endif + } + from = window; + if (wnext == 0) { /* very common case */ + from += wsize - op; + } else if (wnext >= op) { /* contiguous in window */ + from += wnext - op; + } else { /* wrap around window */ + op -= wnext; + from += wsize - op; + if (op < len) { /* some from end of window */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + from = window; /* more from start of window */ + op = wnext; + /* This (rare) case can create a situation where + the first chunkcopy below must be checked. + */ + } + } + if (op < len) { /* still need some from output */ + len -= op; + out = chunkcopy_safe(out, from, op, safe); + out = CHUNKUNROLL(out, &dist, &len); + out = chunkcopy_safe(out, out - dist, len, safe); + } else { + out = chunkcopy_safe(out, from, len, safe); + } + } else if (extra_safe) { + /* Whole reference is in range of current output. */ + if (dist >= len || dist >= state->chunksize) + out = chunkcopy_safe(out, out - dist, len, safe); + else + out = CHUNKMEMSET_SAFE(out, dist, len, (unsigned)((safe - out) + 1)); + } else { + /* Whole reference is in range of current output. No range checks are + necessary because we start with room for at least 258 bytes of output, + so unroll and roundoff operations can write beyond `out+len` so long + as they stay within 258 bytes of `out`. + */ + if (dist >= len || dist >= state->chunksize) + out = CHUNKCOPY(out, out - dist, len); + else + out = CHUNKMEMSET(out, dist, len); + } + } else if ((op & 64) == 0) { /* 2nd level distance code */ + here = dcode + here->val + BITS(op); + goto dodist; + } else { + SET_BAD("invalid distance code"); + break; + } + } else if ((op & 64) == 0) { /* 2nd level length code */ + here = lcode + here->val + BITS(op); + goto dolen; + } else if (op & 32) { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } else { + SET_BAD("invalid literal/length code"); + break; + } + } while (in < last && out < end); + + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (UINT64_C(1) << bits) - 1; + + /* update state and return */ + strm->next_in = in; + strm->next_out = out; + strm->avail_in = (unsigned)(in < last ? (INFLATE_FAST_MIN_HAVE - 1) + (last - in) + : (INFLATE_FAST_MIN_HAVE - 1) - (in - last)); + strm->avail_out = (unsigned)(out < end ? (INFLATE_FAST_MIN_LEFT - 1) + (end - out) + : (INFLATE_FAST_MIN_LEFT - 1) - (out - end)); + + Assert(bits <= 32, "Remaining bits greater than 32"); + state->hold = (uint32_t)hold; + state->bits = bits; + return; +} + +/* + inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): + - Using bit fields for code structure + - Different op definition to avoid & for extra bits (do & for table bits) + - Three separate decoding do-loops for direct, window, and wnext == 0 + - Special case for distance > 1 copies to do overlapped load and store copy + - Explicit branch predictions (based on measured branch probabilities) + - Deferring match copy and interspersed it with decoding subsequent codes + - Swapping literal/length else + - Swapping window/direct else + - Larger unrolled copy loops (three is about right) + - Moving len -= 3 statement into middle of loop + */ diff --git a/internal-complibs/zlib-ng-2.1.2/inffixed_tbl.h b/internal-complibs/zlib-ng-2.1.2/inffixed_tbl.h new file mode 100644 index 000000000..7292fa06e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inffixed_tbl.h @@ -0,0 +1,94 @@ +/* inffixed_tbl.h -- table for decoding fixed codes + * Generated automatically by makefixed(). + */ + +/* WARNING: this file should *not* be used by applications. + * It is part of the implementation of this library and is + * subject to change. Applications should only use zlib.h. + */ + +static const code lenfix[512] = { + {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, + {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, + {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, + {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, + {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, + {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, + {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, + {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, + {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, + {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, + {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, + {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, + {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, + {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, + {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, + {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, + {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, + {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, + {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, + {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, + {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, + {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, + {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, + {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, + {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, + {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, + {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, + {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, + {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, + {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, + {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, + {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, + {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, + {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, + {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, + {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, + {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, + {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, + {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, + {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, + {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, + {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, + {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, + {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, + {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, + {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, + {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, + {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, + {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, + {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, + {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, + {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, + {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, + {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, + {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, + {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, + {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, + {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, + {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, + {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, + {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, + {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, + {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, + {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, + {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, + {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, + {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, + {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, + {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, + {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, + {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, + {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, + {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, + {0,9,255} +}; + +static const code distfix[32] = { + {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, + {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, + {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, + {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, + {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, + {22,5,193},{64,5,0} +}; diff --git a/internal-complibs/zlib-ng-2.1.2/inflate.c b/internal-complibs/zlib-ng-2.1.2/inflate.c new file mode 100644 index 000000000..0cbed041d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inflate.c @@ -0,0 +1,1408 @@ +/* inflate.c -- zlib decompression + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "inflate_p.h" +#include "inffixed_tbl.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef inflateInit +# undef inflateInit2 +#endif + +/* function prototypes */ +static int inflateStateCheck(PREFIX3(stream) *strm); +static int updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum); +static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t len); + +static inline void inf_chksum_cpy(PREFIX3(stream) *strm, uint8_t *dst, + const uint8_t *src, uint32_t copy) { + if (!copy) return; + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold_copy(&state->crc_fold, dst, src, copy); + } else +#endif + { + strm->adler = state->check = functable.adler32_fold_copy(state->check, dst, src, copy); + } +} + +static inline void inf_chksum(PREFIX3(stream) *strm, const uint8_t *src, uint32_t len) { + struct inflate_state *state = (struct inflate_state*)strm->state; +#ifdef GUNZIP + if (state->flags) { + functable.crc32_fold(&state->crc_fold, src, len, 0); + } else +#endif + { + strm->adler = state->check = functable.adler32(state->check, src, len); + } +} + +static int inflateStateCheck(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->zalloc == NULL || strm->zfree == NULL) + return 1; + state = (struct inflate_state *)strm->state; + if (state == NULL || state->strm != strm || state->mode < HEAD || state->mode > SYNC) + return 1; + return 0; +} + +int32_t Z_EXPORT PREFIX(inflateResetKeep)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->check = ADLER32_INITIAL_VALUE; + state->last = 0; + state->havedict = 0; + state->flags = -1; + state->dmax = 32768U; + state->head = NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + INFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + Tracev((stderr, "inflate: reset\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateReset)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return PREFIX(inflateResetKeep)(strm); +} + +int32_t Z_EXPORT PREFIX(inflateReset2)(PREFIX3(stream) *strm, int32_t windowBits) { + int wrap; + struct inflate_state *state; + + /* get the state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) { + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; + } else { + wrap = (windowBits >> 4) + 5; +#ifdef GUNZIP + if (windowBits < 48) + windowBits &= MAX_WBITS; +#endif + } + + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < MIN_WBITS || windowBits > MAX_WBITS)) + return Z_STREAM_ERROR; + if (state->window != NULL && state->wbits != (unsigned)windowBits) { + ZFREE_WINDOW(strm, state->window); + state->window = NULL; + } + + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return PREFIX(inflateReset)(strm); +} + +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(inflateInit2)(PREFIX3(stream) *strm, int32_t windowBits) { + int32_t ret; + struct inflate_state *state; + + if (strm == NULL) + return Z_STREAM_ERROR; + strm->msg = NULL; /* in case we return an error */ + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + state = ZALLOC_INFLATE_STATE(strm); + if (state == NULL) + return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state *)state; + state->strm = strm; + state->window = NULL; + state->mode = HEAD; /* to pass state test in inflateReset2() */ + state->chunksize = functable.chunksize(); + ret = PREFIX(inflateReset2)(strm, windowBits); + if (ret != Z_OK) { + ZFREE_STATE(strm, state); + strm->state = NULL; + } + return ret; +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(inflateInit)(PREFIX3(stream) *strm) { + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit_)(PREFIX3(stream) *strm, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, DEF_WBITS); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(inflateInit2_)(PREFIX3(stream) *strm, int32_t windowBits, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(inflateInit2)(strm, windowBits); +} + +int32_t Z_EXPORT PREFIX(inflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (bits == 0) + return Z_OK; + INFLATE_PRIME_HOOK(strm, bits, value); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + if (bits < 0) { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + (unsigned int)bits > 32) + return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += (unsigned)value << state->bits; + state->bits += (unsigned int)bits; + return Z_OK; +} + +/* + Return state with length and distance decoding tables and index sizes set to + fixed code decoding. This returns fixed tables from inffixed_tbl.h. + */ + +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state) { + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state) { + /* if it hasn't been done already, allocate space for the window */ + if (state->window == NULL) { + unsigned wsize = 1U << state->wbits; + state->window = (unsigned char *)ZALLOC_WINDOW(state->strm, wsize + state->chunksize, sizeof(unsigned char)); + if (state->window == NULL) + return Z_MEM_ERROR; +#ifdef Z_MEMORY_SANITIZER + /* This is _not_ to subvert the memory sanitizer but to instead unposion some + data we willingly and purposefully load uninitialized into vector registers + in order to safely read the last < chunksize bytes of the window. */ + __msan_unpoison(state->window + wsize, state->chunksize); +#endif + } + + /* if window not in use yet, initialize */ + if (state->wsize == 0) { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } + + return Z_OK; +} + +/* + Update the window with the last wsize (normally 32K) bytes written before + returning. If window does not exist yet, create it. This is only called + when a window is already in use, or when output has been written during this + inflate call, but the end of the deflate stream has not been reached yet. + It is also called to create a window for dictionary data when a dictionary + is loaded. + + Providing output buffers larger than 32K to inflate() should provide a speed + advantage, since only the last 32K of output is copied to the sliding window + upon return from inflate(), and since all distances after the first 32K of + output will fall in the output data, making match copies simpler and faster. + The advantage may be dependent on the size of the processor's data caches. + */ +static int32_t updatewindow(PREFIX3(stream) *strm, const uint8_t *end, uint32_t len, int32_t cksum) { + struct inflate_state *state; + uint32_t dist; + + state = (struct inflate_state *)strm->state; + + if (PREFIX(inflate_ensure_window)(state)) return 1; + + /* len state->wsize or less output bytes into the circular window */ + if (len >= state->wsize) { + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * it (s/390 being the primary exception to this. Also, for now, do the adler checksums + * if not a gzip based header. The inline adler checksums will come in the near future, + * possibly the next commit */ + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + /* We have to split the checksum over non-copied and copied bytes */ + if (len > state->wsize) + inf_chksum(strm, end - len, len - state->wsize); + inf_chksum_cpy(strm, state->window, end - state->wsize, state->wsize); + } else { + memcpy(state->window, end - state->wsize, state->wsize); + } + + state->wnext = 0; + state->whave = state->wsize; + } else { + dist = state->wsize - state->wnext; + /* Only do this if the caller specifies to checksum bytes AND the platform requires + * We need to maintain the correct order here for the checksum */ + dist = MIN(dist, len); + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window + state->wnext, end - len, dist); + } else { + memcpy(state->window + state->wnext, end - len, dist); + } + len -= dist; + if (len) { + if (INFLATE_NEED_CHECKSUM(strm) && cksum) { + inf_chksum_cpy(strm, state->window, end - len, len); + } else { + memcpy(state->window, end - len, len); + } + + state->wnext = len; + state->whave = state->wsize; + } else { + state->wnext += dist; + if (state->wnext == state->wsize) + state->wnext = 0; + if (state->whave < state->wsize) + state->whave += dist; + } + } + return 0; +} + +/* + Private macros for inflate() + Look in inflate_p.h for macros shared with inflateBack() +*/ + +/* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ +#define PULLBYTE() \ + do { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += ((unsigned)(*next++) << bits); \ + bits += 8; \ + } while (0) + +/* + inflate() uses a state machine to process as much input data and generate as + much output data as possible before returning. The state machine is + structured roughly as follows: + + for (;;) switch (state) { + ... + case STATEn: + if (not enough input data or output space to make progress) + return; + ... make progress ... + state = STATEm; + break; + ... + } + + so when inflate() is called again, the same case is attempted again, and + if the appropriate resources are provided, the machine proceeds to the + next state. The NEEDBITS() macro is usually the way the state evaluates + whether it can proceed or should return. NEEDBITS() does the return if + the requested bits are not available. The typical use of the BITS macros + is: + + NEEDBITS(n); + ... do something with BITS(n) ... + DROPBITS(n); + + where NEEDBITS(n) either returns from inflate() if there isn't enough + input left to load n bits into the accumulator, or it continues. BITS(n) + gives the low n bits in the accumulator. When done, DROPBITS(n) drops + the low n bits off the accumulator. INITBITS() clears the accumulator + and sets the number of available bits to zero. BYTEBITS() discards just + enough bits to put the accumulator on a byte boundary. After BYTEBITS() + and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. + + NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return + if there is no input available. The decoding of variable length codes uses + PULLBYTE() directly in order to pull just enough bytes to decode the next + code, and no more. + + Some states loop until they get enough input, making sure that enough + state information is maintained to continue the loop where it left off + if NEEDBITS() returns in the loop. For example, want, need, and keep + would all have to actually be part of the saved state in case NEEDBITS() + returns: + + case STATEw: + while (want < need) { + NEEDBITS(n); + keep[want++] = BITS(n); + DROPBITS(n); + } + state = STATEx; + case STATEx: + + As shown above, if the next state is also the next case, then the break + is omitted. + + A state may also return if there is not enough output space available to + complete that state. Those states are copying stored data, writing a + literal byte, and copying a matching string. + + When returning, a "goto inf_leave" is used to update the total counters, + update the check value, and determine whether any progress has been made + during that inflate() call in order to return the proper return code. + Progress is defined as a change in either strm->avail_in or strm->avail_out. + When there is a window, goto inf_leave will update the window with the last + output written. If a goto inf_leave occurs in the middle of decompression + and there is no window currently, goto inf_leave will create one and copy + output to the window for the next call of inflate(). + + In this implementation, the flush parameter of inflate() only affects the + return code (per zlib.h). inflate() always writes as much as possible to + strm->next_out, given the space available and the provided input--the effect + documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers + the allocation of and copying into a sliding window until necessary, which + provides the effect documented in zlib.h for Z_FINISH when the entire input + stream available. So the only thing the flush parameter actually does is: + when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it + will return Z_BUF_ERROR if it has not reached the end of the stream. + */ + +int32_t Z_EXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int32_t flush) { + struct inflate_state *state; + const unsigned char *next; /* next input */ + unsigned char *put; /* next output */ + unsigned have, left; /* available input and output */ + uint32_t hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + uint32_t in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int32_t ret; /* return code */ +#ifdef GUNZIP + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ +#endif + static const uint16_t order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + + if (inflateStateCheck(strm) || strm->next_out == NULL || + (strm->next_in == NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; + + state = (struct inflate_state *)strm->state; + if (state->mode == TYPE) /* skip check */ + state->mode = TYPEDO; + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) { + case HEAD: + if (state->wrap == 0) { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); +#ifdef GUNZIP + if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ + if (state->wbits == 0) + state->wbits = MAX_WBITS; + state->check = CRC32_INITIAL_VALUE; + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + if (state->head != NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ +#else + if ( +#endif + ((BITS(8) << 8) + (hold >> 8)) % 31) { + SET_BAD("incorrect header check"); + break; + } + if (BITS(4) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + if (len > MAX_WBITS || len > state->wbits) { + SET_BAD("invalid window size"); + break; + } + state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; +#ifdef GUNZIP + + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) { + SET_BAD("unknown compression method"); + break; + } + if (state->flags & 0xe000) { + SET_BAD("unknown header flags set"); + break; + } + if (state->head != NULL) + state->head->text = (int)((hold >> 8) & 1); + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + Z_FALLTHROUGH; + + case TIME: + NEEDBITS(32); + if (state->head != NULL) + state->head->time = hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + Z_FALLTHROUGH; + + case OS: + NEEDBITS(16); + if (state->head != NULL) { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + Z_FALLTHROUGH; + + case EXLEN: + if (state->flags & 0x0400) { + NEEDBITS(16); + state->length = (uint16_t)hold; + if (state->head != NULL) + state->head->extra_len = (uint16_t)hold; + if ((state->flags & 0x0200) && (state->wrap & 4)) + CRC2(state->check, hold); + INITBITS(); + } else if (state->head != NULL) { + state->head->extra = NULL; + } + state->mode = EXTRA; + Z_FALLTHROUGH; + + case EXTRA: + if (state->flags & 0x0400) { + copy = state->length; + if (copy > have) + copy = have; + if (copy) { + if (state->head != NULL && state->head->extra != NULL) { + len = state->head->extra_len - state->length; + if (len < state->head->extra_max) { + memcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? + state->head->extra_max - len : copy); + } + } + if ((state->flags & 0x0200) && (state->wrap & 4)) { + state->check = PREFIX(crc32)(state->check, next, copy); + } + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) + goto inf_leave; + } + state->length = 0; + state->mode = NAME; + Z_FALLTHROUGH; + + case NAME: + if (state->flags & 0x0800) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->name != NULL && state->length < state->head->name_max) + state->head->name[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->name = NULL; + } + state->length = 0; + state->mode = COMMENT; + Z_FALLTHROUGH; + + case COMMENT: + if (state->flags & 0x1000) { + if (have == 0) goto inf_leave; + copy = 0; + do { + len = (unsigned)(next[copy++]); + if (state->head != NULL && state->head->comment != NULL + && state->length < state->head->comm_max) + state->head->comment[state->length++] = (unsigned char)len; + } while (len && copy < have); + if ((state->flags & 0x0200) && (state->wrap & 4)) + state->check = PREFIX(crc32)(state->check, next, copy); + have -= copy; + next += copy; + if (len) + goto inf_leave; + } else if (state->head != NULL) { + state->head->comment = NULL; + } + state->mode = HCRC; + Z_FALLTHROUGH; + + case HCRC: + if (state->flags & 0x0200) { + NEEDBITS(16); + if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + SET_BAD("header crc mismatch"); + break; + } + INITBITS(); + } + if (state->head != NULL) { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + /* compute crc32 checksum if not in raw mode */ + if ((state->wrap & 4) && state->flags) + strm->adler = state->check = functable.crc32_fold_reset(&state->crc_fold); + state->mode = TYPE; + break; +#endif + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + Z_FALLTHROUGH; + + case DICT: + if (state->havedict == 0) { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = ADLER32_INITIAL_VALUE; + state->mode = TYPE; + Z_FALLTHROUGH; + + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case TYPEDO: + /* determine and dispatch block type */ + INFLATE_TYPEDO_HOOK(strm, flush); /* hook for IBM Z DFLTCC */ + if (state->last) { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + PREFIX(fixedtables)(state); + Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + SET_BAD("invalid block type"); + } + DROPBITS(2); + break; + + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { + SET_BAD("invalid stored block lengths"); + break; + } + state->length = (uint16_t)hold; + Tracev((stderr, "inflate: stored length %u\n", state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case COPY_: + state->mode = COPY; + Z_FALLTHROUGH; + + case COPY: + /* copy stored block from input to output */ + copy = state->length; + if (copy) { + copy = MIN(copy, have); + copy = MIN(copy, left); + if (copy == 0) + goto inf_leave; + memcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); +#ifndef PKZIP_BUG_WORKAROUND + if (state->nlen > 286 || state->ndist > 30) { + SET_BAD("too many length or distance symbols"); + break; + } +#endif + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + Z_FALLTHROUGH; + + case LENLENS: + /* get code length code lengths (not a typo) */ + while (state->have < state->ncode) { + NEEDBITS(3); + state->lens[order[state->have++]] = (uint16_t)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 7; + ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid code lengths set"); + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + Z_FALLTHROUGH; + + case CODELENS: + /* get length and distance code code lengths */ + while (state->have < state->nlen + state->ndist) { + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) break; + PULLBYTE(); + } + if (here.val < 16) { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } else { + if (here.val == 16) { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) { + SET_BAD("invalid bit length repeat"); + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } else if (here.val == 17) { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } else { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) { + SET_BAD("invalid bit length repeat"); + break; + } + while (copy) { + --copy; + state->lens[state->have++] = (uint16_t)len; + } + } + } + + /* handle error breaks in while */ + if (state->mode == BAD) + break; + + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) { + SET_BAD("invalid code -- missing end-of-block"); + break; + } + + /* build code tables -- note: do not change the lenbits or distbits + values here (10 and 9) without reading the comments in inftrees.h + concerning the ENOUGH constants, which depend on those values */ + state->next = state->codes; + state->lencode = (const code *)(state->next); + state->lenbits = 10; + ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); + if (ret) { + SET_BAD("invalid literal/lengths set"); + break; + } + state->distcode = (const code *)(state->next); + state->distbits = 9; + ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) { + SET_BAD("invalid distances set"); + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) + goto inf_leave; + Z_FALLTHROUGH; + + case LEN_: + state->mode = LEN; + Z_FALLTHROUGH; + + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= INFLATE_FAST_MIN_HAVE && left >= INFLATE_FAST_MIN_LEFT) { + RESTORE(); + functable.inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + + /* get a literal, length, or end-of-block code */ + for (;;) { + here = state->lencode[BITS(state->lenbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = here.val; + + /* process literal */ + if ((int)(here.op) == 0) { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + + /* process end of block */ + if (here.op & 32) { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + + /* invalid code */ + if (here.op & 64) { + SET_BAD("invalid literal/length code"); + break; + } + + /* length code */ + state->extra = (here.op & MAX_BITS); + state->mode = LENEXT; + Z_FALLTHROUGH; + + case LENEXT: + /* get extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + Z_FALLTHROUGH; + + case DIST: + /* get distance code */ + for (;;) { + here = state->distcode[BITS(state->distbits)]; + if (here.bits <= bits) + break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) { + last = here; + for (;;) { + here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)last.bits + (unsigned)here.bits <= bits) + break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) { + SET_BAD("invalid distance code"); + break; + } + state->offset = here.val; + state->extra = (here.op & MAX_BITS); + state->mode = DISTEXT; + Z_FALLTHROUGH; + + case DISTEXT: + /* get distance extra bits, if any */ + if (state->extra) { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } +#ifdef INFLATE_STRICT + if (state->offset > state->dmax) { + SET_BAD("invalid distance too far back"); + break; + } +#endif + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + Z_FALLTHROUGH; + + case MATCH: + /* copy match from window to output */ + if (left == 0) + goto inf_leave; + copy = out - left; + if (state->offset > copy) { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) { + if (state->sane) { + SET_BAD("invalid distance too far back"); + break; + } +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + copy = MIN(copy, state->length); + copy = MIN(copy, left); + left -= copy; + state->length -= copy; + do { + *put++ = 0; + } while (--copy); + if (state->length == 0) + state->mode = LEN; + break; +#endif + } + if (copy > state->wnext) { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } else { + from = state->window + (state->wnext - copy); + } + copy = MIN(copy, state->length); + copy = MIN(copy, left); + + put = chunkcopy_safe(put, from, copy, put + left); + } else { + copy = MIN(state->length, left); + + put = functable.chunkmemset_safe(put, state->offset, copy, left); + } + left -= copy; + state->length -= copy; + if (state->length == 0) + state->mode = LEN; + break; + + case LIT: + if (left == 0) + goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + + case CHECK: + if (state->wrap) { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + + /* compute crc32 checksum if not in raw mode */ + if (INFLATE_NEED_CHECKSUM(strm) && state->wrap & 4) { + if (out) { + inf_chksum(strm, put - out, out); + } +#ifdef GUNZIP + if (state->flags) + strm->adler = state->check = functable.crc32_fold_final(&state->crc_fold); +#endif + } + out = left; + if ((state->wrap & 4) && ( +#ifdef GUNZIP + state->flags ? hold : +#endif + ZSWAP32(hold)) != state->check) { + SET_BAD("incorrect data check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } +#ifdef GUNZIP + state->mode = LENGTH; + Z_FALLTHROUGH; + + case LENGTH: + if (state->wrap && state->flags) { + NEEDBITS(32); + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { + SET_BAD("incorrect length check"); + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } +#endif + state->mode = DONE; + Z_FALLTHROUGH; + + case DONE: + /* inflate stream terminated properly */ + ret = Z_STREAM_END; + goto inf_leave; + + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + + case MEM: + return Z_MEM_ERROR; + + case SYNC: + + default: /* can't happen, but makes compilers happy */ + return Z_STREAM_ERROR; + } + + /* + Return from inflate(), updating the total counts and the check value. + If there was no progress during the inflate() call, return a buffer + error. Call updatewindow() to create and/or update the window state. + Note: a memory error from inflate() is non-recoverable. + */ + inf_leave: + RESTORE(); + if (INFLATE_NEED_UPDATEWINDOW(strm) && + (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH)))) { + /* update sliding window with respective checksum if not in "raw" mode */ + if (updatewindow(strm, strm->next_out, out - strm->avail_out, state->wrap & 4)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + + strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; +} + +int32_t Z_EXPORT PREFIX(inflateEnd)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->window != NULL) + ZFREE_WINDOW(strm, state->window); + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + + INFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary */ + if (state->whave && dictionary != NULL) { + memcpy(dictionary, state->window + state->wnext, state->whave - state->wnext); + memcpy(dictionary + state->whave - state->wnext, state->window, state->wnext); + } + if (dictLength != NULL) + *dictLength = state->whave; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + struct inflate_state *state; + unsigned long dictid; + int32_t ret; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; + + /* check for correct dictionary identifier */ + if (state->mode == DICT) { + dictid = functable.adler32(ADLER32_INITIAL_VALUE, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } + + INFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + + /* copy dictionary to window using updatewindow(), which will amend the + existing dictionary if appropriate */ + ret = updatewindow(strm, dictionary + dictLength, dictLength, 0); + if (ret) { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateGetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + struct inflate_state *state; + + /* check state */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if ((state->wrap & 2) == 0) + return Z_STREAM_ERROR; + + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; +} + +/* + Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found + or when out of input. When called, *have is the number of pattern bytes + found in order so far, in 0..3. On return *have is updated to the new + state. If on return *have equals four, then the pattern was found and the + return value is how many bytes were read including the last byte of the + pattern. If *have is less than four, then the pattern has not been found + yet and the return value is len. In the latter case, syncsearch() can be + called again with more data and the *have state. *have is initialized to + zero for the first call. + */ +static uint32_t syncsearch(uint32_t *have, const uint8_t *buf, uint32_t len) { + uint32_t got, next; + + got = *have; + next = 0; + while (next < len && got < 4) { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; +} + +int32_t Z_EXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) { + unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ + size_t in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state *state; + + /* check parameters */ + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) + return Z_BUF_ERROR; + + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } + + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; + + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) + return Z_DATA_ERROR; + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; + in = strm->total_in; + out = strm->total_out; + PREFIX(inflateReset)(strm); + strm->total_in = (z_uintmax_t)in; /* Can't use z_size_t here as it will overflow on 64-bit Windows */ + strm->total_out = (z_uintmax_t)out; + state->flags = flags; + state->mode = TYPE; + return Z_OK; +} + +/* + Returns true if inflate is currently at the end of a block generated by + Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP + implementation to provide an additional safety check. PPP uses + Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored + block. When decompressing, PPP checks that at the end of input packet, + inflate is waiting for these length bytes. + */ +int32_t Z_EXPORT PREFIX(inflateSyncPoint)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + INFLATE_SYNC_POINT_HOOK(strm); + state = (struct inflate_state *)strm->state; + return state->mode == STORED && state->bits == 0; +} + +int32_t Z_EXPORT PREFIX(inflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + struct inflate_state *state; + struct inflate_state *copy; + unsigned char *window; + unsigned wsize; + + /* check input */ + if (inflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state *)source->state; + + /* allocate space */ + copy = ZALLOC_INFLATE_STATE(source); + if (copy == NULL) + return Z_MEM_ERROR; + window = NULL; + if (state->window != NULL) { + wsize = 1U << state->wbits; + window = (unsigned char *)ZALLOC_WINDOW(source, wsize, sizeof(unsigned char)); + if (window == NULL) { + ZFREE_STATE(source, copy); + return Z_MEM_ERROR; + } + } + + /* copy state */ + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + ZCOPY_INFLATE_STATE(copy, state); + copy->strm = dest; + if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != NULL) { + ZCOPY_WINDOW(window, state->window, (size_t)1U << state->wbits); + } + copy->window = window; + dest->state = (struct internal_state *)copy; + return Z_OK; +} + +int32_t Z_EXPORT PREFIX(inflateUndermine)(PREFIX3(stream) *strm, int32_t subvert) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + state->sane = !subvert; + return Z_OK; +#else + Z_UNUSED(subvert); + state->sane = 1; + return Z_DATA_ERROR; +#endif +} + +int32_t Z_EXPORT PREFIX(inflateValidate)(PREFIX3(stream) *strm, int32_t check) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return Z_STREAM_ERROR; + state = (struct inflate_state *)strm->state; + if (check && state->wrap) + state->wrap |= 4; + else + state->wrap &= ~4; + return Z_OK; +} + +long Z_EXPORT PREFIX(inflateMark)(PREFIX3(stream) *strm) { + struct inflate_state *state; + + if (inflateStateCheck(strm)) + return -65536; + INFLATE_MARK_HOOK(strm); /* hook for IBM Z DFLTCC */ + state = (struct inflate_state *)strm->state; + return (long)(((unsigned long)((long)state->back)) << 16) + + (state->mode == COPY ? state->length : + (state->mode == MATCH ? state->was - state->length : 0)); +} + +unsigned long Z_EXPORT PREFIX(inflateCodesUsed)(PREFIX3(stream) *strm) { + struct inflate_state *state; + if (strm == NULL || strm->state == NULL) + return (unsigned long)-1; + state = (struct inflate_state *)strm->state; + return (unsigned long)(state->next - state->codes); +} diff --git a/internal-complibs/zlib-ng-2.1.2/inflate.h b/internal-complibs/zlib-ng-2.1.2/inflate.h new file mode 100644 index 000000000..39cdf5d68 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inflate.h @@ -0,0 +1,140 @@ +/* inflate.h -- internal inflate state definition + * Copyright (C) 1995-2019 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#ifndef INFLATE_H_ +#define INFLATE_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and trailer decoding by inflate(). + NO_GZIP would be used to avoid linking in the crc code when it is not needed. + For shared libraries, gzip decoding should be left enabled. */ +#ifndef NO_GZIP +# define GUNZIP +#endif + +/* Possible inflate modes between inflate() calls */ +typedef enum { + HEAD = 16180, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ +} inflate_mode; + +/* + State transitions between above modes - + + (most modes can go to BAD or MEM on error -- not shown for clarity) + + Process header: + HEAD -> (gzip) or (zlib) or (raw) + (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> + HCRC -> TYPE + (zlib) -> DICTID or TYPE + DICTID -> DICT -> TYPE + (raw) -> TYPEDO + Read deflate blocks: + TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK + STORED -> COPY_ -> COPY -> TYPE + TABLE -> LENLENS -> CODELENS -> LEN_ + LEN_ -> LEN + Read deflate codes in fixed or dynamic block: + LEN -> LENEXT or LIT or TYPE + LENEXT -> DIST -> DISTEXT -> MATCH -> LEN + LIT -> LEN + Process trailer: + CHECK -> LENGTH -> DONE + */ + +/* State maintained between inflate() calls -- approximately 7K bytes, not + including the allocated sliding window, which is up to 32K bytes. */ +struct inflate_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip, + bit 2 true to validate check value */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + PREFIX(gz_headerp) head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + uint32_t wsize; /* window size or zero if not using window */ + uint32_t whave; /* valid bytes in the window */ + uint32_t wnext; /* window write index */ + unsigned char *window; /* allocated sliding window, if needed */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* bit accumulator */ + uint32_t hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + uint32_t length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const *lencode; /* starting table for length/literal codes */ + code const *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + uint32_t have; /* number of code lengths in lens[] */ + code *next; /* next available space in codes[] */ + uint16_t lens[320]; /* temporary storage for code lengths */ + uint16_t work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ + uint32_t chunksize; /* size of memory copying chunk */ +}; + +int Z_INTERNAL PREFIX(inflate_ensure_window)(struct inflate_state *state); +void Z_INTERNAL PREFIX(fixedtables)(struct inflate_state *state); + +#endif /* INFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/inflate_p.h b/internal-complibs/zlib-ng-2.1.2/inflate_p.h new file mode 100644 index 000000000..a007cd05d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inflate_p.h @@ -0,0 +1,225 @@ +/* inflate_p.h -- Private inline functions and macros shared with more than one deflate method + * + */ + +#ifndef INFLATE_P_H +#define INFLATE_P_H + +#include + +/* Architecture-specific hooks. */ +#ifdef S390_DFLTCC_INFLATE +# include "arch/s390/dfltcc_inflate.h" +#else +/* Memory management for the inflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_INFLATE_STATE(strm) ((struct inflate_state *)ZALLOC(strm, 1, sizeof(struct inflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_INFLATE_STATE(dst, src) memcpy(dst, src, sizeof(struct inflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define ZCOPY_WINDOW(dest, src, n) memcpy(dest, src, n) +# define ZFREE_WINDOW(strm, addr) ZFREE(strm, addr) +/* Invoked at the end of inflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflatePrime(). Useful for updating arch-specific buffers. */ +# define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0) +/* Invoked at the beginning of each block. Useful for plugging arch-specific inflation code. */ +# define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0) +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */ +# define INFLATE_NEED_UPDATEWINDOW(strm) 1 +/* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */ +# define INFLATE_MARK_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */ +# define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0) +/* Invoked at the beginning of inflateSetDictionary(). Useful for checking arch-specific window data. */ +# define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of inflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +#endif + +/* + * Macros shared by inflate() and inflateBack() + */ + +/* check function to use adler32() for zlib or crc32() for gzip */ +#ifdef GUNZIP +# define UPDATE(check, buf, len) \ + (state->flags ? PREFIX(crc32)(check, buf, len) : functable.adler32(check, buf, len)) +#else +# define UPDATE(check, buf, len) functable.adler32(check, buf, len) +#endif + +/* check macros for header crc */ +#ifdef GUNZIP +# define CRC2(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = PREFIX(crc32)(check, hbuf, 2); \ + } while (0) + +# define CRC4(check, word) \ + do { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = PREFIX(crc32)(check, hbuf, 4); \ + } while (0) +#endif + +/* Load registers with state in inflate() for speed */ +#define LOAD() \ + do { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) + +/* Restore state from registers in inflate() */ +#define RESTORE() \ + do { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = (z_const unsigned char *)next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) + +/* Clear the input bit accumulator */ +#define INITBITS() \ + do { \ + hold = 0; \ + bits = 0; \ + } while (0) + +/* Ensure that there is at least n bits in the bit accumulator. If there is + not enough available input to do that, then return from inflate()/inflateBack(). */ +#define NEEDBITS(n) \ + do { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) + +/* Return the low n bits of the bit accumulator (n < 16) */ +#define BITS(n) \ + (hold & ((1U << (unsigned)(n)) - 1)) + +/* Remove n bits from the bit accumulator */ +#define DROPBITS(n) \ + do { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) + +/* Remove zero to seven bits as needed to go to a byte boundary */ +#define BYTEBITS() \ + do { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) + +/* Set mode=BAD and prepare error message */ +#define SET_BAD(errmsg) \ + do { \ + state->mode = BAD; \ + strm->msg = (char *)errmsg; \ + } while (0) + +#define INFLATE_FAST_MIN_HAVE 15 +#define INFLATE_FAST_MIN_LEFT 260 + +/* Load 64 bits from IN and place the bytes at offset BITS in the result. */ +static inline uint64_t load_64_bits(const unsigned char *in, unsigned bits) { + uint64_t chunk; + memcpy(&chunk, in, sizeof(chunk)); + +#if BYTE_ORDER == LITTLE_ENDIAN + return chunk << bits; +#else + return ZSWAP64(chunk) << bits; +#endif +} + +/* Behave like chunkcopy, but avoid writing beyond of legal output. */ +static inline uint8_t* chunkcopy_safe(uint8_t *out, uint8_t *from, uint64_t len, uint8_t *safe) { + uint64_t safelen = (safe - out) + 1; + len = MIN(len, safelen); + int32_t olap_src = from >= out && from < out + len; + int32_t olap_dst = out >= from && out < from + len; + uint64_t tocopy; + + /* For all cases without overlap, memcpy is ideal */ + if (!(olap_src || olap_dst)) { + memcpy(out, from, (size_t)len); + return out + len; + } + + /* We are emulating a self-modifying copy loop here. To do this in a way that doesn't produce undefined behavior, + * we have to get a bit clever. First if the overlap is such that src falls between dst and dst+len, we can do the + * initial bulk memcpy of the nonoverlapping region. Then, we can leverage the size of this to determine the safest + * atomic memcpy size we can pick such that we have non-overlapping regions. This effectively becomes a safe look + * behind or lookahead distance. */ + uint64_t non_olap_size = llabs(from - out); // llabs vs labs for compatibility with windows + + memcpy(out, from, (size_t)non_olap_size); + out += non_olap_size; + from += non_olap_size; + len -= non_olap_size; + + /* So this doesn't give use a worst case scenario of function calls in a loop, + * we want to instead break this down into copy blocks of fixed lengths */ + while (len) { + tocopy = MIN(non_olap_size, len); + len -= tocopy; + + while (tocopy >= 32) { + memcpy(out, from, 32); + out += 32; + from += 32; + tocopy -= 32; + } + + if (tocopy >= 16) { + memcpy(out, from, 16); + out += 16; + from += 16; + tocopy -= 16; + } + + if (tocopy >= 8) { + memcpy(out, from, 8); + out += 8; + from += 8; + tocopy -= 8; + } + + if (tocopy >= 4) { + memcpy(out, from, 4); + out += 4; + from += 4; + tocopy -= 4; + } + + if (tocopy >= 2) { + memcpy(out, from, 2); + out += 2; + from += 2; + tocopy -= 2; + } + + if (tocopy) { + *out++ = *from++; + } + } + + return out; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/inftrees.c b/internal-complibs/zlib-ng-2.1.2/inftrees.c new file mode 100644 index 000000000..f04d65f86 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inftrees.c @@ -0,0 +1,295 @@ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" + +const char PREFIX(inflate_copyright)[] = " inflate 1.2.13 Copyright 1995-2022 Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* + Build a set of tables to decode the provided canonical Huffman code. + The code lengths are lens[0..codes-1]. The result starts at *table, + whose indices are 0..2^bits-1. work is a writable array of at least + lens shorts, which is used as a work area. type is the type of code + to be generated, CODES, LENS, or DISTS. On return, zero is success, + -1 is an invalid code, and +1 means that ENOUGH isn't enough. table + on return points to the next available entry's address. bits is the + requested root table index bits, and on return it is the actual root + table index bits. It will differ if the request is greater than the + longest code or if it is less than the shortest code. + */ +int Z_INTERNAL zng_inflate_table(codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work) { + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code *next; /* next available space in table */ + const uint16_t *base; /* base value table to use */ + const uint16_t *extra; /* extra bits table to use */ + unsigned match; /* use base and extra for symbol >= match */ + uint16_t count[MAX_BITS+1]; /* number of codes of each length */ + uint16_t offs[MAX_BITS+1]; /* offsets in table for each length */ + static const uint16_t lbase[31] = { /* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const uint16_t lext[31] = { /* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 77, 202}; + static const uint16_t dbase[32] = { /* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const uint16_t dext[32] = { /* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; + + /* + Process a set of code lengths to create a canonical Huffman code. The + code lengths are lens[0..codes-1]. Each length corresponds to the + symbols 0..codes-1. The Huffman code is generated by first sorting the + symbols by length from short to long, and retaining the symbol order + for codes with equal lengths. Then the code starts with all zero bits + for the first code of the shortest length, and the codes are integer + increments for the same length, and zeros are appended as the length + increases. For the deflate format, these bits are stored backwards + from their more natural integer increment ordering, and so when the + decoding tables are built in the large loop below, the integer codes + are incremented backwards. + + This routine assumes, but does not check, that all of the entries in + lens[] are in the range 0..MAXBITS. The caller must assure this. + 1..MAXBITS is interpreted as that code length. zero means that that + symbol does not occur in this code. + + The codes are sorted by computing a count of codes for each length, + creating from that a table of starting indices for each length in the + sorted table, and then entering the symbols in order in the sorted + table. The sorted table is work[], with that space being provided by + the caller. + + The length counts are used for other purposes as well, i.e. finding + the minimum and maximum length codes, determining if there are any + codes at all, checking for a valid set of lengths, and looking ahead + at length counts to determine sub-table sizes when building the + decoding tables. + */ + + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAX_BITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; + + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAX_BITS; max >= 1; max--) + if (count[max] != 0) break; + root = MIN(root, max); + if (UNLIKELY(max == 0)) { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (uint16_t)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + root = MAX(root, min); + + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAX_BITS; len++) { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ + + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAX_BITS; len++) + offs[len + 1] = offs[len] + count[len]; + + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (uint16_t)sym; + + /* + Create and fill in decoding tables. In this loop, the table being + filled is at next and has curr index bits. The code being used is huff + with length len. That code is converted to an index by dropping drop + bits off of the bottom. For codes where len is less than drop + curr, + those top drop + curr - len bits are incremented through all values to + fill the table with replicated entries. + + root is the number of index bits for the root table. When len exceeds + root, sub-tables are created pointed to by the root entry with an index + of the low root bits of huff. This is saved in low to check for when a + new sub-table should be started. drop is zero when the root table is + being filled, and drop is root when sub-tables are being filled. + + When a new sub-table is needed, it is necessary to look ahead in the + code lengths to determine what size sub-table is needed. The length + counts are used for this, and so count[] is decremented as codes are + entered in the tables. + + used keeps track of how many table entries have been allocated from the + provided *table space. It is checked for LENS and DIST tables against + the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in + the initial root table size constants. See the comments in inftrees.h + for more information. + + sym increments through all symbols, and the loop terminates when + all codes of length max, i.e. all codes, have been processed. This + routine permits incomplete codes, so another loop after this one fills + in the rest of the decoding tables with invalid code markers. + */ + + /* set up for code type */ + switch (type) { + case CODES: + base = extra = work; /* dummy value--not used */ + match = 20; + break; + case LENS: + base = lbase; + extra = lext; + match = 257; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + match = 0; + } + + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ + + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* process all codes and make table entries */ + for (;;) { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if (LIKELY(work[sym] >= match)) { + here.op = (unsigned char)(extra[work[sym] - match]); + here.val = base[work[sym] - match]; + } else if (work[sym] + 1U < match) { + here.op = (unsigned char)0; + here.val = work[sym]; + } else { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } + + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); + + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) { + huff &= incr - 1; + huff += incr; + } else { + huff = 0; + } + + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) { + if (len == max) + break; + len = lens[work[sym]]; + } + + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; + + /* increment past last table */ + next += min; /* here min is 1 << curr */ + + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) { + left -= count[curr + drop]; + if (left <= 0) + break; + curr++; + left <<= 1; + } + + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || (type == DISTS && used > ENOUGH_DISTS)) + return 1; + + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (uint16_t)(next - *table); + } + } + + /* fill in remaining table entry if code is incomplete (guaranteed to have + at most one remaining entry, since if the code is incomplete, the + maximum code length that was allowed to get this far is one bit) */ + if (UNLIKELY(huff != 0)) { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (uint16_t)0; + next[huff] = here; + } + + /* set return parameters */ + *table += used; + *bits = root; + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/inftrees.h b/internal-complibs/zlib-ng-2.1.2/inftrees.h new file mode 100644 index 000000000..eeae9c6ac --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/inftrees.h @@ -0,0 +1,66 @@ +#ifndef INFTREES_H_ +#define INFTREES_H_ + +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Structure for decoding tables. Each entry provides either the + information needed to do the operation requested by the code that + indexed that table entry, or it provides a pointer to another + table that indexes more bits of the code. op indicates whether + the entry is a pointer to another table, a literal, a length or + distance, an end-of-block, or an invalid code. For a table + pointer, the low four bits of op is the number of index bits of + that table. For a length or distance, the low four bits of op + is the number of extra bits to get after the code. bits is + the number of bits in this code or part of the code to drop off + of the bit buffer. val is the actual byte to output in the case + of a literal, the base length or distance, or the offset from + the current table to the next table. Each entry is four bytes. */ +typedef struct { + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + uint16_t val; /* offset in table or code value */ +} code; + +/* op values as set by inflate_table(): + 00000000 - literal + 0000tttt - table link, tttt != 0 is the number of table index bits + 0001eeee - length or distance, eeee is the number of extra bits + 01100000 - end of block + 01000000 - invalid code + */ + +/* Maximum size of the dynamic table. The maximum number of code structures is + 1924, which is the sum of 1332 for literal/length codes and 592 for distance + codes. These values were found by exhaustive searches using the program + examples/enough.c found in the zlib distributions. The arguments to that + program are the number of symbols, the initial root table size, and the + maximum bit length of a code. "enough 286 10 15" for literal/length codes + returns returns 1332, and "enough 30 9 15" for distance codes returns 592. + The initial root table size (10 or 9) is found in the fifth argument of the + inflate_table() calls in inflate.c and infback.c. If the root table size is + changed, then these maximum sizes would be need to be recalculated and + updated. */ +#define ENOUGH_LENS 1332 +#define ENOUGH_DISTS 592 +#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) + +/* Type of code to build for inflate_table() */ +typedef enum { + CODES, + LENS, + DISTS +} codetype; + +int Z_INTERNAL zng_inflate_table (codetype type, uint16_t *lens, unsigned codes, + code * *table, unsigned *bits, uint16_t *work); + +#endif /* INFTREES_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/insert_string.c b/internal-complibs/zlib-ng-2.1.2/insert_string.c new file mode 100644 index 000000000..cfe39837f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/insert_string.c @@ -0,0 +1,21 @@ +/* insert_string.c -- insert_string integer hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 16 + +#define HASH_CALC(s, h, val) h = ((val * 2654435761U) >> HASH_SLIDE); +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_c +#define INSERT_STRING insert_string_c +#define QUICK_INSERT_STRING quick_insert_string_c + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.2/insert_string_roll.c b/internal-complibs/zlib-ng-2.1.2/insert_string_roll.c new file mode 100644 index 000000000..dfea347bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/insert_string_roll.c @@ -0,0 +1,24 @@ +/* insert_string_roll.c -- insert_string rolling hash variant + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "zbuild.h" +#include "deflate.h" + +#define HASH_SLIDE 5 + +#define HASH_CALC(s, h, val) h = ((h << HASH_SLIDE) ^ ((uint8_t)val)) +#define HASH_CALC_VAR s->ins_h +#define HASH_CALC_VAR_INIT +#define HASH_CALC_READ val = strstart[0] +#define HASH_CALC_MASK (32768u - 1u) +#define HASH_CALC_OFFSET (STD_MIN_MATCH-1) + +#define UPDATE_HASH update_hash_roll +#define INSERT_STRING insert_string_roll +#define QUICK_INSERT_STRING quick_insert_string_roll + +#include "insert_string_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.2/insert_string_tpl.h b/internal-complibs/zlib-ng-2.1.2/insert_string_tpl.h new file mode 100644 index 000000000..4acd67fd6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/insert_string_tpl.h @@ -0,0 +1,108 @@ +#ifndef INSERT_STRING_H_ +#define INSERT_STRING_H_ + +/* insert_string.h -- Private insert_string functions shared with more than + * one insert string implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef HASH_CALC_OFFSET +# define HASH_CALC_OFFSET 0 +#endif +#ifndef HASH_CALC_MASK +# define HASH_CALC_MASK HASH_MASK +#endif +#ifndef HASH_CALC_READ +# if BYTE_ORDER == LITTLE_ENDIAN +# define HASH_CALC_READ \ + memcpy(&val, strstart, sizeof(val)); +# else +# define HASH_CALC_READ \ + val = ((uint32_t)(strstart[0])); \ + val |= ((uint32_t)(strstart[1]) << 8); \ + val |= ((uint32_t)(strstart[2]) << 16); \ + val |= ((uint32_t)(strstart[3]) << 24); +# endif +#endif + +/* =========================================================================== + * Update a hash value with the given input byte + * IN assertion: all calls to to UPDATE_HASH are made with consecutive + * input characters, so that a running hash key can be computed from the + * previous key instead of complete recalculation each time. + */ +Z_INTERNAL uint32_t UPDATE_HASH(deflate_state *const s, uint32_t h, uint32_t val) { + (void)s; + HASH_CALC(s, h, val); + return h & HASH_CALC_MASK; +} + +/* =========================================================================== + * Quick insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + */ +Z_INTERNAL Pos QUICK_INSERT_STRING(deflate_state *const s, uint32_t str) { + Pos head; + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + head = s->head[hm]; + if (LIKELY(head != str)) { + s->prev[str & s->w_mask] = head; + s->head[hm] = (Pos)str; + } + return head; +} + +/* =========================================================================== + * Insert string str in the dictionary and set match_head to the previous head + * of the hash chain (the most recent string with same hash key). Return + * the previous length of the hash chain. + * IN assertion: all calls to to INSERT_STRING are made with consecutive + * input characters and the first STD_MIN_MATCH bytes of str are valid + * (except for the last STD_MIN_MATCH-1 bytes of the input file). + */ +Z_INTERNAL void INSERT_STRING(deflate_state *const s, uint32_t str, uint32_t count) { + uint8_t *strstart = s->window + str + HASH_CALC_OFFSET; + uint8_t *strend = strstart + count; + + for (Pos idx = (Pos)str; strstart < strend; idx++, strstart++) { + uint32_t val, hm; + + HASH_CALC_VAR_INIT; + HASH_CALC_READ; + HASH_CALC(s, HASH_CALC_VAR, val); + HASH_CALC_VAR &= HASH_CALC_MASK; + hm = HASH_CALC_VAR; + + Pos head = s->head[hm]; + if (LIKELY(head != idx)) { + s->prev[idx & s->w_mask] = head; + s->head[hm] = idx; + } + } +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/match_tpl.h b/internal-complibs/zlib-ng-2.1.2/match_tpl.h new file mode 100644 index 000000000..d07679852 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/match_tpl.h @@ -0,0 +1,289 @@ +/* match_tpl.h -- find longest match template for compare256 variants + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Portions copyright (C) 2014-2021 Konstantin Nosov + * Fast-zlib optimized longest_match + * https://github.com/gildor2/fast_zlib + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "functable.h" + +#ifndef MATCH_TPL_H +#define MATCH_TPL_H + +#define EARLY_EXIT_TRIGGER_LEVEL 5 + +#endif + +/* Set match_start to the longest match starting at the given string and + * return its length. Matches shorter or equal to prev_length are discarded, + * in which case the result is equal to prev_length and match_start is garbage. + * + * IN assertions: cur_match is the head of the hash chain for the current + * string (strstart) and its distance is <= MAX_DIST, and prev_length >=1 + * OUT assertion: the match length is not greater than s->lookahead + */ +Z_INTERNAL uint32_t LONGEST_MATCH(deflate_state *const s, Pos cur_match) { + unsigned int strstart = s->strstart; + const unsigned wmask = s->w_mask; + unsigned char *window = s->window; + unsigned char *scan = window + strstart; + Z_REGISTER unsigned char *mbase_start = window; + Z_REGISTER unsigned char *mbase_end; + const Pos *prev = s->prev; + Pos limit; +#ifdef LONGEST_MATCH_SLOW + Pos limit_base; +#else + int32_t early_exit; +#endif + uint32_t chain_length, nice_match, best_len, offset; + uint32_t lookahead = s->lookahead; + Pos match_offset = 0; +#ifdef UNALIGNED_OK + uint8_t scan_start[8]; +#endif + uint8_t scan_end[8]; + +#define GOTO_NEXT_CHAIN \ + if (--chain_length && (cur_match = prev[cur_match & wmask]) > limit) \ + continue; \ + return best_len; + + /* The code is optimized for STD_MAX_MATCH-2 multiple of 16. */ + Assert(STD_MAX_MATCH == 258, "Code too clever"); + + best_len = s->prev_length ? s->prev_length : STD_MIN_MATCH-1; + + /* Calculate read offset which should only extend an extra byte + * to find the next best match length. + */ + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_start, scan, sizeof(uint64_t)); + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_start, scan, sizeof(uint32_t)); + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + mbase_end = (mbase_start+offset); + + /* Do not waste too much time if we already have a good match */ + chain_length = s->max_chain_length; + if (best_len >= s->good_match) + chain_length >>= 2; + nice_match = (uint32_t)s->nice_match; + + /* Stop when cur_match becomes <= limit. To simplify the code, + * we prevent matches with the string of window index 0 + */ + limit = strstart > MAX_DIST(s) ? (Pos)(strstart - MAX_DIST(s)) : 0; +#ifdef LONGEST_MATCH_SLOW + limit_base = limit; + if (best_len >= STD_MIN_MATCH) { + /* We're continuing search (lazy evaluation). */ + uint32_t i, hash; + Pos pos; + + /* Find a most distant chain starting from scan with index=1 (index=0 corresponds + * to cur_match). We cannot use s->prev[strstart+1,...] immediately, because + * these strings are not yet inserted into the hash table. + */ + hash = s->update_hash(s, 0, scan[1]); + hash = s->update_hash(s, hash, scan[2]); + + for (i = 3; i <= best_len; i++) { + hash = s->update_hash(s, hash, scan[i]); + + /* If we're starting with best_len >= 3, we can use offset search. */ + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(i - 2); + cur_match = pos; + } + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + if (cur_match <= limit) + goto break_matching; + mbase_start -= match_offset; + mbase_end -= match_offset; + } +#else + early_exit = s->level < EARLY_EXIT_TRIGGER_LEVEL; +#endif + Assert((unsigned long)strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); + for (;;) { + if (cur_match >= strstart) + break; + + /* Skip to next match if the match length cannot increase or if the match length is + * less than 2. Note that the checks below for insufficient lookahead only occur + * occasionally for performance reasons. + * Therefore uninitialized memory will be accessed and conditional jumps will be made + * that depend on those values. However the length of the match is limited to the + * lookahead, so the output of deflate is not affected by the uninitialized values. + */ +#ifdef UNALIGNED_OK + if (best_len < sizeof(uint32_t)) { + for (;;) { + if (zng_memcmp_2(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_2(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# ifdef UNALIGNED64_OK + } else if (best_len >= sizeof(uint64_t)) { + for (;;) { + if (zng_memcmp_8(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_8(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } +# endif + } else { + for (;;) { + if (zng_memcmp_4(mbase_end+cur_match, scan_end) == 0 && + zng_memcmp_4(mbase_start+cur_match, scan_start) == 0) + break; + GOTO_NEXT_CHAIN; + } + } +#else + for (;;) { + if (mbase_end[cur_match] == scan_end[0] && mbase_end[cur_match+1] == scan_end[1] && + mbase_start[cur_match] == scan[0] && mbase_start[cur_match+1] == scan[1]) + break; + GOTO_NEXT_CHAIN; + } +#endif + uint32_t len = COMPARE256(scan+2, mbase_start+cur_match+2) + 2; + Assert(scan+len <= window+(unsigned)(s->window_size-1), "wild scan"); + + if (len > best_len) { + uint32_t match_start = cur_match - match_offset; + s->match_start = match_start; + + /* Do not look for matches beyond the end of the input. */ + if (len > lookahead) + return lookahead; + best_len = len; + if (best_len >= nice_match) + return best_len; + + offset = best_len-1; +#ifdef UNALIGNED_OK + if (best_len >= sizeof(uint32_t)) { + offset -= 2; +#ifdef UNALIGNED64_OK + if (best_len >= sizeof(uint64_t)) + offset -= 4; +#endif + } +#endif + +#ifdef UNALIGNED64_OK + memcpy(scan_end, scan+offset, sizeof(uint64_t)); +#elif defined(UNALIGNED_OK) + memcpy(scan_end, scan+offset, sizeof(uint32_t)); +#else + scan_end[0] = *(scan+offset); + scan_end[1] = *(scan+offset+1); +#endif + +#ifdef LONGEST_MATCH_SLOW + /* Look for a better string offset */ + if (UNLIKELY(len > STD_MIN_MATCH && match_start + len < strstart)) { + Pos pos, next_pos; + uint32_t i, hash; + unsigned char *scan_endstr; + + /* Go back to offset 0 */ + cur_match -= match_offset; + match_offset = 0; + next_pos = cur_match; + for (i = 0; i <= len - STD_MIN_MATCH; i++) { + pos = prev[(cur_match + i) & wmask]; + if (pos < next_pos) { + /* Hash chain is more distant, use it */ + if (pos <= limit_base + i) + goto break_matching; + next_pos = pos; + match_offset = (Pos)i; + } + } + /* Switch cur_match to next_pos chain */ + cur_match = next_pos; + + /* Try hash head at len-(STD_MIN_MATCH-1) position to see if we could get + * a better cur_match at the end of string. Using (STD_MIN_MATCH-1) lets + * us include one more byte into hash - the byte which will be checked + * in main loop now, and which allows to grow match by 1. + */ + scan_endstr = scan + len - (STD_MIN_MATCH+1); + + hash = s->update_hash(s, 0, scan_endstr[0]); + hash = s->update_hash(s, hash, scan_endstr[1]); + hash = s->update_hash(s, hash, scan_endstr[2]); + + pos = s->head[hash]; + if (pos < cur_match) { + match_offset = (Pos)(len - (STD_MIN_MATCH+1)); + if (pos <= limit_base + match_offset) + goto break_matching; + cur_match = pos; + } + + /* Update offset-dependent variables */ + limit = limit_base+match_offset; + mbase_start = window-match_offset; + mbase_end = (mbase_start+offset); + continue; + } +#endif + mbase_end = (mbase_start+offset); + } +#ifndef LONGEST_MATCH_SLOW + else if (UNLIKELY(early_exit)) { + /* The probability of finding a match later if we here is pretty low, so for + * performance it's best to outright stop here for the lower compression levels + */ + break; + } +#endif + GOTO_NEXT_CHAIN; + } + return best_len; + +#ifdef LONGEST_MATCH_SLOW +break_matching: + + if (best_len < s->lookahead) + return best_len; + + return s->lookahead; +#endif +} + +#undef LONGEST_MATCH_SLOW +#undef LONGEST_MATCH +#undef COMPARE256 diff --git a/internal-complibs/zlib-ng-2.1.2/slide_hash.c b/internal-complibs/zlib-ng-2.1.2/slide_hash.c new file mode 100644 index 000000000..b9fbbdb69 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/slide_hash.c @@ -0,0 +1,52 @@ +/* slide_hash.c -- slide hash table C implementation + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" + +/* =========================================================================== + * Slide the hash table when sliding the window down (could be avoided with 32 + * bit values at the expense of memory usage). We slide even when level == 0 to + * keep the hash table consistent if we switch back to level > 0 later. + */ +static inline void slide_hash_c_chain(Pos *table, uint32_t entries, uint16_t wsize) { +#ifdef NOT_TWEAK_COMPILER + table += entries; + do { + unsigned m; + m = *--table; + *table = (Pos)(m >= wsize ? m-wsize : 0); + /* If entries is not on any hash chain, prev[entries] is garbage but + * its value will never be used. + */ + } while (--entries); +#else + { + /* As of I make this change, gcc (4.8.*) isn't able to vectorize + * this hot loop using saturated-subtraction on x86-64 architecture. + * To avoid this defect, we can change the loop such that + * o. the pointer advance forward, and + * o. demote the variable 'm' to be local to the loop, and + * choose type "Pos" (instead of 'unsigned int') for the + * variable to avoid unnecessary zero-extension. + */ + unsigned int i; + Pos *q = table; + for (i = 0; i < entries; i++) { + Pos m = *q; + Pos t = (Pos)wsize; + *q++ = (Pos)(m >= t ? m-t: 0); + } + } +#endif /* NOT_TWEAK_COMPILER */ +} + +Z_INTERNAL void slide_hash_c(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + + slide_hash_c_chain(s->head, HASH_SIZE, wsize); + slide_hash_c_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/.gitignore b/internal-complibs/zlib-ng-2.1.2/test/.gitignore new file mode 100644 index 000000000..96a3cad07 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/.gitignore @@ -0,0 +1,5 @@ +# ignore Makefiles; they're all automatically generated +Makefile +/switchlevels +/switchlevels.dSYM/ +/switchlevels.exe diff --git a/internal-complibs/zlib-ng-2.1.2/test/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/test/CMakeLists.txt new file mode 100644 index 000000000..d434ec308 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/CMakeLists.txt @@ -0,0 +1,257 @@ +cmake_minimum_required(VERSION 3.5.1) + +macro(configure_test_executable target) + target_include_directories(${target} PRIVATE ${PROJECT_BINARY_DIR} ${PROJECT_SOURCE_DIR}) + set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + if(NOT WITH_GZFILEOP) + target_compile_definitions(${target} PRIVATE -DWITH_GZFILEOP) + target_sources(${target} PRIVATE ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) + endif() +endmacro() + +if(ZLIBNG_ENABLE_TESTS) + add_definitions(-DZLIBNG_ENABLE_TESTS) +endif() + +add_executable(example example.c) +configure_test_executable(example) +target_link_libraries(example zlib) +add_test(NAME example COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minigzip minigzip.c) +configure_test_executable(minigzip) +if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(minigzip zlibstatic) +else() + target_link_libraries(minigzip zlib) +endif() +if(BASEARCH_S360_FOUND) + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + set_source_files_properties(minigzip.c PROPERTIES COMPILE_DEFINITIONS BUFLEN=262144) + endif() +endif() +set(MINIGZIP_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(minideflate minideflate.c) +configure_test_executable(minideflate) +target_link_libraries(minideflate zlib) +set(MINIDEFLATE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +if(INSTALL_UTILS) + install(TARGETS minigzip minideflate + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() + +add_executable(switchlevels switchlevels.c) +configure_test_executable(switchlevels) +target_link_libraries(switchlevels zlib) +set(SWITCHLEVELS_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(infcover infcover.c) +configure_test_executable(infcover) +target_link_libraries(infcover zlib) +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + target_sources(infcover PRIVATE ${PROJECT_SOURCE_DIR}/inftrees.c) +endif() +# infcover references zng_inflate_table() and struct inflate_state, which are internal to zlib-ng. +if(ZLIBNG_ENABLE_TESTS) + add_test(NAME infcover COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +add_executable(makefixed ${PROJECT_SOURCE_DIR}/tools/makefixed.c ${PROJECT_SOURCE_DIR}/inftrees.c) +configure_test_executable(makefixed) +set(MAKEFIXED_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(maketrees ${PROJECT_SOURCE_DIR}/tools/maketrees.c ${PROJECT_SOURCE_DIR}/trees.c ${PROJECT_SOURCE_DIR}/zutil.c) +configure_test_executable(maketrees) +set(MAKETREES_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +add_executable(makecrct ${PROJECT_SOURCE_DIR}/tools/makecrct.c) +configure_test_executable(makecrct) +set(MAKECRCT_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if(NOT BASEARCH_WASM32_FOUND) + # Runs tests targeting CVEs + include(cmake/test-cves.cmake) + + # Run tests with data files + include(cmake/test-data.cmake) + + # Run tests targeting GitHub issues + include(cmake/test-issues.cmake) + + # Run tests targeting tools + include(cmake/test-tools.cmake) +endif() + +if(WITH_FUZZERS) + add_subdirectory(fuzz) +endif() + +if(WITH_GTEST OR WITH_BENCHMARKS) + if(CMAKE_VERSION VERSION_LESS 3.12) + message(WARNING "Minimum cmake version of 3.12 not met for GoogleTest or benchmarks!") + + set(WITH_GTEST OFF) + set(WITH_GTEST OFF PARENT_SCOPE) + + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARKS OFF PARENT_SCOPE) + else() + enable_language(CXX) + endif() +endif() + +if(WITH_BENCHMARKS) + add_subdirectory(benchmarks) +endif() + +if(WITH_GTEST) + include(FetchContent) + + # Google test requires at least C++11 + set(CMAKE_CXX_STANDARD 11) + + # Google test requires MSAN instrumented LLVM C++ libraries + if(WITH_SANITIZER STREQUAL "Memory") + if(NOT DEFINED ENV{LLVM_BUILD_DIR}) + message(FATAL_ERROR "MSAN instrumented C++ libraries required!") + endif() + + # Must set include and compile options before fetching googletest + include_directories($ENV{LLVM_BUILD_DIR}/include $ENV{LLVM_BUILD_DIR}/include/c++/v1) + add_compile_options(-stdlib=libc++ -g) + endif() + + if(NOT TARGET GTest::GTest) + # Prevent overriding the parent project's compiler/linker settings for Windows + set(gtest_force_shared_crt ON CACHE BOOL + "Use shared (DLL) run-time lib even when Google Test is built as static lib." FORCE) + + # Allow specifying alternative Google test repository + if(NOT DEFINED GTEST_REPOSITORY) + set(GTEST_REPOSITORY https://github.com/google/googletest.git) + endif() + if(NOT DEFINED GTEST_TAG) + # Use older version of Google test to support older versions of GCC + if (CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS_EQUAL 5.3) + set(GTEST_TAG release-1.10.0) + else() + set(GTEST_TAG release-1.11.0) + endif() + endif() + + # Fetch Google test source code from official repository + FetchContent_Declare(googletest + GIT_REPOSITORY ${GTEST_REPOSITORY} + GIT_TAG ${GTEST_TAG}) + + FetchContent_GetProperties(googletest) + if(NOT googletest_POPULATED) + FetchContent_Populate(googletest) + add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() + add_library(GTest::GTest ALIAS gtest) + add_library(GTest::Main ALIAS gtest_main) + endif() + + set(TEST_SRCS + test_compress.cc + test_compress_bound.cc + test_cve-2003-0107.cc + test_deflate_bound.cc + test_deflate_copy.cc + test_deflate_dict.cc + test_deflate_hash_head_0.cc + test_deflate_header.cc + test_deflate_params.cc + test_deflate_pending.cc + test_deflate_prime.cc + test_deflate_quick_bi_valid.cc + test_deflate_quick_block_open.cc + test_deflate_tune.cc + test_dict.cc + test_inflate_adler32.cc + test_large_buffers.cc + test_raw.cc + test_small_buffers.cc + test_small_window.cc + ) + + if(WITH_GZFILEOP) + list(APPEND TEST_SRCS test_gzio.cc) + endif() + + if(ZLIBNG_ENABLE_TESTS) + list(APPEND TEST_SRCS + test_adler32.cc # adler32_neon(), etc + test_aligned_alloc.cc # zng_alloc_aligned() + test_compare256.cc # compare256_neon(), etc + test_crc32.cc # crc32_acle(), etc + test_inflate_sync.cc # expects a certain compressed block layout + test_main.cc # cpu_check_features() + test_version.cc # expects a fixed version string + ) + endif() + + add_executable(gtest_zlib ${TEST_SRCS}) + configure_test_executable(gtest_zlib) + + if(WITH_SANITIZER STREQUAL "Memory") + target_link_directories(gtest_zlib PRIVATE $ENV{LLVM_BUILD_DIR}/lib) + target_link_options(gtest_zlib PRIVATE + -stdlib=libc++ + -lc++abi + -fsanitize=memory + -fsanitize-memory-track-origins) + endif() + + if(NOT ZLIB_COMPAT AND DEFINED ZLIB_LIBRARIES AND DEFINED ZLIB_INCLUDE_DIRS) + if(NOT IS_ABSOLUTE ${ZLIB_LIBRARIES}) + get_filename_component(ZLIB_ABSOLUTE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/${ZLIB_LIBRARIES}" + ABSOLUTE) + else() + set(ZLIB_ABSOLUTE_PATH ${ZLIB_LIBRARIES}) + endif() + + add_library(external_zlib STATIC IMPORTED) + set_property(TARGET external_zlib PROPERTY IMPORTED_LOCATION ${ZLIB_ABSOLUTE_PATH}) + message(STATUS "Added dual linking tests against zlib") + message(STATUS " Zlib include dirs: ${ZLIB_INCLUDE_DIRS}") + message(STATUS " Zlib libraries: ${ZLIB_ABSOLUTE_PATH}") + + target_sources(gtest_zlib PRIVATE test_compress_dual.cc) + target_include_directories(gtest_zlib PRIVATE ${ZLIB_INCLUDE_DIRS}) + target_link_libraries(gtest_zlib external_zlib) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + # Link statically in order to test internal zlib-ng functions. + target_link_libraries(gtest_zlib zlibstatic) + else() + target_link_libraries(gtest_zlib zlib) + endif() + + if(BUILD_SHARED_LIBS) + target_link_libraries(gtest_zlib GTest::Main) + endif() + target_link_libraries(gtest_zlib GTest::GTest) + + find_package(Threads) + if(Threads_FOUND AND NOT BASEARCH_WASM32_FOUND) + target_sources(gtest_zlib PRIVATE test_deflate_concurrency.cc) + if(UNIX AND NOT APPLE) + # On Linux, use a workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52590 + target_link_libraries(gtest_zlib -Wl,--whole-archive -lpthread -Wl,--no-whole-archive) + endif() + target_link_libraries(gtest_zlib Threads::Threads) + endif() + + add_test(NAME gtest_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/test/CVE-2002-0059/test.gz b/internal-complibs/zlib-ng-2.1.2/test/CVE-2002-0059/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..c5c3e184b1a90692f1c2dc729eb106476d231378 GIT binary patch literal 4610 zcmb2|=3oE==C>CV8G$T;1@EN)&o6EfRlAUMpn;K@jYq;DVU#f%2%{-sG#8BKg3(+s vnhQpA!DucR%>|>mU^Ewu=7P~&Fq#WSbHQjX7-G5L2bCV85!7kBn%P`G%zxAfEl}iz!@q6kpjs906!lM=l}o! literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.2/test/CVE-2005-1849/test.gz b/internal-complibs/zlib-ng-2.1.2/test/CVE-2005-1849/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..b28f278263c0a3154faeb3c3dd7b083a3a593c8d GIT binary patch literal 52 kcmb2|=3oE==C@ZA85!7kBn%P`G%zxAz!-252m>Ss01LtkQvd(} literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.2/test/CVE-2005-2096/test.gz b/internal-complibs/zlib-ng-2.1.2/test/CVE-2005-2096/test.gz new file mode 100644 index 0000000000000000000000000000000000000000..11590aeab9ac844087776ab66eb2f5d2c9f6d013 GIT binary patch literal 52 pcmb2|=3oE==C>CV84oltGP4!m+X9 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.2/test/GH-382/defneg3.dat b/internal-complibs/zlib-ng-2.1.2/test/GH-382/defneg3.dat new file mode 100644 index 000000000..5fa6a0804 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/GH-382/defneg3.dat @@ -0,0 +1 @@ +oÌ™Ì?ÌOÌÃÌḩÌÕÌ>ÌÌÌàÌ̹̘ÌÔÌEÌsÌ—ÌÌ4̢̙̑Ì6ÌÌØÌæÌ\ÌÌÌ5̪̲̕ÌmÌÌ–Ìç̺̜ÌÙ̧ÌÌíÌíÌ–ÌÌëÌmÌìÌÎ̵ÌGÌïÌOÌÛÌ ÌÃÌòÌÎÌôÌ„Ì;Ì”ÌýÌ’ÌÓÌÀÌ×Ì,ÌÑÌ¢ÌáÌAÌ9Ì»ÌæÌ‚ÌÂÌsÌý̼ÌÝÌÌ­ÌeÌòÌÝÌUÌuÌí̱ÌËÌwÌùÌ•ÌDÌß̋̽Ìt̞̣̹ÌöÌôÌOÌîÌíÌ…ÌpÌGÌìÌ°ÌÀÌ(ÌÌÌ̤Ì{Ì“ÌßÌïÌÕÌÌøÌÌMÌ#ÌÌí̵ÌdÌ·ÌIÌßÌhÌ_ÌpÌJÌÇÌ¢ÌÎÌÌoÌÌêÌÁÌ;Ì<̘ÌZÌÈÌÑÌoÌWÌ„Ì¿Ì}ÌáÌÌÌ:Ìá̧̻̕ÌeÌFÌtÌ(ÌEÌoÌàÌpÌÌ¢Ì(Ì;ÌþÌëÌóÌ!̹̹ÌÉÌÌœÌîÌÖÌ4ÌÈÌ3ÌëÌ‹ÌBÌŽÌÆÌuÌPÌ6Ì“ÌþÌ&̦̳̕ÌÁÌðÌ»ÌÌÌTÌÀ̧ÌbÌÌÒÌÕÌëÌ{ÌÆÌ¡ÌÊÌNÌ9ÌÇÌÌBÌÑ \ No newline at end of file diff --git a/internal-complibs/zlib-ng-2.1.2/test/GH-751/test.txt b/internal-complibs/zlib-ng-2.1.2/test/GH-751/test.txt new file mode 100644 index 000000000..ef2143ece --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/GH-751/test.txt @@ -0,0 +1 @@ +abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc diff --git a/internal-complibs/zlib-ng-2.1.2/test/GH-979/pigz-2.6.tar.gz b/internal-complibs/zlib-ng-2.1.2/test/GH-979/pigz-2.6.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..0d76ef8757e36dc5ab02e579a99442c211b6d978 GIT binary patch literal 106840 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%0Dmda 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 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.2/test/Makefile.in b/internal-complibs/zlib-ng-2.1.2/test/Makefile.in new file mode 100644 index 000000000..429e2c770 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/Makefile.in @@ -0,0 +1,82 @@ +# Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler +# Copyright 2015, Daniel Axtens, IBM Corporation +# zlib license, see zlib.h + +CC= +CFLAGS= +EXE= +SRCDIR= +SRCTOP= +LIBNAME= +TEST_LDFLAGS=-L.. ../$(LIBNAME).a + +EMU_RUN= + +all: alltests + +alltests: #set by ../configure +check_cross_dep: +ifneq (,$(findstring qemu,$(EMU_RUN))) +QEMU_VER:=$(shell command -v $(EMU_RUN) --version 2> /dev/null) +ifeq (,$(QEMU_VER)) +$(error You need QEMU to run tests on non-native platform) +endif +endif + +ALL_SRC_FILES := $(wildcard ../*) + +teststatic: check_cross_dep + @TMPST=tmpst_$$$$; \ + HELLOST=tmphellost_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${EMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${EMU_RUN} ../example$(EXE) $$TMPST; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPST $$HELLOST + +testshared: check_cross_dep + @LD_LIBRARY_PATH=`pwd`/..:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`/..:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`/..:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`/..:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$$$; \ + HELLOSH=tmphellosh_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${EMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${EMU_RUN} ../examplesh$(EXE) $$TMPSH; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPSH $$HELLOSH + +.PHONY: ghtests +ghtests: testGH-361 testGH-364 testGH-751 testGH-1235 + +.PHONY: testGH-361 +testGH-361: + $(EMU_RUN) ../minigzip$(EXE) -4 <$(SRCDIR)/GH-361/test.txt >/dev/null + +switchlevels$(EXE): $(SRCDIR)/switchlevels.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-364 +testGH-364: switchlevels$(EXE) + $(EMU_RUN) ./switchlevels$(EXE) 1 5 9 3 <$(SRCDIR)/GH-364/test.bin >/dev/null + +.PHONY: testGH-751 +testGH-751: + $(EMU_RUN) ../minigzip$(EXE) <$(SRCDIR)/GH-751/test.txt | $(EMU_RUN) ../minigzip$(EXE) -d >/dev/null + +gh1235$(EXE): $(SRCDIR)/gh1235.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-1235 +testGH-1235: gh1235$(EXE) + $(EMU_RUN) ./gh1235$(EXE) + +clean: + rm -f *.o *.gcda *.gcno *.gcov + rm -f switchlevels$(EXE) gh1235$(EXE) + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/test/README.md b/internal-complibs/zlib-ng-2.1.2/test/README.md new file mode 100644 index 000000000..d844ba530 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/README.md @@ -0,0 +1,37 @@ +Contents +-------- + +|Name|Description| +|-|-| +|[CVE-2003-0107](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT| +|[CVE-2002-0059](https://nvd.nist.gov/vuln/detail/CVE-2002-0059)|inflateEnd to release memory more than once| +|[CVE-2004-0797](https://nvd.nist.gov/vuln/detail/CVE-2004-0797)|Error handling in inflate and inflateBack causes crash| +|[CVE-2005-1849](https://nvd.nist.gov/vuln/detail/CVE-2005-1849)|inftrees.h bug causes crash| +|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description| +|[CVE-2018-25032](https://nvd.nist.gov/vuln/detail/CVE-2018-25032)|Memory corruption when compressing if the input has many distant matches.| +|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches| +|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels| +|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick| + +Copying +------- + +Some of the files in _test_ are licensed differently: + + - test/data/fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and + is licensed under the Creative Commons Attribution 3.0 license + (CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/ + for more information. + + - test/data/paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper + “Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA + Replication Timing in _Drosophila_†by Federico Comoglio and Renato Paro, + which is licensed under the CC-BY license. See + https://www.ploscompbiol.org/static/license for more information. + + - test/data/lcet10.txt is from Project Gutenberg. It does not have expired + copyright, but is still in the public domain according to the license information. + (https://www.gutenberg.org/ebooks/53). + + - test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri + that reproduced GH-382. It is licensed under the terms of the zlib license. diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/ignore b/internal-complibs/zlib-ng-2.1.2/test/abi/ignore new file mode 100644 index 000000000..583c92184 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/ignore @@ -0,0 +1,12 @@ +# See https://sourceware.org/libabigail/manual/libabigail-concepts.html#suppression-specifications + +[suppress_type] + name = internal_state + +[suppress_type] + name_regexp = z_stream.* + +# Size varies with version number +[suppress_variable] + name_regexp = z(|ng|libng)_(|v)string + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..c9088b86f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..48f8fb6bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..cee35ca46 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips-unknown-linux-gnu.abi new file mode 100644 index 000000000..6a321b540 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips-unknown-linux-gnu.abi @@ -0,0 +1,1032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips64-unknown-linux-gnuabi64.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips64-unknown-linux-gnuabi64.abi new file mode 100644 index 000000000..81925a88c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-mips64-unknown-linux-gnuabi64.abi @@ -0,0 +1,1030 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3d7ca82c1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..ad037fd6a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..5ef350b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..569d084b9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..b2a63a4bd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi @@ -0,0 +1,1281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..cfc0eddc6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1904 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..414f8a96e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..f5b3aa773 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1881 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips-unknown-linux-gnu.abi new file mode 100644 index 000000000..53e2b06b5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips-unknown-linux-gnu.abi @@ -0,0 +1,1241 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips64-unknown-linux-gnuabi64.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips64-unknown-linux-gnuabi64.abi new file mode 100644 index 000000000..3e4322f45 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-mips64-unknown-linux-gnuabi64.abi @@ -0,0 +1,1250 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3164f07e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1895 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..1d97902bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..613f5f2f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1886 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..82d8943b8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,2032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..a03df554a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi @@ -0,0 +1,2064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.2/test/abicheck.md b/internal-complibs/zlib-ng-2.1.2/test/abicheck.md new file mode 100644 index 000000000..57337f588 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abicheck.md @@ -0,0 +1,59 @@ +ABI Compatibility test +---------------------- + +abicheck.sh uses libabigail to check ABI stability. +It will abort if the current source +tree has a change that breaks binary compatibility. + +This protects against the common scenario where: +- an app is compiled against the current zlib-ng +- the system package manager updates the zlib-ng shared library +- the app now crashes because some symbol is + missing or some public structure or parameter + has changed type or size + +If run with --zlib-compat, it verifies that the +current source tree generates a library that +is ABI-compatible with the reference release +of classic zlib. This ensures that building +zlib-ng with --zlib-compat does what it says on the tin. + +abicheck.sh is not perfect, but it can catch +many common compatibility issues. + +Cached files test/abi/*.abi +--------------------------- + +Comparing to the old version of zlib (or zlib-ng) +means someone has to check out and build +the previous source tree and extract its .abi +using abidw. This can be slow. + +If you don't mind the slowness, run abicheck.sh --refresh-if, +and it will download and build the reference version +and extract the .abi on the spot if needed. +(FIXME: should this be the default?) + +On the next run, the reference .abi file will already be +present, and that step will be skipped. +It's stored in the tests/abi directory, +in a file with the architecture and git hash in the name. + +If you're running continuous integration +which clear out the source tree on each run, +and you don't want your build machines +constantly downloading and building the old +version, you can check the .abi file into git. + +To make this easier, a helper script could be written to automatically build +all the configurations tested by .github/workflows/abicheck.yml +Then they could be checked into git en masse by a maintainer +when a new platform is added or a new major version (which +intentionally breaks backwards compatibility) is being prepared. + +Further reading +--------------- + +- https://sourceware.org/libabigail/manual/ +- https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/ +- https://developers.redhat.com/blog/2020/04/02/how-to-write-an-abi-compliance-checker-using-libabigail/ diff --git a/internal-complibs/zlib-ng-2.1.2/test/abicheck.sh b/internal-complibs/zlib-ng-2.1.2/test/abicheck.sh new file mode 100755 index 000000000..1656711f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/abicheck.sh @@ -0,0 +1,163 @@ +#!/bin/sh +set -ex +TESTDIR="$(cd $(dirname "$0"); pwd)" + +usage() { + cat <<_EOF_ +Usage: $0 [--zlib-compat][--refresh][--refresh-if] + +Build shared library with -ggdb, then compare its ABI to the stable +ABI, and abort if differences found. + +Options: +--zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng. +--refresh - build the reference library and extract its ABI rather than using a stored ABI file. +--refresh-if - refresh only if ABI file not present. + +Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS. + +Requires libabigail (on Ubuntu, install package abigail-tools). +_EOF_ +} + +# Print the multiarch tuple for the current (non-cross) machine, +# or the empty string if unavailable. +detect_chost() { + dpkg-architecture -qDEB_HOST_MULTIARCH || + $CC -print-multiarch || + $CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' || + true +} + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +suffix="-ng" +CONFIGURE_ARGS_NG="$CONFIGURE_ARGS" +refresh=false +refresh_if=false +for arg +do + case "$arg" in + --zlib-compat) + suffix="" + CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat" + ;; + --refresh) + refresh=true + ;; + --refresh-if) + refresh_if=true + ;; + --help) + usage + exit 0 + ;; + *) + echo "Unknown arg '$arg'" + usage + exit 1 + ;; + esac +done + +# Choose reference repo and commit +if test "$suffix" = "" +then + # Reference is zlib 1.2.13. + ABI_GIT_REPO=https://github.com/madler/zlib.git + ABI_GIT_COMMIT=04f42ceca40f73e2978b50e93806c2a18c1281fc +else + # Reference is most recent zlib-ng develop with zlib 1.2.12 compatible api. + ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git + ABI_GIT_COMMIT=e4614ebcb9b3e5b108dc983c155e4baf80882311 +fi + +# Test compat build for ABI compatibility with zlib +if test "$CHOST" = "" +then + # Note: don't export CHOST here, as we don't want configure seeing it + # when it's just the name for the build machine. + # Leave it as a plain shell variable, not an environment variable. + CHOST=$(detect_chost) + # Support -m32 for non-cross builds. + case "$CFLAGS" in + *-m32*) M32="-m32";; + *) M32="";; + esac +fi + +# Canonicalize CHOST to work around bug in original zlib's configure +# (Don't export it if it wasn't already exported, else may cause +# default compiler detection failure and shared library link error +# when building both zlib and zlib-ng. +# See https://github.com/zlib-ng/zlib-ng/issues/1219) +CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) + +if test "$CHOST" = "" +then + echo "abicheck: SKIP, as we don't know CHOST" + exit 0 +fi + +ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" +if ! $refresh && $refresh_if && ! test -f "$ABIFILE" +then + refresh=true +fi +abidw --version + +if $refresh +then + # Check out reference source + rm -rf btmp1 + mkdir -p btmp1/src.d + cd btmp1/src.d + git init + git remote add origin $ABI_GIT_REPO + git fetch origin $ABI_GIT_COMMIT + git reset --hard FETCH_HEAD + cd .. + # Build unstripped, uninstalled, very debug shared library + CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS + make -j2 + cd .. + # Find shared library, extract its abi + dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + abidw $dylib1 > "$ABIFILE" + # Maintainers may wish to check $ABIFILE into git when a new + # target is added, or when a major release happens that is + # intended to change the ABI. Alternately, this script could + # just always rebuild the reference source, and dispense with + # caching abi files in git (but that would slow builds down). +fi + +if ! test -f "$ABIFILE" +then + echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if" + exit 1 +fi + +# Build unstripped, uninstalled, very debug shared library +rm -rf btmp2 +mkdir btmp2 +cd btmp2 +CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG +make -j2 +cd .. +# Find shared library, extract its abi +dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) +abidw $dylib2 > btmp2/zlib${suffix}-built.abi + +# Compare it to the reference +# FIXME: use --no-added-syms for now, but we probably want to be more strict. +if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi +then + echo "abicheck: PASS" +else + echo "abicheck: FAIL" + exit 1 +fi diff --git a/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/CMakeLists.txt new file mode 100644 index 000000000..1b87005f7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(zlib-ng-add-subdirecory-test C) + +include(CTest) + +set(BUILD_SHARED_LIBS OFF) +set(ZLIB_ENABLE_TESTS ON CACHE BOOL "Build test binaries" FORCE) + +add_subdirectory(../.. zlib-ng) + +add_executable(app main.c) +target_link_libraries(app zlibstatic) diff --git a/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/main.c b/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/main.c new file mode 100644 index 000000000..638a35b1d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/add-subdirectory-project/main.c @@ -0,0 +1,7 @@ +#include +#include "zlib-ng.h" + +int main(void) { + printf("zlib-ng: %s\n", ZLIBNG_VERSION); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/CMakeLists.txt new file mode 100644 index 000000000..475fe07ce --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.12) + +include(FetchContent) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) + +enable_language(CXX) + +# Search for Google benchmark package +find_package(benchmark QUIET) +if(NOT benchmark_FOUND) + # Fetch google benchmark source code from official repository + set(BENCHMARK_ENABLE_TESTING OFF) + + # Allow specifying alternative Google benchmark repository + if(NOT DEFINED GBENCHMARK_REPOSITORY) + set(GBENCHMARK_REPOSITORY https://github.com/google/benchmark.git) + endif() + if(NOT DEFINED GBENCHMARK_TAG) + set(GBENCHMARK_TAG v1.7.1) + endif() + + FetchContent_Declare(benchmark + GIT_REPOSITORY ${GBENCHMARK_REPOSITORY} + GIT_TAG ${GBENCHMARK_TAG}) + + FetchContent_GetProperties(benchmark) + if(NOT benchmark_POPULATED) + FetchContent_Populate(benchmark) + add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() +endif() + +add_executable(benchmark_zlib + benchmark_adler32.cc + benchmark_adler32_copy.cc + benchmark_compare256.cc + benchmark_compare256_rle.cc + benchmark_crc32.cc + benchmark_main.cc + benchmark_slidehash.cc + ) + +target_compile_definitions(benchmark_zlib PRIVATE -DBENCHMARK_STATIC_DEFINE) +target_include_directories(benchmark_zlib PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + +target_link_libraries(benchmark_zlib zlibstatic benchmark::benchmark) +if(WIN32) + target_link_libraries(benchmark_zlib shlwapi) +endif() + +if(ZLIB_ENABLE_TESTS) + add_test(NAME benchmark_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +if(WITH_BENCHMARK_APPS) + option(BUILD_ALT_BENCH "Link against alternative zlib implementation" OFF) + + # Search for libpng package + find_package(PNG QUIET) + + if(NOT PNG_FOUND) + FetchContent_Declare(PNG + GIT_REPOSITORY https://github.com/glennrp/libpng.git) + + FetchContent_GetProperties(PNG) + if(NOT PNG_POPULATED) + FetchContent_Populate(PNG) + add_subdirectory(${PNG_SOURCE_DIR} ${PNG_BINARY_DIR}) + endif() + endif() + + set(BENCH_APP_SRCS + benchmark_png_encode.cc + benchmark_png_decode.cc + benchmark_main.cc + ) + + add_executable(benchmark_zlib_apps ${BENCH_APP_SRCS}) + + if(DEFINED BUILD_ALT_BENCH) + set(ZLIB_ALT_LIB "libz.a" CACHE FILEPATH "Optional alternative zlib implementation (defaults to stock zlib)") + add_executable(benchmark_zlib_apps_alt ${BENCH_APP_SRCS}) + target_link_libraries(benchmark_zlib_apps_alt libpng.a ${ZLIB_ALT_LIB} benchmark::benchmark) + target_compile_definitions(benchmark_zlib_apps_alt PRIVATE BUILD_ALT=1) + target_include_directories(benchmark_zlib_apps_alt PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + endif() + + target_include_directories(benchmark_zlib_apps PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + + # We need the static png library if we're statically linking to zlib, + # otherwise it will resolve these things in the system provided dynamic + # libraries (likely linked to stock zlib) + target_link_libraries(benchmark_zlib_apps libpng.a zlibstatic benchmark::benchmark) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/README.md b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/README.md new file mode 100644 index 000000000..5dce7f51b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/README.md @@ -0,0 +1,47 @@ +## Benchmarks +These benchmarks are written using [Google Benchmark](https://github.com/google/benchmark). + +*Repetitions* + +To increase the number of times each benchmark iteration is run use: + +``` +--benchmark_repetitions=20 +``` + +*Filters* + +To filter out which benchmarks are performed use: + +``` +--benchmark_filter="adler32*" +``` + +There are two different benchmarks, micro and macro. + +### Benchmark benchmark_zlib +These are microbenchmarks intended to test lower level subfunctions of the library. + +Benchmarks include impelementations of: + - Adler32 + - CRC + - 256 byte comparisons + - SIMD accelerated "slide hash" routine + +By default these benchmarks report things on the nanosecond scale and are small enough +to measure very minute diferences. + +### Benchmark benchmark_zlib_apps +These benchmarks measure applications of zlib as a whole. Currently the only examples +are PNG encoding and decoding. The PNG encode and decode tests leveraging procedurally +generated and highly compressible image data. + +Additionally, a test called `png_decode_realistic` that will decode any RGB 8 BPP encoded +set of PNGs in the working directory under a directory named "test_pngs" with files named +{0..1}.png. If these images do not exist, they will error out and the benchmark will move +on to the next set of benchmarks. + +*benchmark_zlib_apps_alt* + +The user can compile a comparison benchmark application linking to any zlib-compatible +implementation of his or her choosing. diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32.cc new file mode 100644 index 000000000..5b0b65d67 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32.cc @@ -0,0 +1,89 @@ +/* benchmark_adler32.cc -- benchmark adler32 variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class adler32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_func adler32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_ADLER32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32, name)->Range(2048, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32(c, adler32_c, 1); + +#ifdef ARM_NEON +BENCHMARK_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +BENCHMARK_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +BENCHMARK_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSSE3 +BENCHMARK_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32_copy.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32_copy.cc new file mode 100644 index 000000000..cbee780b7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_adler32_copy.cc @@ -0,0 +1,118 @@ +/* benchmark_adler32_copy.cc -- benchmark adler32 (elided copy) variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +typedef uint32_t (*adler32_cpy_func)(uint32_t adler, unsigned char *dst, const uint8_t *buf, size_t len); + +class adler32_copy: public benchmark::Fixture { +private: + uint32_t *random_ints_src; + uint32_t *random_ints_dst; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints_src = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + random_ints_dst = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints_src != NULL); + assert(random_ints_dst != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints_src[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_cpy_func adler32_func) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32_func(hash, (unsigned char *)random_ints_dst, + (const unsigned char*)random_ints_src, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints_src); + zng_free(random_ints_dst); + } +}; + +#define BENCHMARK_ADLER32_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +#define BENCHMARK_ADLER32_BASELINE_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, [](uint32_t init_sum, unsigned char *dst, \ + const uint8_t *buf, size_t len) -> uint32_t { \ + memcpy(dst, buf, (size_t)len); \ + return fptr(init_sum, buf, len); \ + }); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32_BASELINE_COPY(c, adler32_c, 1); + +#ifdef ARM_NEON +/* If we inline this copy for neon, the function would go here */ +//BENCHMARK_ADLER32_COPY(neon, adler32_neon, test_cpu_features.arm.has_neon); +BENCHMARK_ADLER32_BASELINE_COPY(neon_copy_baseline, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +//BENCHMARK_ADLER32_COPY(vmx_inline_copy, adler32_fold_copy_vmx, test_cpu_features.power.has_altivec); +BENCHMARK_ADLER32_BASELINE_COPY(vmx_copy_baseline, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +//BENCHMARK_ADLER32_COPY(power8_inline_copy, adler32_fold_copy_power8, test_cpu_features.power.has_arch_2_07); +BENCHMARK_ADLER32_BASELINE_COPY(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSE42 +BENCHMARK_ADLER32_BASELINE_COPY(sse42_baseline, adler32_ssse3, test_cpu_features.x86.has_ssse3); +BENCHMARK_ADLER32_COPY(sse42, adler32_fold_copy_sse42, test_cpu_features.x86.has_sse42); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32_BASELINE_COPY(avx2_baseline, adler32_avx2, test_cpu_features.x86.has_avx2); +BENCHMARK_ADLER32_COPY(avx2, adler32_fold_copy_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, test_cpu_features.x86.has_avx512); +BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32_BASELINE_COPY(avx512_vnni_baseline, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +BENCHMARK_ADLER32_COPY(avx512_vnni, adler32_fold_copy_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256.cc new file mode 100644 index 000000000..3ab04d202 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256.cc @@ -0,0 +1,84 @@ +/* benchmark_compare256.cc -- benchmark compare256 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_COMPARE_SIZE (256) + +class compare256: public benchmark::Fixture { +private: + uint8_t *str1; + uint8_t *str2; + +public: + void SetUp(const ::benchmark::State& state) { + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + } + + void Bench(benchmark::State& state, compare256_func compare256) { + int32_t match_len = (int32_t)state.range(0) - 1; + uint32_t len = 0; + + str2[match_len] = 0; + for (auto _ : state) { + len = compare256((const uint8_t *)str1, (const uint8_t *)str2); + } + str2[match_len] = 'a'; + + benchmark::DoNotOptimize(len); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(str1); + zng_free(str2); + } +}; + +#define BENCHMARK_COMPARE256(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(compare256, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(compare256, name)->Range(1, MAX_COMPARE_SIZE); + +BENCHMARK_COMPARE256(c, compare256_c, 1); + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +BENCHMARK_COMPARE256(unaligned_16, compare256_unaligned_16, 1); +#ifdef HAVE_BUILTIN_CTZ +BENCHMARK_COMPARE256(unaligned_32, compare256_unaligned_32, 1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(unaligned_64, compare256_unaligned_64, 1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER9 +BENCHMARK_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00); +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256_rle.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256_rle.cc new file mode 100644 index 000000000..5a8afd694 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_compare256_rle.cc @@ -0,0 +1,73 @@ +/* benchmark_compare256_rle.cc -- benchmark compare256_rle variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "compare256_rle.h" +# include "cpu_features.h" +} + +#define MAX_COMPARE_SIZE (256) + +class compare256_rle: public benchmark::Fixture { +private: + uint8_t *str1; + uint8_t *str2; + +public: + void SetUp(const ::benchmark::State& state) { + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + } + + void Bench(benchmark::State& state, compare256_rle_func compare256_rle) { + int32_t match_len = (int32_t)state.range(0); + uint32_t len; + + str2[match_len] = 0; + for (auto _ : state) { + len = compare256_rle((const uint8_t *)str1, (const uint8_t *)str2); + } + str2[match_len] = 'a'; + + benchmark::DoNotOptimize(len); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(str1); + zng_free(str2); + } +}; + +#define BENCHMARK_COMPARE256_RLE(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(compare256_rle, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(compare256_rle, name)->Range(1, MAX_COMPARE_SIZE); + +BENCHMARK_COMPARE256_RLE(c, compare256_rle_c, 1); + +#ifdef UNALIGNED_OK +BENCHMARK_COMPARE256_RLE(unaligned_16, compare256_rle_unaligned_16, 1); +#ifdef HAVE_BUILTIN_CTZ +BENCHMARK_COMPARE256_RLE(unaligned_32, compare256_rle_unaligned_32, 1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256_RLE(unaligned_64, compare256_rle_unaligned_64, 1); +#endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_crc32.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_crc32.cc new file mode 100644 index 000000000..b2b9673d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_crc32.cc @@ -0,0 +1,69 @@ +/* benchmark_crc32.cc -- benchmark crc32 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class crc32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, crc32_func crc32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = crc32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_CRC32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(crc32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(crc32, name)->Range(1, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_CRC32(braid, PREFIX(crc32_braid), 1); + +#ifdef ARM_ACLE +BENCHMARK_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32); +#elif defined(POWER8_VSX) +BENCHMARK_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07); +#elif defined(S390_CRC32_VX) +BENCHMARK_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx); +#elif defined(X86_PCLMULQDQ_CRC) +/* CRC32 fold does a memory copy while hashing */ +BENCHMARK_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq); +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_main.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_main.cc new file mode 100644 index 000000000..3ef2c5e87 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_main.cc @@ -0,0 +1,28 @@ +/* benchmark_main.cc -- benchmark suite main entry point + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +#ifndef BUILD_ALT +extern "C" { +# include "zbuild.h" +# include "../test_cpu_features.h" + + struct cpu_features test_cpu_features; +} +#endif + +int main(int argc, char** argv) { +#ifndef BUILD_ALT + cpu_check_features(&test_cpu_features); +#endif + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + + return EXIT_SUCCESS; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_decode.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_decode.cc new file mode 100644 index 000000000..c037976c8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_decode.cc @@ -0,0 +1,126 @@ +#include +#include +#include "benchmark_png_shared.h" +#include + +class png_decode: public benchmark::Fixture { +protected: + png_dat inpng[10]; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *output_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width*height); + } + + void SetUp(const ::benchmark::State& state) { + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + assert(output_img_buf != NULL); + init_img(output_img_buf, IMWIDTH, IMHEIGHT); + + /* First we need to author the png bytes to be decoded */ + for (int i = 0; i < 10; ++i) { + inpng[i] = {NULL, 0, 0}; + encode_png(output_img_buf, &inpng[i], i, IMWIDTH, IMHEIGHT); + } + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + int compress_lvl = state.range(0); + png_parse_dat in = { inpng[compress_lvl].buf }; + uint32_t width, height; + decode_png(&in, (png_bytepp)&output_img_buf, IMWIDTH * IMHEIGHT * 3, width, height); + } + } + + void TearDown(const ::benchmark::State &state) { + free(output_img_buf); + for (int i = 0; i < 10; ++i) { + free(inpng[i].buf); + } + } +}; + +class png_decode_realistic: public png_decode { +private: + bool test_files_found = false; + +public: + void SetUp(const ::benchmark::State &state) { + output_img_buf = NULL; + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Let's take all the images at different compression levels and jam their bytes into buffers */ + char test_fname[25]; + FILE *files[10]; + + /* Set all to NULL */ + memset(files, 0, sizeof(FILE*)); + + for (size_t i = 0; i < 10; ++i) { + sprintf(test_fname, "test_pngs/%1lu.png", i); + FILE *in_img = fopen(test_fname, "r"); + if (in_img == NULL) { + for (size_t j = 0; j < i; ++j) { + if (files[j]) + fclose(files[j]); + } + + /* For proper cleanup */ + for (size_t j = i; j < 10; ++j) { + inpng[i] = { NULL, 0, 0 }; + } + + return; + } + files[i] = in_img; + } + + test_files_found = true; + /* Now that we've established we have all the png files, let's read all of their bytes into buffers */ + for (size_t i = 0; i < 10; ++i) { + FILE *in_file = files[i]; + fseek(in_file, 0, SEEK_END); + size_t num_bytes = ftell(in_file); + rewind(in_file); + + uint8_t *raw_file = (uint8_t*)malloc(num_bytes); + if (raw_file == NULL) + abort(); + + inpng[i].buf = raw_file; + inpng[i].len = num_bytes; + inpng[i].buf_rem = 0; + + size_t bytes_read = fread(raw_file, 1, num_bytes, in_file); + if (bytes_read != num_bytes) { + fprintf(stderr, "couldn't read all of the bytes for file test_pngs/%lu.png", i); + abort(); + } + + fclose(in_file); + } + } + + void Bench(benchmark::State &state) { + if (!test_files_found) { + state.SkipWithError("Test imagery in test_pngs not found"); + } + + png_decode::Bench(state); + } +}; + +BENCHMARK_DEFINE_F(png_decode, png_decode)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode, png_decode)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); + +BENCHMARK_DEFINE_F(png_decode_realistic, png_decode_realistic)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode_realistic, png_decode_realistic)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_encode.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_encode.cc new file mode 100644 index 000000000..f1c597d36 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_encode.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include "benchmark_png_shared.h" + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +class png_encode: public benchmark::Fixture { +private: + png_dat outpng; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *input_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width * height); + } + + void SetUp(const ::benchmark::State& state) { + input_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + outpng.buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Using malloc rather than zng_alloc so that we can call realloc. + * IMWIDTH * IMHEIGHT is likely to be more than enough bytes, though, + * given that a simple run length encoding already pretty much can + * reduce to this */ + outpng.len = 0; + outpng.buf_rem = IMWIDTH * IMHEIGHT * 3; + assert(input_img_buf != NULL); + assert(outpng.buf != NULL); + init_img(input_img_buf, IMWIDTH, IMHEIGHT); + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + encode_png((png_bytep)input_img_buf, &outpng, state.range(0), IMWIDTH, IMHEIGHT); + outpng.buf_rem = outpng.len; + outpng.len = 0; + } + } + + void TearDown(const ::benchmark::State &state) { + free(input_img_buf); + free(outpng.buf); + } +}; + +BENCHMARK_DEFINE_F(png_encode, encode_compressible)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_encode, encode_compressible)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_shared.h b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_shared.h new file mode 100644 index 000000000..926b4d964 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_png_shared.h @@ -0,0 +1,146 @@ +#pragma once + +#include +#include +#include + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +extern "C" { +# include +} + +typedef struct _png_dat { + uint8_t *buf; + int64_t len; + size_t buf_rem; +} png_dat; + +typedef struct _png_parse_dat { + uint8_t *cur_pos; +} png_parse_dat; + +/* Write a customized write callback so that we write back to an in-memory buffer. + * This allows the testing to not involve disk IO */ +static void png_write_cb(png_structp pngp, png_bytep data, png_size_t len) { + png_dat *dat = (png_dat*)png_get_io_ptr(pngp); + size_t curSize = dat->len + len; + + /* realloc double the requested buffer size to prevent excessive reallocs */ + if (dat->buf_rem < len) { + dat->buf = (uint8_t*)realloc(dat->buf, dat->len + dat->buf_rem + 2 * len); + + if (!dat->buf) { + /* Pretty unlikely but we'll put it here just in case */ + fprintf(stderr, "realloc failed, exiting\n"); + exit(1); + } + + dat->buf_rem += 2 * len; + } + + memcpy(dat->buf + dat->len, data, len); + dat->len = curSize; + dat->buf_rem -= len; +} + +static void init_compressible(png_bytep buf, size_t num_pix) { + /* It doesn't actually matter what we make this, but for + * the sake of a reasonable test image, let's make this + * be a stripe of R, G, & B, with no alpha channel */ + int32_t i = 0; + int32_t red_stop = num_pix / 3; + int32_t blue_stop = 2 * num_pix / 3; + int32_t green_stop = num_pix; + + for (int32_t x = 0; i < red_stop; x += 3, ++i) { + buf[x] = 255; + buf[x + 1] = 0; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < blue_stop; x+= 3, ++i) { + buf[x] = 0; + buf[x + 1] = 255; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < green_stop; x += 3, ++i) { + buf[x] = 0; + buf[x + 1] = 0; + buf[x + 2] = 255; + } +} + +static inline void encode_png(png_bytep buf, png_dat *outpng, int32_t comp_level, uint32_t width, uint32_t height) { + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + /* Most of this error handling is _likely_ not necessary. Likewise it's likely + * a lot of this stuff can be done in the setup function to avoid measuring this + * fixed setup time, but for now we'll do it here */ + if (!png) abort(); + + png_infop info = png_create_info_struct(png); + if (!info) abort(); + + png_set_write_fn(png, outpng, png_write_cb, NULL); + png_bytep *png_row_ptrs = new png_bytep[height]; + for (int i = 0; i < IMHEIGHT; ++i) { + png_row_ptrs[i] = (png_bytep)&buf[3*i*width]; + } + + png_set_IHDR(png, info, IMWIDTH, IMHEIGHT, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png, info); + png_set_compression_level(png, comp_level); + png_set_filter(png, 0, PNG_FILTER_NONE); + png_write_image(png, (png_bytepp)png_row_ptrs); + png_write_end(png, NULL); + png_destroy_write_struct(&png, &info); + delete[] png_row_ptrs; +} + +static void read_from_pngdat(png_structp png, png_bytep out, png_size_t bytes_to_read) { + png_parse_dat *io = (png_parse_dat*)png_get_io_ptr(png); + memcpy(out, io->cur_pos, bytes_to_read); + io->cur_pos += bytes_to_read; +} + +static inline int decode_png(png_parse_dat *dat, png_bytepp out_bytes, size_t in_size, uint32_t &width, uint32_t &height) { + png_structp png = NULL; + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png) abort(); + png_infop info = NULL; + info = png_create_info_struct(png); + if (!info) abort(); + + png_set_read_fn(png, dat, read_from_pngdat); + png_read_info(png, info); + + int bit_depth = 0, color_type = -1; + png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + + size_t im_size = width * height * bit_depth/8 * 3; + if (color_type != PNG_COLOR_TYPE_RGB) { + fprintf(stderr, "expected an 8 bpp RGB image\n"); + abort(); + } + + if (im_size > in_size) { + *out_bytes = (png_bytep)realloc(*out_bytes, im_size); + } + + png_bytep *out_rows = new png_bytep[height]; + for (size_t i = 0; i < height; ++i) + out_rows[i] = *out_bytes + (width*i*3); + + png_read_rows(png, out_rows, NULL, height); + png_destroy_read_struct(&png, &info, NULL); + delete[] out_rows; + + return im_size; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_slidehash.cc b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_slidehash.cc new file mode 100644 index 000000000..238cc1f65 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/benchmarks/benchmark_slidehash.cc @@ -0,0 +1,86 @@ +/* benchmark_slidehash.cc -- benchmark slide_hash variants + * Copyright (C) 2022 Adam Stylinski, Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "deflate.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS 32768 + +class slide_hash: public benchmark::Fixture { +private: + uint16_t *l0; + uint16_t *l1; + deflate_state *s_g; + +public: + void SetUp(const ::benchmark::State& state) { + l0 = (uint16_t *)zng_alloc(HASH_SIZE * sizeof(uint16_t)); + + for (uint32_t i = 0; i < HASH_SIZE; i++) { + l0[i] = rand(); + } + + l1 = (uint16_t *)zng_alloc(MAX_RANDOM_INTS * sizeof(uint16_t)); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + l1[i] = rand(); + } + + deflate_state *s = (deflate_state*)malloc(sizeof(deflate_state)); + s->head = l0; + s->prev = l1; + s_g = s; + } + + void Bench(benchmark::State& state, slide_hash_func slide_hash) { + s_g->w_size = (uint32_t)state.range(0); + + for (auto _ : state) { + slide_hash(s_g); + benchmark::DoNotOptimize(s_g); + } + } + + void TearDown(const ::benchmark::State& state) { + zng_free(l0); + zng_free(l1); + } +}; + +#define BENCHMARK_SLIDEHASH(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(slide_hash, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(slide_hash, name)->RangeMultiplier(2)->Range(1024, MAX_RANDOM_INTS); + +BENCHMARK_SLIDEHASH(c, slide_hash_c, 1); + +#ifdef ARM_NEON +BENCHMARK_SLIDEHASH(neon, slide_hash_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER8_VSX +BENCHMARK_SLIDEHASH(power8, slide_hash_power8, test_cpu_features.power.has_arch_2_07); +#endif +#ifdef PPC_VMX +BENCHMARK_SLIDEHASH(vmx, slide_hash_vmx, test_cpu_features.power.has_altivec); +#endif + +#ifdef X86_SSE2 +BENCHMARK_SLIDEHASH(sse2, slide_hash_sse2, test_cpu_features.x86.has_sse2); +#endif +#ifdef X86_AVX2 +BENCHMARK_SLIDEHASH(avx2, slide_hash_avx2, test_cpu_features.x86.has_avx2); +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/compress-and-verify.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/compress-and-verify.cmake new file mode 100644 index 000000000..d2d9917a9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/compress-and-verify.cmake @@ -0,0 +1,283 @@ +# compress-and-verify.cmake -- Runs a test against an input file to make sure that the specified +# targets are able to to compress and then decompress successfully. Optionally verify +# the results with gzip. Output files are generated with unique names to prevent parallel +# tests from corrupting one another. Default target arguments are compatible with minigzip. + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# that test a specific input file for compression or decompression. + +# Required Variables +# INPUT - Input file to test +# TARGET or - Command to run for both compress and decompress +# COMPRESS_TARGET and - Command to run to compress input file +# DECOMPRESS_TARGET - Command to run to decompress output file + +# Optional Variables +# TEST_NAME - Name of test to use when constructing output file paths +# COMPRESS_ARGS - Arguments to pass for compress command (default: -c -k) +# DECOMPRESS_ARGS - Arguments to pass to decompress command (default: -d -c) + +# GZIP_VERIFY - Verify that gzip can decompress the COMPRESS_TARGET output and +# verify that DECOMPRESS_TARGET can decompress gzip output of INPUT +# COMPARE - Verify decompressed output is the same as input +# FILEMODE - Pass data to/from (de)compressor using files instead of stdin/stdout +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +if(TARGET) + set(COMPRESS_TARGET ${TARGET}) + set(DECOMPRESS_TARGET ${TARGET}) +endif() + +if(NOT DEFINED INPUT OR NOT DEFINED COMPRESS_TARGET OR NOT DEFINED DECOMPRESS_TARGET) + message(FATAL_ERROR "Compress test arguments missing") +endif() + +# Set default values +if(NOT DEFINED COMPARE) + set(COMPARE ON) +endif() +if(NOT DEFINED FILEMODE) + set(FILEMODE OFF) +endif() +if(NOT DEFINED COMPRESS_ARGS) + set(COMPRESS_ARGS -3 -k) + if(NOT FILEMODE) + list(APPEND COMPRESS_ARGS -c) + endif() +endif() +if(NOT DEFINED DECOMPRESS_ARGS) + set(DECOMPRESS_ARGS -d -k) + if(NOT FILEMODE) + list(APPEND DECOMPRESS_ARGS -c) + endif() +endif() +if(NOT DEFINED GZIP_VERIFY) + set(GZIP_VERIFY ON) +endif() +if(NOT DEFINED SUCCESS_EXIT) + set(SUCCESS_EXIT 0) +endif() + +# Use test name from input file name +if(NOT DEFINED TEST_NAME) + get_filename_component(TEST_NAME "${INPUT}" NAME) +endif() + +# Generate unique output path so multiple tests can be executed at the same time +string(RANDOM LENGTH 6 UNIQUE_ID) +string(REPLACE "." "-" TEST_NAME "${TEST_NAME}") +set(OUTPUT_BASE "${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${TEST_NAME}-${UNIQUE_ID}") + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT_BASE}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +# Cleanup temporary files +macro(cleanup_always) + file(GLOB TEMP_FILES ${OUTPUT_BASE}*) + file(REMOVE ${TEMP_FILES}) +endmacro() +# Clean up temporary files if not on CI +macro(cleanup) + if(NOT DEFINED ENV{CI}) + cleanup_always() + endif() +endmacro() + +# Show differences between two files +macro(diff src1 src2) + find_program(XXD xxd) + if(XXD) + find_program(DIFF diff) + if(DIFF) + set(XXD_COMMAND ${XXD} ${src1} ${src1}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + set(XXD_COMMAND ${XXD} ${src2} ${src2}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + + set(DIFF_COMMAND ${DIFF} -u ${src1}.hex ${src2}.hex) + execute_process(COMMAND ${DIFF_COMMAND} + OUTPUT_FILE ${src2}.diff) + + file(READ ${src2}.diff DIFF_OUTPUT) + message(STATUS "Diff:\n${DIFF_OUTPUT}") + + if(NOT DEFINED ENV{CI}) + file(REMOVE ${src1}.hex ${src2}.hex ${src2}.diff) + endif() + endif() + endif() +endmacro() + + +macro(exec_streams tcmd tsrc tdst) + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${tcmd}" + -DINPUT=${tsrc} + -DOUTPUT=${tdst} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +endmacro() + +macro(exec_files tcmd tsrc) + execute_process(COMMAND + ${tcmd} ${tsrc} + RESULT_VARIABLE CMD_RESULT) +endmacro() + +# Compress input file +if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find compress input: ${INPUT}") +endif() + +set(COMPRESS_COMMAND ${COMPRESS_TARGET} ${COMPRESS_ARGS}) + +set(INPUT_FILE ${OUTPUT_BASE}) + +# Make CMake copy and rename file in one operation +configure_file(${INPUT} ${INPUT_FILE} COPYONLY) + +message(STATUS "Compress ${COMPRESS_COMMAND}") +message(STATUS " Source file: ${INPUT}") +message(STATUS " Compression input file: ${INPUT_FILE}") +message(STATUS " Output: ${OUTPUT_BASE}.gz") + +if(FILEMODE) + exec_files("${COMPRESS_COMMAND}" "${INPUT_FILE}") +else() + exec_streams("${COMPRESS_COMMAND}" "${INPUT_FILE}" "${OUTPUT_BASE}.gz") +endif() + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Compress failed: ${CMD_RESULT}") +endif() + +# Decompress output +if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress input: ${OUTPUT_BASE}.gz") +endif() + +set(DECOMPRESS_COMMAND ${DECOMPRESS_TARGET} ${DECOMPRESS_ARGS}) + +message(STATUS "Decompress ${DECOMPRESS_COMMAND}") +message(STATUS " Input: ${OUTPUT_BASE}.gz") +message(STATUS " Output: ${OUTPUT_BASE}") + +if(FILEMODE) + exec_files("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz") +else() + exec_streams("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz" "${OUTPUT_BASE}") +endif() + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress failed: ${CMD_RESULT}") +endif() + +if(COMPARE) + message(STATUS "Diff comparison") + message(STATUS " Input: ${INPUT}") + message(STATUS " Output: ${OUTPUT_BASE}") + + # Compare decompressed output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE} + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}) + cleanup() + message(FATAL_ERROR "Compare decompress failed: ${CMD_RESULT}") + endif() +endif() + +if(GZIP_VERIFY AND NOT "${COMPRESS_ARGS}" MATCHES "-T") + # Transparent writing does not use gzip format + find_program(GZIP gzip) + if(GZIP) + if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find gzip decompress input: ${OUTPUT_BASE}.gz") + endif() + + # Check gzip can decompress our compressed output + set(GZ_DECOMPRESS_COMMAND ${GZIP} -d) + + message(STATUS "Gzip decompress ${GZ_DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}.gz") + message(STATUS " Output: ${OUTPUT_BASE}-ungzip") + + exec_streams("${GZ_DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz" "${OUTPUT_BASE}-ungzip") + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compare gzip output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-ungzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-ungzip) + cleanup() + message(FATAL_ERROR "Compare gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compress input file with gzip + set(GZ_COMPRESS_COMMAND ${GZIP} --stdout) + + message(STATUS "Gzip compress ${GZ_COMPRESS_COMMAND}") + message(STATUS " Input: ${INPUT}") + message(STATUS " Output: ${OUTPUT_BASE}-gzip.gz") + + exec_streams("${GZ_COMPRESS_COMMAND}" "${INPUT}" "${OUTPUT_BASE}-gzip.gz") + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip compress failed: ${CMD_RESULT}") + endif() + + if(NOT EXISTS ${OUTPUT_BASE}-gzip.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress gzip input: ${OUTPUT_BASE}-gzip.gz") + endif() + + message(STATUS "Decompress gzip ${DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}-gzip.gz") + message(STATUS " Output: ${OUTPUT_BASE}-gzip") + + # Check decompress target can handle gzip compressed output + if(FILEMODE) + exec_files("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}-gzip.gz") + else() + exec_streams("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}-gzip.gz" "${OUTPUT_BASE}-gzip") + endif() + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress gzip failed: ${CMD_RESULT}") + endif() + + if(COMPARE) + # Compare original input file with gzip decompressed output + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-gzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-gzip) + cleanup() + message(FATAL_ERROR "Compare decompress gzip failed: ${CMD_RESULT}") + endif() + endif() + endif() +endif() + +cleanup_always() diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-compare.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-compare.cmake new file mode 100644 index 000000000..eb2218dcb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-compare.cmake @@ -0,0 +1,72 @@ +# run-and-compare.cmake -- Runs a command and compares its output to an expected value + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Required Variables +# COMMAND - Command to run +# OUTPUT - Standard output +# COMPARE - String to compare output against + +# Optional Variables +# INPUT - Standard input +# IGNORE_LINE_ENDINGS - Ignore line endings when comparing output + +if(NOT DEFINED OUTPUT OR NOT DEFINED COMPARE OR NOT DEFINED COMMAND) + message(FATAL_ERROR "Run and compare arguments missing") +endif() + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +if(INPUT) + # Run command with stdin input and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DINPUT=${INPUT} + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +else() + # Run command and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run before compare failed: ${CMD_RESULT}") +endif() + +# Use configure_file to normalize line-endings +if(IGNORE_LINE_ENDINGS) + # Rewrite files with normalized line endings to temporary directory + get_filename_component(COMPARE_NAME ${COMPARE} NAME) + set(COMPARE_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${COMPARE_NAME}.cmp) + configure_file(${COMPARE} ${COMPARE_TEMP} NEWLINE_STYLE LF) + set(COMPARE ${COMPARE_TEMP}) + + get_filename_component(OUTPUT_NAME ${OUTPUT} NAME) + set(OUTPUT_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${OUTPUT_NAME}.cmp) + configure_file(${OUTPUT} ${OUTPUT_TEMP} NEWLINE_STYLE LF) + set(OUTPUT ${OUTPUT_TEMP}) +endif() + +# Compare that output is equal to specified file +execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${COMPARE} ${OUTPUT} + RESULT_VARIABLE CMD_RESULT) + +# Delete temporary files used to normalize line-endings +if(IGNORE_LINE_ENDINGS) + file(REMOVE ${COMPARE} ${OUTPUT}) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run compare failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-redirect.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-redirect.cmake new file mode 100644 index 000000000..6651d1a30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/run-and-redirect.cmake @@ -0,0 +1,54 @@ +# run-and-redirect.cmake -- Runs a command and validates exit code + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Normally ctest will always fail with non-zero exit code, but we have tests +# that need to check specific exit codes. + +# Required Variables +# COMMAND - Command to run + +# Optional Variables +# INPUT - Standard input +# OUTPUT - Standard output (default: /dev/null) +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +# If no output is specified, discard output +if(NOT DEFINED OUTPUT) + if(WIN32) + set(OUTPUT NUL) + else() + set(OUTPUT /dev/null) + endif() +endif() + +if(INPUT) + # Check to see that input file exists + if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find input: ${INPUT}") + endif() + # Execute with both stdin and stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + INPUT_FILE ${INPUT} + OUTPUT_FILE ${OUTPUT}) +else() + # Execute with only stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + OUTPUT_FILE ${OUTPUT}) +endif() + +# Check if exit code is in list of successful exit codes +if(SUCCESS_EXIT) + list(FIND SUCCESS_EXIT ${CMD_RESULT} _INDEX) + if (${_INDEX} GREATER -1) + set(CMD_RESULT 0) + endif() +endif() + +# Check to see if successful +if(CMD_RESULT) + message(FATAL_ERROR "${COMMAND} failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/test-cves.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-cves.cmake new file mode 100644 index 000000000..4a0860403 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-cves.cmake @@ -0,0 +1,33 @@ +# test-cves.cmake -- Tests targeting common vulnerabilities and exposures + +set(CVES CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096) +foreach(cve ${CVES}) + set(CVE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ -d) + add_test(NAME ${cve} + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${CVE_COMMAND}" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${cve}/test.gz + "-DSUCCESS_EXIT=0;1" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) +endforeach() + +set(CVE_COMPRESS_LEVELS 6 1 2) +foreach(cve_compress_level ${CVE_COMPRESS_LEVELS}) + add_test(NAME CVE-2018-25032-fixed-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-F;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/fixed.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + + add_test(NAME CVE-2018-25032-default-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/default.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/test-data.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-data.cmake new file mode 100644 index 000000000..e60c356e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-data.cmake @@ -0,0 +1,68 @@ +# test-data.cmake - Tests targeting data files in the data directory + +# Test compress and verify test against data file using extra args +macro(test_minigzip name path) + # Construct compression arguments for minigzip + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id minigzip-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + endif() +endmacro() + +# List of arg combinations to use during compression +set(TEST_CONFIGS + -R # Z_RLE + -h # Z_HUFFMAN_ONLY + -T # Direct store + -0 # No compression + -1 # Deflate quick + -2 # Deflate fast + -4 # Deflate medium (lazy matches) + "-5;-F" # Deflate medium (Z_FIXED) + -6 # Deflate medium + -9 # Deflate slow + "-9;-f" # Deflate slow (Z_FILTERED) +) + +# Enumerate all files in data directory to run tests against +file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) + +# For all files in the data directory, run tests against them +foreach(test_file_path ${TEST_FILE_PATHS}) + if("${test_file_path}" MATCHES ".gz$" OR "${test_file_path}" MATCHES ".out$" OR + "${test_file_path}" MATCHES "/.git/" OR "${test_file_path}" MATCHES ".md$") + continue() + endif() + foreach(test_config ${TEST_CONFIGS}) + get_filename_component(test_name ${test_file_path} NAME) + if (test_name STREQUAL "") + continue() + endif() + test_minigzip(${test_name} ${test_file_path} ${test_config}) + endforeach() +endforeach() + +# Additional tests to verify with automatic data type detection arg +test_minigzip("detect-text" "data/lcet10.txt" -A) +test_minigzip("detect-binary" "data/paper-100k.pdf" -A) diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/test-issues.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-issues.cmake new file mode 100644 index 000000000..1ffb3abda --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-issues.cmake @@ -0,0 +1,68 @@ +# test-issues.cmake -- Tests targeting specific GitHub issues + +add_test(NAME GH-361 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-4" + -DTEST_NAME=GH-361-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-361/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-364 + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=1;5;9;3" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-364-test-bin + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-364/test.bin + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-382 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-m;1;-w;-15;-1;-s;4" + "-DDECOMPRESS_ARGS=-c;-d;-m;1;-w;-15" + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-382-defneg3-dat + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-382/defneg3.dat + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-segfault + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;9744;1;91207" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-segfault-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-incomplete-read + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;88933;1;195840;2;45761" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-incomplete-read-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-zero-stored-block + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;15248;1;1050;2;25217" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-zero-stored-block-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-751 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-751-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-751/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) diff --git a/internal-complibs/zlib-ng-2.1.2/test/cmake/test-tools.cmake b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-tools.cmake new file mode 100644 index 000000000..c2a683fbd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/cmake/test-tools.cmake @@ -0,0 +1,80 @@ +# test-tools.cmake -- Tests targeting tool coverage + +# Compress and decompress using file_compress/file_decompress, optionally also testing MMAP +add_test(NAME minigzip-file_compress + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + -DFILEMODE=ON + -DGZIP_VERIFY=ON + -DTEST_NAME=minigzip-file_compress + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/paper-100k.pdf + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME minideflate-file_compress + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + -DFILEMODE=ON + -DGZIP_VERIFY=OFF + -DTEST_NAME=minideflate-file_compress + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/paper-100k.pdf + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +# Test --help and invalid parameters for our tools +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--help") +add_test(NAME minigzip-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--invalid") +add_test(NAME minigzip-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--help") +add_test(NAME minideflate-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--invalid") +add_test(NAME minideflate-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${SWITCHLEVELS_COMMAND} "--help") +add_test(NAME switchlevels-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +# Test generated crc32 tables match tables in source directory +add_test(NAME makecrct + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKECRCT_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/crc32_braid_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/crc32_braid_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated inflate tables match tables in source directory +add_test(NAME makefixed + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKEFIXED_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/inffixed_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/inffixed_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated tree tables match tables in source directory +add_test(NAME maketrees + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKETREES_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/trees_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/trees_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) diff --git a/internal-complibs/zlib-ng-2.1.2/test/data/fireworks.jpg b/internal-complibs/zlib-ng-2.1.2/test/data/fireworks.jpg new file mode 100644 index 0000000000000000000000000000000000000000..078cf1755dc0853e97ad30fc7af4d6af0b67047e GIT binary patch literal 123093 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
    ma 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

    3ZRBxkF?%H#_f~x|{{V*%h1A?S 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 AYXATM literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.2/test/data/lcet10.txt b/internal-complibs/zlib-ng-2.1.2/test/data/lcet10.txt new file mode 100644 index 000000000..1dbdfc56e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/data/lcet10.txt @@ -0,0 +1,7519 @@ + + +The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC TEXTS + + + + + WORKSHOP ON ELECTRONIC TEXTS + + PROCEEDINGS + + + + Edited by James Daly + + + + + + + + 9-10 June 1992 + + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + + *** *** *** ****** *** *** *** + + + TABLE OF CONTENTS + + +Acknowledgements + +Introduction + +Proceedings + Welcome + Prosser Gifford and Carl Fleischhauer + + Session I. Content in a New Form: Who Will Use It and What Will They Do? + James Daly (Moderator) + Avra Michelson, Overview + Susan H. Veccia, User Evaluation + Joanne Freeman, Beyond the Scholar + Discussion + + Session II. Show and Tell + Jacqueline Hess (Moderator) + Elli Mylonas, Perseus Project + Discussion + Eric M. Calaluca, Patrologia Latina Database + Carl Fleischhauer and Ricky Erway, American Memory + Discussion + Dorothy Twohig, The Papers of George Washington + Discussion + Maria L. Lebron, The Online Journal of Current Clinical Trials + Discussion + Lynne K. Personius, Cornell mathematics books + Discussion + + Session III. Distribution, Networks, and Networking: + Options for Dissemination + Robert G. Zich (Moderator) + Clifford A. Lynch + Discussion + Howard Besser + Discussion + Ronald L. Larsen + Edwin B. Brownrigg + Discussion + + Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats + William L. Hooton (Moderator) + A) Principal Methods for Image Capture of Text: + direct scanning, use of microform + Anne R. Kenney + Pamela Q.J. Andre + Judith A. Zidar + Donald J. Waters + Discussion + B) Special Problems: bound volumes, conservation, + reproducing printed halftones + George Thoma + Carl Fleischhauer + Discussion + C) Image Standards and Implications for Preservation + Jean Baronas + Patricia Battin + Discussion + D) Text Conversion: OCR vs. rekeying, standards of accuracy + and use of imperfect texts, service bureaus + Michael Lesk + Ricky Erway + Judith A. Zidar + Discussion + + Session V. Approaches to Preparing Electronic Texts + Susan Hockey (Moderator) + Stuart Weibel + Discussion + C.M. Sperberg-McQueen + Discussion + Eric M. Calaluca + Discussion + + Session VI. Copyright Issues + Marybeth Peters + + Session VII. Conclusion + Prosser Gifford (Moderator) + General discussion + +Appendix I: Program + +Appendix II: Abstracts + +Appendix III: Directory of Participants + + + *** *** *** ****** *** *** *** + + + Acknowledgements + +I would like to thank Carl Fleischhauer and Prosser Gifford for the +opportunity to learn about areas of human activity unknown to me a scant +ten months ago, and the David and Lucile Packard Foundation for +supporting that opportunity. The help given by others is acknowledged on +a separate page. + + 19 October 1992 + + + *** *** *** ****** *** *** *** + + + INTRODUCTION + +The Workshop on Electronic Texts (1) drew together representatives of +various projects and interest groups to compare ideas, beliefs, +experiences, and, in particular, methods of placing and presenting +historical textual materials in computerized form. Most attendees gained +much in insight and outlook from the event. But the assembly did not +form a new nation, or, to put it another way, the diversity of projects +and interests was too great to draw the representatives into a cohesive, +action-oriented body.(2) + +Everyone attending the Workshop shared an interest in preserving and +providing access to historical texts. But within this broad field the +attendees represented a variety of formal, informal, figurative, and +literal groups, with many individuals belonging to more than one. These +groups may be defined roughly according to the following topics or +activities: + +* Imaging +* Searchable coded texts +* National and international computer networks +* CD-ROM production and dissemination +* Methods and technology for converting older paper materials into +electronic form +* Study of the use of digital materials by scholars and others + +This summary is arranged thematically and does not follow the actual +sequence of presentations. + +NOTES: + (1) In this document, the phrase electronic text is used to mean + any computerized reproduction or version of a document, book, + article, or manuscript (including images), and not merely a machine- + readable or machine-searchable text. + + (2) The Workshop was held at the Library of Congress on 9-10 June + 1992, with funding from the David and Lucile Packard Foundation. + The document that follows represents a summary of the presentations + made at the Workshop and was compiled by James DALY. This + introduction was written by DALY and Carl FLEISCHHAUER. + + +PRESERVATION AND IMAGING + +Preservation, as that term is used by archivists,(3) was most explicitly +discussed in the context of imaging. Anne KENNEY and Lynne PERSONIUS +explained how the concept of a faithful copy and the user-friendliness of +the traditional book have guided their project at Cornell University.(4) +Although interested in computerized dissemination, participants in the +Cornell project are creating digital image sets of older books in the +public domain as a source for a fresh paper facsimile or, in a future +phase, microfilm. The books returned to the library shelves are +high-quality and useful replacements on acid-free paper that should last +a long time. To date, the Cornell project has placed little or no +emphasis on creating searchable texts; one would not be surprised to find +that the project participants view such texts as new editions, and thus +not as faithful reproductions. + +In her talk on preservation, Patricia BATTIN struck an ecumenical and +flexible note as she endorsed the creation and dissemination of a variety +of types of digital copies. Do not be too narrow in defining what counts +as a preservation element, BATTIN counseled; for the present, at least, +digital copies made with preservation in mind cannot be as narrowly +standardized as, say, microfilm copies with the same objective. Setting +standards precipitously can inhibit creativity, but delay can result in +chaos, she advised. + +In part, BATTIN's position reflected the unsettled nature of image-format +standards, and attendees could hear echoes of this unsettledness in the +comments of various speakers. For example, Jean BARONAS reviewed the +status of several formal standards moving through committees of experts; +and Clifford LYNCH encouraged the use of a new guideline for transmitting +document images on Internet. Testimony from participants in the National +Agricultural Library's (NAL) Text Digitization Program and LC's American +Memory project highlighted some of the challenges to the actual creation +or interchange of images, including difficulties in converting +preservation microfilm to digital form. Donald WATERS reported on the +progress of a master plan for a project at Yale University to convert +books on microfilm to digital image sets, Project Open Book (POB). + +The Workshop offered rather less of an imaging practicum than planned, +but "how-to" hints emerge at various points, for example, throughout +KENNEY's presentation and in the discussion of arcana such as +thresholding and dithering offered by George THOMA and FLEISCHHAUER. + +NOTES: + (3) Although there is a sense in which any reproductions of + historical materials preserve the human record, specialists in the + field have developed particular guidelines for the creation of + acceptable preservation copies. + + (4) Titles and affiliations of presenters are given at the + beginning of their respective talks and in the Directory of + Participants (Appendix III). + + +THE MACHINE-READABLE TEXT: MARKUP AND USE + +The sections of the Workshop that dealt with machine-readable text tended +to be more concerned with access and use than with preservation, at least +in the narrow technical sense. Michael SPERBERG-McQUEEN made a forceful +presentation on the Text Encoding Initiative's (TEI) implementation of +the Standard Generalized Markup Language (SGML). His ideas were echoed +by Susan HOCKEY, Elli MYLONAS, and Stuart WEIBEL. While the +presentations made by the TEI advocates contained no practicum, their +discussion focused on the value of the finished product, what the +European Community calls reusability, but what may also be termed +durability. They argued that marking up--that is, coding--a text in a +well-conceived way will permit it to be moved from one computer +environment to another, as well as to be used by various users. Two +kinds of markup were distinguished: 1) procedural markup, which +describes the features of a text (e.g., dots on a page), and 2) +descriptive markup, which describes the structure or elements of a +document (e.g., chapters, paragraphs, and front matter). + +The TEI proponents emphasized the importance of texts to scholarship. +They explained how heavily coded (and thus analyzed and annotated) texts +can underlie research, play a role in scholarly communication, and +facilitate classroom teaching. SPERBERG-McQUEEN reminded listeners that +a written or printed item (e.g., a particular edition of a book) is +merely a representation of the abstraction we call a text. To concern +ourselves with faithfully reproducing a printed instance of the text, +SPERBERG-McQUEEN argued, is to concern ourselves with the representation +of a representation ("images as simulacra for the text"). The TEI proponents' +interest in images tends to focus on corollary materials for use in teaching, +for example, photographs of the Acropolis to accompany a Greek text. + +By the end of the Workshop, SPERBERG-McQUEEN confessed to having been +converted to a limited extent to the view that electronic images +constitute a promising alternative to microfilming; indeed, an +alternative probably superior to microfilming. But he was not convinced +that electronic images constitute a serious attempt to represent text in +electronic form. HOCKEY and MYLONAS also conceded that their experience +at the Pierce Symposium the previous week at Georgetown University and +the present conference at the Library of Congress had compelled them to +reevaluate their perspective on the usefulness of text as images. +Attendees could see that the text and image advocates were in +constructive tension, so to say. + +Three nonTEI presentations described approaches to preparing +machine-readable text that are less rigorous and thus less expensive. In +the case of the Papers of George Washington, Dorothy TWOHIG explained +that the digital version will provide a not-quite-perfect rendering of +the transcribed text--some 135,000 documents, available for research +during the decades while the perfect or print version is completed. +Members of the American Memory team and the staff of NAL's Text +Digitization Program (see below) also outlined a middle ground concerning +searchable texts. In the case of American Memory, contractors produce +texts with about 99-percent accuracy that serve as "browse" or +"reference" versions of written or printed originals. End users who need +faithful copies or perfect renditions must refer to accompanying sets of +digital facsimile images or consult copies of the originals in a nearby +library or archive. American Memory staff argued that the high cost of +producing 100-percent accurate copies would prevent LC from offering +access to large parts of its collections. + + +THE MACHINE-READABLE TEXT: METHODS OF CONVERSION + +Although the Workshop did not include a systematic examination of the +methods for converting texts from paper (or from facsimile images) into +machine-readable form, nevertheless, various speakers touched upon this +matter. For example, WEIBEL reported that OCLC has experimented with a +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000. + +Pamela ANDRE presented an overview of NAL's Text Digitization Program and +Judith ZIDAR discussed the technical details. ZIDAR explained how NAL +purchased hardware and software capable of performing optical character +recognition (OCR) and text conversion and used its own staff to convert +texts. The process, ZIDAR said, required extensive editing and project +staff found themselves considering alternatives, including rekeying +and/or creating abstracts or summaries of texts. NAL reckoned costs at +$7 per page. By way of contrast, Ricky ERWAY explained that American +Memory had decided from the start to contract out conversion to external +service bureaus. The criteria used to select these contractors were cost +and quality of results, as opposed to methods of conversion. ERWAY noted +that historical documents or books often do not lend themselves to OCR. +Bound materials represent a special problem. In her experience, quality +control--inspecting incoming materials, counting errors in samples--posed +the most time-consuming aspect of contracting out conversion. ERWAY +reckoned American Memory's costs at $4 per page, but cautioned that fewer +cost-elements had been included than in NAL's figure. + + +OPTIONS FOR DISSEMINATION + +The topic of dissemination proper emerged at various points during the +Workshop. At the session devoted to national and international computer +networks, LYNCH, Howard BESSER, Ronald LARSEN, and Edwin BROWNRIGG +highlighted the virtues of Internet today and of the network that will +evolve from Internet. Listeners could discern in these narratives a +vision of an information democracy in which millions of citizens freely +find and use what they need. LYNCH noted that a lack of standards +inhibits disseminating multimedia on the network, a topic also discussed +by BESSER. LARSEN addressed the issues of network scalability and +modularity and commented upon the difficulty of anticipating the effects +of growth in orders of magnitude. BROWNRIGG talked about the ability of +packet radio to provide certain links in a network without the need for +wiring. However, the presenters also called attention to the +shortcomings and incongruities of present-day computer networks. For +example: 1) Network use is growing dramatically, but much network +traffic consists of personal communication (E-mail). 2) Large bodies of +information are available, but a user's ability to search across their +entirety is limited. 3) There are significant resources for science and +technology, but few network sources provide content in the humanities. +4) Machine-readable texts are commonplace, but the capability of the +system to deal with images (let alone other media formats) lags behind. +A glimpse of a multimedia future for networks, however, was provided by +Maria LEBRON in her overview of the Online Journal of Current Clinical +Trials (OJCCT), and the process of scholarly publishing on-line. + +The contrasting form of the CD-ROM disk was never systematically +analyzed, but attendees could glean an impression from several of the +show-and-tell presentations. The Perseus and American Memory examples +demonstrated recently published disks, while the descriptions of the +IBYCUS version of the Papers of George Washington and Chadwyck-Healey's +Patrologia Latina Database (PLD) told of disks to come. According to +Eric CALALUCA, PLD's principal focus has been on converting Jacques-Paul +Migne's definitive collection of Latin texts to machine-readable form. +Although everyone could share the network advocates' enthusiasm for an +on-line future, the possibility of rolling up one's sleeves for a session +with a CD-ROM containing both textual materials and a powerful retrieval +engine made the disk seem an appealing vessel indeed. The overall +discussion suggested that the transition from CD-ROM to on-line networked +access may prove far slower and more difficult than has been anticipated. + + +WHO ARE THE USERS AND WHAT DO THEY DO? + +Although concerned with the technicalities of production, the Workshop +never lost sight of the purposes and uses of electronic versions of +textual materials. As noted above, those interested in imaging discussed +the problematical matter of digital preservation, while the TEI proponents +described how machine-readable texts can be used in research. This latter +topic received thorough treatment in the paper read by Avra MICHELSON. +She placed the phenomenon of electronic texts within the context of +broader trends in information technology and scholarly communication. + +Among other things, MICHELSON described on-line conferences that +represent a vigorous and important intellectual forum for certain +disciplines. Internet now carries more than 700 conferences, with about +80 percent of these devoted to topics in the social sciences and the +humanities. Other scholars use on-line networks for "distance learning." +Meanwhile, there has been a tremendous growth in end-user computing; +professors today are less likely than their predecessors to ask the +campus computer center to process their data. Electronic texts are one +key to these sophisticated applications, MICHELSON reported, and more and +more scholars in the humanities now work in an on-line environment. +Toward the end of the Workshop, Michael LESK presented a corollary to +MICHELSON's talk, reporting the results of an experiment that compared +the work of one group of chemistry students using traditional printed +texts and two groups using electronic sources. The experiment +demonstrated that in the event one does not know what to read, one needs +the electronic systems; the electronic systems hold no advantage at the +moment if one knows what to read, but neither do they impose a penalty. + +DALY provided an anecdotal account of the revolutionizing impact of the +new technology on his previous methods of research in the field of classics. +His account, by extrapolation, served to illustrate in part the arguments +made by MICHELSON concerning the positive effects of the sudden and radical +transformation being wrought in the ways scholars work. + +Susan VECCIA and Joanne FREEMAN delineated the use of electronic +materials outside the university. The most interesting aspect of their +use, FREEMAN said, could be seen as a paradox: teachers in elementary +and secondary schools requested access to primary source materials but, +at the same time, found that "primariness" itself made these materials +difficult for their students to use. + + +OTHER TOPICS + +Marybeth PETERS reviewed copyright law in the United States and offered +advice during a lively discussion of this subject. But uncertainty +remains concerning the price of copyright in a digital medium, because a +solution remains to be worked out concerning management and synthesis of +copyrighted and out-of-copyright pieces of a database. + +As moderator of the final session of the Workshop, Prosser GIFFORD directed +discussion to future courses of action and the potential role of LC in +advancing them. Among the recommendations that emerged were the following: + + * Workshop participants should 1) begin to think about working + with image material, but structure and digitize it in such a + way that at a later stage it can be interpreted into text, and + 2) find a common way to build text and images together so that + they can be used jointly at some stage in the future, with + appropriate network support, because that is how users will want + to access these materials. The Library might encourage attempts + to bring together people who are working on texts and images. + + * A network version of American Memory should be developed or + consideration should be given to making the data in it + available to people interested in doing network multimedia. + Given the current dearth of digital data that is appealing and + unencumbered by extremely complex rights problems, developing a + network version of American Memory could do much to help make + network multimedia a reality. + + * Concerning the thorny issue of electronic deposit, LC should + initiate a catalytic process in terms of distributed + responsibility, that is, bring together the distributed + organizations and set up a study group to look at all the + issues related to electronic deposit and see where we as a + nation should move. For example, LC might attempt to persuade + one major library in each state to deal with its state + equivalent publisher, which might produce a cooperative project + that would be equitably distributed around the country, and one + in which LC would be dealing with a minimal number of publishers + and minimal copyright problems. LC must also deal with the + concept of on-line publishing, determining, among other things, + how serials such as OJCCT might be deposited for copyright. + + * Since a number of projects are planning to carry out + preservation by creating digital images that will end up in + on-line or near-line storage at some institution, LC might play + a helpful role, at least in the near term, by accelerating how + to catalog that information into the Research Library Information + Network (RLIN) and then into OCLC, so that it would be accessible. + This would reduce the possibility of multiple institutions digitizing + the same work. + + +CONCLUSION + +The Workshop was valuable because it brought together partisans from +various groups and provided an occasion to compare goals and methods. +The more committed partisans frequently communicate with others in their +groups, but less often across group boundaries. The Workshop was also +valuable to attendees--including those involved with American Memory--who +came less committed to particular approaches or concepts. These +attendees learned a great deal, and plan to select and employ elements of +imaging, text-coding, and networked distribution that suit their +respective projects and purposes. + +Still, reality rears its ugly head: no breakthrough has been achieved. +On the imaging side, one confronts a proliferation of competing +data-interchange standards and a lack of consensus on the role of digital +facsimiles in preservation. In the realm of machine-readable texts, one +encounters a reasonably mature standard but methodological difficulties +and high costs. These latter problems, of course, represent a special +impediment to the desire, as it is sometimes expressed in the popular +press, "to put the [contents of the] Library of Congress on line." In +the words of one participant, there was "no solution to the economic +problems--the projects that are out there are surviving, but it is going +to be a lot of work to transform the information industry, and so far the +investment to do that is not forthcoming" (LESK, per litteras). + + + *** *** *** ****** *** *** *** + + + PROCEEDINGS + + +WELCOME + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GIFFORD * Origin of Workshop in current Librarian's desire to make LC's +collections more widely available * Desiderata arising from the prospect +of greater interconnectedness * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +After welcoming participants on behalf of the Library of Congress, +American Memory (AM), and the National Demonstration Lab, Prosser +GIFFORD, director for scholarly programs, Library of Congress, located +the origin of the Workshop on Electronic Texts in a conversation he had +had considerably more than a year ago with Carl FLEISCHHAUER concerning +some of the issues faced by AM. On the assumption that numerous other +people were asking the same questions, the decision was made to bring +together as many of these people as possible to ask the same questions +together. In a deeper sense, GIFFORD said, the origin of the Workshop +lay in the desire of the current Librarian of Congress, James H. +Billington, to make the collections of the Library, especially those +offering unique or unusual testimony on aspects of the American +experience, available to a much wider circle of users than those few +people who can come to Washington to use them. This meant that the +emphasis of AM, from the outset, has been on archival collections of the +basic material, and on making these collections themselves available, +rather than selected or heavily edited products. + +From AM's emphasis followed the questions with which the Workshop began: +who will use these materials, and in what form will they wish to use +them. But an even larger issue deserving mention, in GIFFORD's view, was +the phenomenal growth in Internet connectivity. He expressed the hope +that the prospect of greater interconnectedness than ever before would +lead to: 1) much more cooperative and mutually supportive endeavors; 2) +development of systems of shared and distributed responsibilities to +avoid duplication and to ensure accuracy and preservation of unique +materials; and 3) agreement on the necessary standards and development of +the appropriate directories and indices to make navigation +straightforward among the varied resources that are, and increasingly +will be, available. In this connection, GIFFORD requested that +participants reflect from the outset upon the sorts of outcomes they +thought the Workshop might have. Did those present constitute a group +with sufficient common interests to propose a next step or next steps, +and if so, what might those be? They would return to these questions the +following afternoon. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * Core of Workshop concerns preparation and production of +materials * Special challenge in conversion of textual materials * +Quality versus quantity * Do the several groups represented share common +interests? * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +emphasized that he would attempt to represent the people who perform some +of the work of converting or preparing materials and that the core of +the Workshop had to do with preparation and production. FLEISCHHAUER +then drew a distinction between the long term, when many things would be +available and connected in the ways that GIFFORD described, and the short +term, in which AM not only has wrestled with the issue of what is the +best course to pursue but also has faced a variety of technical +challenges. + +FLEISCHHAUER remarked AM's endeavors to deal with a wide range of library +formats, such as motion picture collections, sound-recording collections, +and pictorial collections of various sorts, especially collections of +photographs. In the course of these efforts, AM kept coming back to +textual materials--manuscripts or rare printed matter, bound materials, +etc. Text posed the greatest conversion challenge of all. Thus, the +genesis of the Workshop, which reflects the problems faced by AM. These +problems include physical problems. For example, those in the library +and archive business deal with collections made up of fragile and rare +manuscript items, bound materials, especially the notoriously brittle +bound materials of the late nineteenth century. These are precious +cultural artifacts, however, as well as interesting sources of +information, and LC desires to retain and conserve them. AM needs to +handle things without damaging them. Guillotining a book to run it +through a sheet feeder must be avoided at all costs. + +Beyond physical problems, issues pertaining to quality arose. For +example, the desire to provide users with a searchable text is affected +by the question of acceptable level of accuracy. One hundred percent +accuracy is tremendously expensive. On the other hand, the output of +optical character recognition (OCR) can be tremendously inaccurate. +Although AM has attempted to find a middle ground, uncertainty persists +as to whether or not it has discovered the right solution. + +Questions of quality arose concerning images as well. FLEISCHHAUER +contrasted the extremely high level of quality of the digital images in +the Cornell Xerox Project with AM's efforts to provide a browse-quality +or access-quality image, as opposed to an archival or preservation image. +FLEISCHHAUER therefore welcomed the opportunity to compare notes. + +FLEISCHHAUER observed in passing that conversations he had had about +networks have begun to signal that for various forms of media a +determination may be made that there is a browse-quality item, or a +distribution-and-access-quality item that may coexist in some systems +with a higher quality archival item that would be inconvenient to send +through the network because of its size. FLEISCHHAUER referred, of +course, to images more than to searchable text. + +As AM considered those questions, several conceptual issues arose: ought +AM occasionally to reproduce materials entirely through an image set, at +other times, entirely through a text set, and in some cases, a mix? +There probably would be times when the historical authenticity of an +artifact would require that its image be used. An image might be +desirable as a recourse for users if one could not provide 100-percent +accurate text. Again, AM wondered, as a practical matter, if a +distinction could be drawn between rare printed matter that might exist +in multiple collections--that is, in ten or fifteen libraries. In such +cases, the need for perfect reproduction would be less than for unique +items. Implicit in his remarks, FLEISCHHAUER conceded, was the admission +that AM has been tilting strongly towards quantity and drawing back a +little from perfect quality. That is, it seemed to AM that society would +be better served if more things were distributed by LC--even if they were +not quite perfect--than if fewer things, perfectly represented, were +distributed. This was stated as a proposition to be tested, with +responses to be gathered from users. + +In thinking about issues related to reproduction of materials and seeing +other people engaged in parallel activities, AM deemed it useful to +convene a conference. Hence, the Workshop. FLEISCHHAUER thereupon +surveyed the several groups represented: 1) the world of images (image +users and image makers); 2) the world of text and scholarship and, within +this group, those concerned with language--FLEISCHHAUER confessed to finding +delightful irony in the fact that some of the most advanced thinkers on +computerized texts are those dealing with ancient Greek and Roman materials; +3) the network world; and 4) the general world of library science, which +includes people interested in preservation and cataloging. + +FLEISCHHAUER concluded his remarks with special thanks to the David and +Lucile Packard Foundation for its support of the meeting, the American +Memory group, the Office for Scholarly Programs, the National +Demonstration Lab, and the Office of Special Events. He expressed the +hope that David Woodley Packard might be able to attend, noting that +Packard's work and the work of the foundation had sponsored a number of +projects in the text area. + + ****** + +SESSION I. CONTENT IN A NEW FORM: WHO WILL USE IT AND WHAT WILL THEY DO? + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DALY * Acknowledgements * A new Latin authors disk * Effects of the new +technology on previous methods of research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Serving as moderator, James DALY acknowledged the generosity of all the +presenters for giving of their time, counsel, and patience in planning +the Workshop, as well as of members of the American Memory project and +other Library of Congress staff, and the David and Lucile Packard +Foundation and its executive director, Colburn S. Wilbur. + +DALY then recounted his visit in March to the Center for Electronic Texts +in the Humanities (CETH) and the Department of Classics at Rutgers +University, where an old friend, Lowell Edmunds, introduced him to the +department's IBYCUS scholarly personal computer, and, in particular, the +new Latin CD-ROM, containing, among other things, almost all classical +Latin literary texts through A.D. 200. Packard Humanities Institute +(PHI), Los Altos, California, released this disk late in 1991, with a +nominal triennial licensing fee. + +Playing with the disk for an hour or so at Rutgers brought home to DALY +at once the revolutionizing impact of the new technology on his previous +methods of research. Had this disk been available two or three years +earlier, DALY contended, when he was engaged in preparing a commentary on +Book 10 of Virgil's Aeneid for Cambridge University Press, he would not +have required a forty-eight-square-foot table on which to spread the +numerous, most frequently consulted items, including some ten or twelve +concordances to key Latin authors, an almost equal number of lexica to +authors who lacked concordances, and where either lexica or concordances +were lacking, numerous editions of authors antedating and postdating Virgil. + +Nor, when checking each of the average six to seven words contained in +the Virgilian hexameter for its usage elsewhere in Virgil's works or +other Latin authors, would DALY have had to maintain the laborious +mechanical process of flipping through these concordances, lexica, and +editions each time. Nor would he have had to frequent as often the +Milton S. Eisenhower Library at the Johns Hopkins University to consult +the Thesaurus Linguae Latinae. Instead of devoting countless hours, or +the bulk of his research time, to gathering data concerning Virgil's use +of words, DALY--now freed by PHI's Latin authors disk from the +tyrannical, yet in some ways paradoxically happy scholarly drudgery-- +would have been able to devote that same bulk of time to analyzing and +interpreting Virgilian verbal usage. + +Citing Theodore Brunner, Gregory Crane, Elli MYLONAS, and Avra MICHELSON, +DALY argued that this reversal in his style of work, made possible by the +new technology, would perhaps have resulted in better, more productive +research. Indeed, even in the course of his browsing the Latin authors +disk at Rutgers, its powerful search, retrieval, and highlighting +capabilities suggested to him several new avenues of research into +Virgil's use of sound effects. This anecdotal account, DALY maintained, +may serve to illustrate in part the sudden and radical transformation +being wrought in the ways scholars work. + + ****** + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MICHELSON * Elements related to scholarship and technology * Electronic +texts within the context of broader trends within information technology +and scholarly communication * Evaluation of the prospects for the use of +electronic texts * Relationship of electronic texts to processes of +scholarly communication in humanities research * New exchange formats +created by scholars * Projects initiated to increase scholarly access to +converted text * Trend toward making electronic resources available +through research and education networks * Changes taking place in +scholarly communication among humanities scholars * Network-mediated +scholarship transforming traditional scholarly practices * Key +information technology trends affecting the conduct of scholarly +communication over the next decade * The trend toward end-user computing +* The trend toward greater connectivity * Effects of these trends * Key +transformations taking place * Summary of principal arguments * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Avra MICHELSON, Archival Research and Evaluation Staff, National Archives +and Records Administration (NARA), argued that establishing who will use +electronic texts and what they will use them for involves a consideration +of both information technology and scholarship trends. This +consideration includes several elements related to scholarship and +technology: 1) the key trends in information technology that are most +relevant to scholarship; 2) the key trends in the use of currently +available technology by scholars in the nonscientific community; and 3) +the relationship between these two very distinct but interrelated trends. +The investment in understanding this relationship being made by +information providers, technologists, and public policy developers, as +well as by scholars themselves, seems to be pervasive and growing, +MICHELSON contended. She drew on collaborative work with Jeff Rothenberg +on the scholarly use of technology. + +MICHELSON sought to place the phenomenon of electronic texts within the +context of broader trends within information technology and scholarly +communication. She argued that electronic texts are of most use to +researchers to the extent that the researchers' working context (i.e., +their relevant bibliographic sources, collegial feedback, analytic tools, +notes, drafts, etc.), along with their field's primary and secondary +sources, also is accessible in electronic form and can be integrated in +ways that are unique to the on-line environment. + +Evaluation of the prospects for the use of electronic texts includes two +elements: 1) an examination of the ways in which researchers currently +are using electronic texts along with other electronic resources, and 2) +an analysis of key information technology trends that are affecting the +long-term conduct of scholarly communication. MICHELSON limited her +discussion of the use of electronic texts to the practices of humanists +and noted that the scientific community was outside the panel's overview. + +MICHELSON examined the nature of the current relationship of electronic +texts in particular, and electronic resources in general, to what she +maintained were, essentially, five processes of scholarly communication +in humanities research. Researchers 1) identify sources, 2) communicate +with their colleagues, 3) interpret and analyze data, 4) disseminate +their research findings, and 5) prepare curricula to instruct the next +generation of scholars and students. This examination would produce a +clearer understanding of the synergy among these five processes that +fuels the tendency of the use of electronic resources for one process to +stimulate its use for other processes of scholarly communication. + +For the first process of scholarly communication, the identification of +sources, MICHELSON remarked the opportunity scholars now enjoy to +supplement traditional word-of-mouth searches for sources among their +colleagues with new forms of electronic searching. So, for example, +instead of having to visit the library, researchers are able to explore +descriptions of holdings in their offices. Furthermore, if their own +institutions' holdings prove insufficient, scholars can access more than +200 major American library catalogues over Internet, including the +universities of California, Michigan, Pennsylvania, and Wisconsin. +Direct access to the bibliographic databases offers intellectual +empowerment to scholars by presenting a comprehensive means of browsing +through libraries from their homes and offices at their convenience. + +The second process of communication involves communication among +scholars. Beyond the most common methods of communication, scholars are +using E-mail and a variety of new electronic communications formats +derived from it for further academic interchange. E-mail exchanges are +growing at an astonishing rate, reportedly 15 percent a month. They +currently constitute approximately half the traffic on research and +education networks. Moreover, the global spread of E-mail has been so +rapid that it is now possible for American scholars to use it to +communicate with colleagues in close to 140 other countries. + +Other new exchange formats created by scholars and operating on Internet +include more than 700 conferences, with about 80 percent of these devoted +to topics in the social sciences and humanities. The rate of growth of +these scholarly electronic conferences also is astonishing. From l990 to +l991, 200 new conferences were identified on Internet. From October 1991 +to June 1992, an additional 150 conferences in the social sciences and +humanities were added to this directory of listings. Scholars have +established conferences in virtually every field, within every different +discipline. For example, there are currently close to 600 active social +science and humanities conferences on topics such as art and +architecture, ethnomusicology, folklore, Japanese culture, medical +education, and gifted and talented education. The appeal to scholars of +communicating through these conferences is that, unlike any other medium, +electronic conferences today provide a forum for global communication +with peers at the front end of the research process. + +Interpretation and analysis of sources constitutes the third process of +scholarly communication that MICHELSON discussed in terms of texts and +textual resources. The methods used to analyze sources fall somewhere on +a continuum from quantitative analysis to qualitative analysis. +Typically, evidence is culled and evaluated using methods drawn from both +ends of this continuum. At one end, quantitative analysis involves the +use of mathematical processes such as a count of frequencies and +distributions of occurrences or, on a higher level, regression analysis. +At the other end of the continuum, qualitative analysis typically +involves nonmathematical processes oriented toward language +interpretation or the building of theory. Aspects of this work involve +the processing--either manual or computational--of large and sometimes +massive amounts of textual sources, although the use of nontextual +sources as evidence, such as photographs, sound recordings, film footage, +and artifacts, is significant as well. + +Scholars have discovered that many of the methods of interpretation and +analysis that are related to both quantitative and qualitative methods +are processes that can be performed by computers. For example, computers +can count. They can count brush strokes used in a Rembrandt painting or +perform regression analysis for understanding cause and effect. By means +of advanced technologies, computers can recognize patterns, analyze text, +and model concepts. Furthermore, computers can complete these processes +faster with more sources and with greater precision than scholars who +must rely on manual interpretation of data. But if scholars are to use +computers for these processes, source materials must be in a form +amenable to computer-assisted analysis. For this reason many scholars, +once they have identified the sources that are key to their research, are +converting them to machine-readable form. Thus, a representative example +of the numerous textual conversion projects organized by scholars around +the world in recent years to support computational text analysis is the +TLG, the Thesaurus Linguae Graecae. This project is devoted to +converting the extant ancient texts of classical Greece. (Editor's note: +according to the TLG Newsletter of May l992, TLG was in use in thirty-two +different countries. This figure updates MICHELSON's previous count by one.) + +The scholars performing these conversions have been asked to recognize +that the electronic sources they are converting for one use possess value +for other research purposes as well. As a result, during the past few +years, humanities scholars have initiated a number of projects to +increase scholarly access to converted text. So, for example, the Text +Encoding Initiative (TEI), about which more is said later in the program, +was established as an effort by scholars to determine standard elements +and methods for encoding machine-readable text for electronic exchange. +In a second effort to facilitate the sharing of converted text, scholars +have created a new institution, the Center for Electronic Texts in the +Humanities (CETH). The center estimates that there are 8,000 series of +source texts in the humanities that have been converted to +machine-readable form worldwide. CETH is undertaking an international +search for converted text in the humanities, compiling it into an +electronic library, and preparing bibliographic descriptions of the +sources for the Research Libraries Information Network's (RLIN) +machine-readable data file. The library profession has begun to initiate +large conversion projects as well, such as American Memory. + +While scholars have been making converted text available to one another, +typically on disk or on CD-ROM, the clear trend is toward making these +resources available through research and education networks. Thus, the +American and French Research on the Treasury of the French Language +(ARTFL) and the Dante Project are already available on Internet. +MICHELSON summarized this section on interpretation and analysis by +noting that: 1) increasing numbers of humanities scholars in the library +community are recognizing the importance to the advancement of +scholarship of retrospective conversion of source materials in the arts +and humanities; and 2) there is a growing realization that making the +sources available on research and education networks maximizes their +usefulness for the analysis performed by humanities scholars. + +The fourth process of scholarly communication is dissemination of +research findings, that is, publication. Scholars are using existing +research and education networks to engineer a new type of publication: +scholarly-controlled journals that are electronically produced and +disseminated. Although such journals are still emerging as a +communication format, their number has grown, from approximately twelve +to thirty-six during the past year (July 1991 to June 1992). Most of +these electronic scholarly journals are devoted to topics in the +humanities. As with network conferences, scholarly enthusiasm for these +electronic journals stems from the medium's unique ability to advance +scholarship in a way that no other medium can do by supporting global +feedback and interchange, practically in real time, early in the research +process. Beyond scholarly journals, MICHELSON remarked the delivery of +commercial full-text products, such as articles in professional journals, +newsletters, magazines, wire services, and reference sources. These are +being delivered via on-line local library catalogues, especially through +CD-ROMs. Furthermore, according to MICHELSON, there is general optimism +that the copyright and fees issues impeding the delivery of full text on +existing research and education networks soon will be resolved. + +The final process of scholarly communication is curriculum development +and instruction, and this involves the use of computer information +technologies in two areas. The first is the development of +computer-oriented instructional tools, which includes simulations, +multimedia applications, and computer tools that are used to assist in +the analysis of sources in the classroom, etc. The Perseus Project, a +database that provides a multimedia curriculum on classical Greek +civilization, is a good example of the way in which entire curricula are +being recast using information technologies. It is anticipated that the +current difficulty in exchanging electronically computer-based +instructional software, which in turn makes it difficult for one scholar +to build upon the work of others, will be resolved before too long. +Stand-alone curricular applications that involve electronic text will be +shareable through networks, reinforcing their significance as intellectual +products as well as instructional tools. + +The second aspect of electronic learning involves the use of research and +education networks for distance education programs. Such programs +interactively link teachers with students in geographically scattered +locations and rely on the availability of electronic instructional +resources. Distance education programs are gaining wide appeal among +state departments of education because of their demonstrated capacity to +bring advanced specialized course work and an array of experts to many +classrooms. A recent report found that at least 32 states operated at +least one statewide network for education in 1991, with networks under +development in many of the remaining states. + +MICHELSON summarized this section by noting two striking changes taking +place in scholarly communication among humanities scholars. First is the +extent to which electronic text in particular, and electronic resources +in general, are being infused into each of the five processes described +above. As mentioned earlier, there is a certain synergy at work here. +The use of electronic resources for one process tends to stimulate its +use for other processes, because the chief course of movement is toward a +comprehensive on-line working context for humanities scholars that +includes on-line availability of key bibliographies, scholarly feedback, +sources, analytical tools, and publications. MICHELSON noted further +that the movement toward a comprehensive on-line working context for +humanities scholars is not new. In fact, it has been underway for more +than forty years in the humanities, since Father Roberto Busa began +developing an electronic concordance of the works of Saint Thomas Aquinas +in 1949. What we are witnessing today, MICHELSON contended, is not the +beginning of this on-line transition but, for at least some humanities +scholars, the turning point in the transition from a print to an +electronic working context. Coinciding with the on-line transition, the +second striking change is the extent to which research and education +networks are becoming the new medium of scholarly communication. The +existing Internet and the pending National Education and Research Network +(NREN) represent the new meeting ground where scholars are going for +bibliographic information, scholarly dialogue and feedback, the most +current publications in their field, and high-level educational +offerings. Traditional scholarly practices are undergoing tremendous +transformations as a result of the emergence and growing prominence of +what is called network-mediated scholarship. + +MICHELSON next turned to the second element of the framework she proposed +at the outset of her talk for evaluating the prospects for electronic +text, namely the key information technology trends affecting the conduct +of scholarly communication over the next decade: 1) end-user computing +and 2) connectivity. + +End-user computing means that the person touching the keyboard, or +performing computations, is the same as the person who initiates or +consumes the computation. The emergence of personal computers, along +with a host of other forces, such as ubiquitous computing, advances in +interface design, and the on-line transition, is prompting the consumers +of computation to do their own computing, and is thus rendering obsolete +the traditional distinction between end users and ultimate users. + +The trend toward end-user computing is significant to consideration of +the prospects for electronic texts because it means that researchers are +becoming more adept at doing their own computations and, thus, more +competent in the use of electronic media. By avoiding programmer +intermediaries, computation is becoming central to the researcher's +thought process. This direct involvement in computing is changing the +researcher's perspective on the nature of research itself, that is, the +kinds of questions that can be posed, the analytical methodologies that +can be used, the types and amount of sources that are appropriate for +analyses, and the form in which findings are presented. The trend toward +end-user computing means that, increasingly, electronic media and +computation are being infused into all processes of humanities +scholarship, inspiring remarkable transformations in scholarly +communication. + +The trend toward greater connectivity suggests that researchers are using +computation increasingly in network environments. Connectivity is +important to scholarship because it erases the distance that separates +students from teachers and scholars from their colleagues, while allowing +users to access remote databases, share information in many different +media, connect to their working context wherever they are, and +collaborate in all phases of research. + +The combination of the trend toward end-user computing and the trend +toward connectivity suggests that the scholarly use of electronic +resources, already evident among some researchers, will soon become an +established feature of scholarship. The effects of these trends, along +with ongoing changes in scholarly practices, point to a future in which +humanities researchers will use computation and electronic communication +to help them formulate ideas, access sources, perform research, +collaborate with colleagues, seek peer review, publish and disseminate +results, and engage in many other professional and educational activities. + +In summary, MICHELSON emphasized four points: 1) A portion of humanities +scholars already consider electronic texts the preferred format for +analysis and dissemination. 2) Scholars are using these electronic +texts, in conjunction with other electronic resources, in all the +processes of scholarly communication. 3) The humanities scholars' +working context is in the process of changing from print technology to +electronic technology, in many ways mirroring transformations that have +occurred or are occurring within the scientific community. 4) These +changes are occurring in conjunction with the development of a new +communication medium: research and education networks that are +characterized by their capacity to advance scholarship in a wholly unique +way. + +MICHELSON also reiterated her three principal arguments: l) Electronic +texts are best understood in terms of the relationship to other +electronic resources and the growing prominence of network-mediated +scholarship. 2) The prospects for electronic texts lie in their capacity +to be integrated into the on-line network of electronic resources that +comprise the new working context for scholars. 3) Retrospective conversion +of portions of the scholarly record should be a key strategy as information +providers respond to changes in scholarly communication practices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +VECCIA * AM's evaluation project and public users of electronic resources +* AM and its design * Site selection and evaluating the Macintosh +implementation of AM * Characteristics of the six public libraries +selected * Characteristics of AM's users in these libraries * Principal +ways AM is being used * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan VECCIA, team leader, and Joanne FREEMAN, associate coordinator, +American Memory, Library of Congress, gave a joint presentation. First, +by way of introduction, VECCIA explained her and FREEMAN's roles in +American Memory (AM). Serving principally as an observer, VECCIA has +assisted with the evaluation project of AM, placing AM collections in a +variety of different sites around the country and helping to organize and +implement that project. FREEMAN has been an associate coordinator of AM +and has been involved principally with the interpretative materials, +preparing some of the electronic exhibits and printed historical +information that accompanies AM and that is requested by users. VECCIA +and FREEMAN shared anecdotal observations concerning AM with public users +of electronic resources. Notwithstanding a fairly structured evaluation +in progress, both VECCIA and FREEMAN chose not to report on specifics in +terms of numbers, etc., because they felt it was too early in the +evaluation project to do so. + +AM is an electronic archive of primary source materials from the Library +of Congress, selected collections representing a variety of formats-- +photographs, graphic arts, recorded sound, motion pictures, broadsides, +and soon, pamphlets and books. In terms of the design of this system, +the interpretative exhibits have been kept separate from the primary +resources, with good reason. Accompanying this collection are printed +documentation and user guides, as well as guides that FREEMAN prepared for +teachers so that they may begin using the content of the system at once. + +VECCIA described the evaluation project before talking about the public +users of AM, limiting her remarks to public libraries, because FREEMAN +would talk more specifically about schools from kindergarten to twelfth +grade (K-12). Having started in spring 1991, the evaluation currently +involves testing of the Macintosh implementation of AM. Since the +primary goal of this evaluation is to determine the most appropriate +audience or audiences for AM, very different sites were selected. This +makes evaluation difficult because of the varying degrees of technology +literacy among the sites. AM is situated in forty-four locations, of +which six are public libraries and sixteen are schools. Represented +among the schools are elementary, junior high, and high schools. +District offices also are involved in the evaluation, which will +conclude in summer 1993. + +VECCIA focused the remainder of her talk on the six public libraries, one +of which doubles as a state library. They represent a range of +geographic areas and a range of demographic characteristics. For +example, three are located in urban settings, two in rural settings, and +one in a suburban setting. A range of technical expertise is to be found +among these facilities as well. For example, one is an "Apple library of +the future," while two others are rural one-room libraries--in one, AM +sits at the front desk next to a tractor manual. + +All public libraries have been extremely enthusiastic, supportive, and +appreciative of the work that AM has been doing. VECCIA characterized +various users: Most users in public libraries describe themselves as +general readers; of the students who use AM in the public libraries, +those in fourth grade and above seem most interested. Public libraries +in rural sites tend to attract retired people, who have been highly +receptive to AM. Users tend to fall into two additional categories: +people interested in the content and historical connotations of these +primary resources, and those fascinated by the technology. The format +receiving the most comments has been motion pictures. The adult users in +public libraries are more comfortable with IBM computers, whereas young +people seem comfortable with either IBM or Macintosh, although most of +them seem to come from a Macintosh background. This same tendency is +found in the schools. + +What kinds of things do users do with AM? In a public library there are +two main goals or ways that AM is being used: as an individual learning +tool, and as a leisure activity. Adult learning was one area that VECCIA +would highlight as a possible application for a tool such as AM. She +described a patron of a rural public library who comes in every day on +his lunch hour and literally reads AM, methodically going through the +collection image by image. At the end of his hour he makes an electronic +bookmark, puts it in his pocket, and returns to work. The next day he +comes in and resumes where he left off. Interestingly, this man had +never been in the library before he used AM. In another small, rural +library, the coordinator reports that AM is a popular activity for some +of the older, retired people in the community, who ordinarily would not +use "those things,"--computers. Another example of adult learning in +public libraries is book groups, one of which, in particular, is using AM +as part of its reading on industrialization, integration, and urbanization +in the early 1900s. + +One library reports that a family is using AM to help educate their +children. In another instance, individuals from a local museum came in +to use AM to prepare an exhibit on toys of the past. These two examples +emphasize the mission of the public library as a cultural institution, +reaching out to people who do not have the same resources available to +those who live in a metropolitan area or have access to a major library. +One rural library reports that junior high school students in large +numbers came in one afternoon to use AM for entertainment. A number of +public libraries reported great interest among postcard collectors in the +Detroit collection, which was essentially a collection of images used on +postcards around the turn of the century. Train buffs are similarly +interested because that was a time of great interest in railroading. +People, it was found, relate to things that they know of firsthand. For +example, in both rural public libraries where AM was made available, +observers reported that the older people with personal remembrances of +the turn of the century were gravitating to the Detroit collection. +These examples served to underscore MICHELSON's observation re the +integration of electronic tools and ideas--that people learn best when +the material relates to something they know. + +VECCIA made the final point that in many cases AM serves as a +public-relations tool for the public libraries that are testing it. In +one case, AM is being used as a vehicle to secure additional funding for +the library. In another case, AM has served as an inspiration to the +staff of a major local public library in the South to think about ways to +make its own collection of photographs more accessible to the public. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FREEMAN * AM and archival electronic resources in a school environment * +Questions concerning context * Questions concerning the electronic format +itself * Computer anxiety * Access and availability of the system * +Hardware * Strengths gained through the use of archival resources in +schools * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Reiterating an observation made by VECCIA, that AM is an archival +resource made up of primary materials with very little interpretation, +FREEMAN stated that the project has attempted to bridge the gap between +these bare primary materials and a school environment, and in that cause +has created guided introductions to AM collections. Loud demand from the +educational community, chiefly from teachers working with the upper +grades of elementary school through high school, greeted the announcement +that AM would be tested around the country. + +FREEMAN reported not only on what was learned about AM in a school +environment, but also on several universal questions that were raised +concerning archival electronic resources in schools. She discussed +several strengths of this type of material in a school environment as +opposed to a highly structured resource that offers a limited number of +paths to follow. + +FREEMAN first raised several questions about using AM in a school +environment. There is often some difficulty in developing a sense of +what the system contains. Many students sit down at a computer resource +and assume that, because AM comes from the Library of Congress, all of +American history is now at their fingertips. As a result of that sort of +mistaken judgment, some students are known to conclude that AM contains +nothing of use to them when they look for one or two things and do not +find them. It is difficult to discover that middle ground where one has +a sense of what the system contains. Some students grope toward the idea +of an archive, a new idea to them, since they have not previously +experienced what it means to have access to a vast body of somewhat +random information. + +Other questions raised by FREEMAN concerned the electronic format itself. +For instance, in a school environment it is often difficult both for +teachers and students to gain a sense of what it is they are viewing. +They understand that it is a visual image, but they do not necessarily +know that it is a postcard from the turn of the century, a panoramic +photograph, or even machine-readable text of an eighteenth-century +broadside, a twentieth-century printed book, or a nineteenth-century +diary. That distinction is often difficult for people in a school +environment to grasp. Because of that, it occasionally becomes difficult +to draw conclusions from what one is viewing. + +FREEMAN also noted the obvious fear of the computer, which constitutes a +difficulty in using an electronic resource. Though students in general +did not suffer from this anxiety, several older students feared that they +were computer-illiterate, an assumption that became self-fulfilling when +they searched for something but failed to find it. FREEMAN said she +believed that some teachers also fear computer resources, because they +believe they lack complete control. FREEMAN related the example of +teachers shooing away students because it was not their time to use the +system. This was a case in which the situation had to be extremely +structured so that the teachers would not feel that they had lost their +grasp on what the system contained. + +A final question raised by FREEMAN concerned access and availability of +the system. She noted the occasional existence of a gap in communication +between school librarians and teachers. Often AM sits in a school +library and the librarian is the person responsible for monitoring the +system. Teachers do not always take into their world new library +resources about which the librarian is excited. Indeed, at the sites +where AM had been used most effectively within a library, the librarian +was required to go to specific teachers and instruct them in its use. As +a result, several AM sites will have in-service sessions over a summer, +in the hope that perhaps, with a more individualized link, teachers will +be more likely to use the resource. + +A related issue in the school context concerned the number of +workstations available at any one location. Centralization of equipment +at the district level, with teachers invited to download things and walk +away with them, proved unsuccessful because the hours these offices were +open were also school hours. + +Another issue was hardware. As VECCIA observed, a range of sites exists, +some technologically advanced and others essentially acquiring their +first computer for the primary purpose of using it in conjunction with +AM's testing. Users at technologically sophisticated sites want even +more sophisticated hardware, so that they can perform even more +sophisticated tasks with the materials in AM. But once they acquire a +newer piece of hardware, they must learn how to use that also; at an +unsophisticated site it takes an extremely long time simply to become +accustomed to the computer, not to mention the program offered with the +computer. All of these small issues raise one large question, namely, +are systems like AM truly rewarding in a school environment, or do they +simply act as innovative toys that do little more than spark interest? + +FREEMAN contended that the evaluation project has revealed several strengths +that were gained through the use of archival resources in schools, including: + + * Psychic rewards from using AM as a vast, rich database, with + teachers assigning various projects to students--oral presentations, + written reports, a documentary, a turn-of-the-century newspaper-- + projects that start with the materials in AM but are completed using + other resources; AM thus is used as a research tool in conjunction + with other electronic resources, as well as with books and items in + the library where the system is set up. + + * Students are acquiring computer literacy in a humanities context. + + * This sort of system is overcoming the isolation between disciplines + that often exists in schools. For example, many English teachers are + requiring their students to write papers on historical topics + represented in AM. Numerous teachers have reported that their + students are learning critical thinking skills using the system. + + * On a broader level, AM is introducing primary materials, not only + to students but also to teachers, in an environment where often + simply none exist--an exciting thing for the students because it + helps them learn to conduct research, to interpret, and to draw + their own conclusions. In learning to conduct research and what it + means, students are motivated to seek knowledge. That relates to + another positive outcome--a high level of personal involvement of + students with the materials in this system and greater motivation to + conduct their own research and draw their own conclusions. + + * Perhaps the most ironic strength of these kinds of archival + electronic resources is that many of the teachers AM interviewed + were desperate, it is no exaggeration to say, not only for primary + materials but for unstructured primary materials. These would, they + thought, foster personally motivated research, exploration, and + excitement in their students. Indeed, these materials have done + just that. Ironically, however, this lack of structure produces + some of the confusion to which the newness of these kinds of + resources may also contribute. The key to effective use of archival + products in a school environment is a clear, effective introduction + to the system and to what it contains. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Nothing known, quantitatively, about the number of +humanities scholars who must see the original versus those who would +settle for an edited transcript, or about the ways in which humanities +scholars are using information technology * Firm conclusions concerning +the manner and extent of the use of supporting materials in print +provided by AM to await completion of evaluative study * A listener's +reflections on additional applications of electronic texts * Role of +electronic resources in teaching elementary research skills to students * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed the presentations by MICHELSON, +VECCIA, and FREEMAN, additional points emerged. + +LESK asked if MICHELSON could give any quantitative estimate of the +number of humanities scholars who must see or want to see the original, +or the best possible version of the material, versus those who typically +would settle for an edited transcript. While unable to provide a figure, +she offered her impressions as an archivist who has done some reference +work and has discussed this issue with other archivists who perform +reference, that those who use archives and those who use primary sources +for what would be considered very high-level scholarly research, as +opposed to, say, undergraduate papers, were few in number, especially +given the public interest in using primary sources to conduct +genealogical or avocational research and the kind of professional +research done by people in private industry or the federal government. +More important in MICHELSON's view was that, quantitatively, nothing is +known about the ways in which, for example, humanities scholars are using +information technology. No studies exist to offer guidance in creating +strategies. The most recent study was conducted in 1985 by the American +Council of Learned Societies (ACLS), and what it showed was that 50 +percent of humanities scholars at that time were using computers. That +constitutes the extent of our knowledge. + +Concerning AM's strategy for orienting people toward the scope of +electronic resources, FREEMAN could offer no hard conclusions at this +point, because she and her colleagues were still waiting to see, +particularly in the schools, what has been made of their efforts. Within +the system, however, AM has provided what are called electronic exhibits- +-such as introductions to time periods and materials--and these are +intended to offer a student user a sense of what a broadside is and what +it might tell her or him. But FREEMAN conceded that the project staff +would have to talk with students next year, after teachers have had a +summer to use the materials, and attempt to discover what the students +were learning from the materials. In addition, FREEMAN described +supporting materials in print provided by AM at the request of local +teachers during a meeting held at LC. These included time lines, +bibliographies, and other materials that could be reproduced on a +photocopier in a classroom. Teachers could walk away with and use these, +and in this way gain a better understanding of the contents. But again, +reaching firm conclusions concerning the manner and extent of their use +would have to wait until next year. + +As to the changes she saw occurring at the National Archives and Records +Administration (NARA) as a result of the increasing emphasis on +technology in scholarly research, MICHELSON stated that NARA at this +point was absorbing the report by her and Jeff Rothenberg addressing +strategies for the archival profession in general, although not for the +National Archives specifically. NARA is just beginning to establish its +role and what it can do. In terms of changes and initiatives that NARA +can take, no clear response could be given at this time. + +GREENFIELD remarked two trends mentioned in the session. Reflecting on +DALY's opening comments on how he could have used a Latin collection of +text in an electronic form, he said that at first he thought most scholars +would be unwilling to do that. But as he thought of that in terms of the +original meaning of research--that is, having already mastered these texts, +researching them for critical and comparative purposes--for the first time, +the electronic format made a lot of sense. GREENFIELD could envision +growing numbers of scholars learning the new technologies for that very +aspect of their scholarship and for convenience's sake. + +Listening to VECCIA and FREEMAN, GREENFIELD thought of an additional +application of electronic texts. He realized that AM could be used as a +guide to lead someone to original sources. Students cannot be expected +to have mastered these sources, things they have never known about +before. Thus, AM is leading them, in theory, to a vast body of +information and giving them a superficial overview of it, enabling them +to select parts of it. GREENFIELD asked if any evidence exists that this +resource will indeed teach the new user, the K-12 students, how to do +research. Scholars already know how to do research and are applying +these new tools. But he wondered why students would go beyond picking +out things that were most exciting to them. + +FREEMAN conceded the correctness of GREENFIELD's observation as applied +to a school environment. The risk is that a student would sit down at a +system, play with it, find some things of interest, and then walk away. +But in the relatively controlled situation of a school library, much will +depend on the instructions a teacher or a librarian gives a student. She +viewed the situation not as one of fine-tuning research skills but of +involving students at a personal level in understanding and researching +things. Given the guidance one can receive at school, it then becomes +possible to teach elementary research skills to students, which in fact +one particular librarian said she was teaching her fifth graders. +FREEMAN concluded that introducing the idea of following one's own path +of inquiry, which is essentially what research entails, involves more +than teaching specific skills. To these comments VECCIA added the +observation that the individual teacher and the use of a creative +resource, rather than AM itself, seemed to make the key difference. +Some schools and some teachers are making excellent use of the nature +of critical thinking and teaching skills, she said. + +Concurring with these remarks, DALY closed the session with the thought that +the more that producers produced for teachers and for scholars to use with +their students, the more successful their electronic products would prove. + + ****** + +SESSION II. SHOW AND TELL + +Jacqueline HESS, director, National Demonstration Laboratory, served as +moderator of the "show-and-tell" session. She noted that a +question-and-answer period would follow each presentation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MYLONAS * Overview and content of Perseus * Perseus' primary materials +exist in a system-independent, archival form * A concession * Textual +aspects of Perseus * Tools to use with the Greek text * Prepared indices +and full-text searches in Perseus * English-Greek word search leads to +close study of words and concepts * Navigating Perseus by tracing down +indices * Using the iconography to perform research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Elli MYLONAS, managing editor, Perseus Project, Harvard University, first +gave an overview of Perseus, a large, collaborative effort based at +Harvard University but with contributors and collaborators located at +numerous universities and colleges in the United States (e.g., Bowdoin, +Maryland, Pomona, Chicago, Virginia). Funded primarily by the +Annenberg/CPB Project, with additional funding from Apple, Harvard, and +the Packard Humanities Institute, among others, Perseus is a multimedia, +hypertextual database for teaching and research on classical Greek +civilization, which was released in February 1992 in version 1.0 and +distributed by Yale University Press. + +Consisting entirely of primary materials, Perseus includes ancient Greek +texts and translations of those texts; catalog entries--that is, museum +catalog entries, not library catalog entries--on vases, sites, coins, +sculpture, and archaeological objects; maps; and a dictionary, among +other sources. The number of objects and the objects for which catalog +entries exist are accompanied by thousands of color images, which +constitute a major feature of the database. Perseus contains +approximately 30 megabytes of text, an amount that will double in +subsequent versions. In addition to these primary materials, the Perseus +Project has been building tools for using them, making access and +navigation easier, the goal being to build part of the electronic +environment discussed earlier in the morning in which students or +scholars can work with their sources. + +The demonstration of Perseus will show only a fraction of the real work +that has gone into it, because the project had to face the dilemma of +what to enter when putting something into machine-readable form: should +one aim for very high quality or make concessions in order to get the +material in? Since Perseus decided to opt for very high quality, all of +its primary materials exist in a system-independent--insofar as it is +possible to be system-independent--archival form. Deciding what that +archival form would be and attaining it required much work and thought. +For example, all the texts are marked up in SGML, which will be made +compatible with the guidelines of the Text Encoding Initiative (TEI) when +they are issued. + +Drawings are postscript files, not meeting international standards, but +at least designed to go across platforms. Images, or rather the real +archival forms, consist of the best available slides, which are being +digitized. Much of the catalog material exists in database form--a form +that the average user could use, manipulate, and display on a personal +computer, but only at great cost. Thus, this is where the concession +comes in: All of this rich, well-marked-up information is stripped of +much of its content; the images are converted into bit-maps and the text +into small formatted chunks. All this information can then be imported +into HyperCard and run on a mid-range Macintosh, which is what Perseus +users have. This fact has made it possible for Perseus to attain wide +use fairly rapidly. Without those archival forms the HyperCard version +being demonstrated could not be made easily, and the project could not +have the potential to move to other forms and machines and software as +they appear, none of which information is in Perseus on the CD. + +Of the numerous multimedia aspects of Perseus, MYLONAS focused on the +textual. Part of what makes Perseus such a pleasure to use, MYLONAS +said, is this effort at seamless integration and the ability to move +around both visual and textual material. Perseus also made the decision +not to attempt to interpret its material any more than one interprets by +selecting. But, MYLONAS emphasized, Perseus is not courseware: No +syllabus exists. There is no effort to define how one teaches a topic +using Perseus, although the project may eventually collect papers by +people who have used it to teach. Rather, Perseus aims to provide +primary material in a kind of electronic library, an electronic sandbox, +so to say, in which students and scholars who are working on this +material can explore by themselves. With that, MYLONAS demonstrated +Perseus, beginning with the Perseus gateway, the first thing one sees +upon opening Perseus--an effort in part to solve the contextualizing +problem--which tells the user what the system contains. + +MYLONAS demonstrated only a very small portion, beginning with primary +texts and running off the CD-ROM. Having selected Aeschylus' Prometheus +Bound, which was viewable in Greek and English pretty much in the same +segments together, MYLONAS demonstrated tools to use with the Greek text, +something not possible with a book: looking up the dictionary entry form +of an unfamiliar word in Greek after subjecting it to Perseus' +morphological analysis for all the texts. After finding out about a +word, a user may then decide to see if it is used anywhere else in Greek. +Because vast amounts of indexing support all of the primary material, one +can find out where else all forms of a particular Greek word appear-- +often not a trivial matter because Greek is highly inflected. Further, +since the story of Prometheus has to do with the origins of sacrifice, a +user may wish to study and explore sacrifice in Greek literature; by +typing sacrifice into a small window, a user goes to the English-Greek +word list--something one cannot do without the computer (Perseus has +indexed the definitions of its dictionary)--the string sacrifice appears +in the definitions of these sixty-five words. One may then find out +where any of those words is used in the work(s) of a particular author. +The English definitions are not lemmatized. + +All of the indices driving this kind of usage were originally devised for +speed, MYLONAS observed; in other words, all that kind of information-- +all forms of all words, where they exist, the dictionary form they belong +to--were collected into databases, which will expedite searching. Then +it was discovered that one can do things searching in these databases +that could not be done searching in the full texts. Thus, although there +are full-text searches in Perseus, much of the work is done behind the +scenes, using prepared indices. Re the indexing that is done behind the +scenes, MYLONAS pointed out that without the SGML forms of the text, it +could not be done effectively. Much of this indexing is based on the +structures that are made explicit by the SGML tagging. + +It was found that one of the things many of Perseus' non-Greek-reading +users do is start from the dictionary and then move into the close study +of words and concepts via this kind of English-Greek word search, by which +means they might select a concept. This exercise has been assigned to +students in core courses at Harvard--to study a concept by looking for the +English word in the dictionary, finding the Greek words, and then finding +the words in the Greek but, of course, reading across in the English. +That tells them a great deal about what a translation means as well. + +Should one also wish to see images that have to do with sacrifice, that +person would go to the object key word search, which allows one to +perform a similar kind of index retrieval on the database of +archaeological objects. Without words, pictures are useless; Perseus has +not reached the point where it can do much with images that are not +cataloged. Thus, although it is possible in Perseus with text and images +to navigate by knowing where one wants to end up--for example, a +red-figure vase from the Boston Museum of Fine Arts--one can perform this +kind of navigation very easily by tracing down indices. MYLONAS +illustrated several generic scenes of sacrifice on vases. The features +demonstrated derived from Perseus 1.0; version 2.0 will implement even +better means of retrieval. + +MYLONAS closed by looking at one of the pictures and noting again that +one can do a great deal of research using the iconography as well as the +texts. For instance, students in a core course at Harvard this year were +highly interested in Greek concepts of foreigners and representations of +non-Greeks. So they performed a great deal of research, both with texts +(e.g., Herodotus) and with iconography on vases and coins, on how the +Greeks portrayed non-Greeks. At the same time, art historians who study +iconography were also interested, and were able to use this material. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Indexing and searchability of all English words in Perseus * +Several features of Perseus 1.0 * Several levels of customization +possible * Perseus used for general education * Perseus' effects on +education * Contextual information in Perseus * Main challenge and +emphasis of Perseus * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Several points emerged in the discussion that followed MYLONAS's presentation. + +Although MYLONAS had not demonstrated Perseus' ability to cross-search +documents, she confirmed that all English words in Perseus are indexed +and can be searched. So, for example, sacrifice could have been searched +in all texts, the historical essay, and all the catalogue entries with +their descriptions--in short, in all of Perseus. + +Boolean logic is not in Perseus 1.0 but will be added to the next +version, although an effort is being made not to restrict Perseus to a +database in which one just performs searching, Boolean or otherwise. It +is possible to move laterally through the documents by selecting a word +one is interested in and selecting an area of information one is +interested in and trying to look that word up in that area. + +Since Perseus was developed in HyperCard, several levels of customization +are possible. Simple authoring tools exist that allow one to create +annotated paths through the information, which are useful for note-taking +and for guided tours for teaching purposes and for expository writing. +With a little more ingenuity it is possible to begin to add or substitute +material in Perseus. + +Perseus has not been used so much for classics education as for general +education, where it seemed to have an impact on the students in the core +course at Harvard (a general required course that students must take in +certain areas). Students were able to use primary material much more. + +The Perseus Project has an evaluation team at the University of Maryland +that has been documenting Perseus' effects on education. Perseus is very +popular, and anecdotal evidence indicates that it is having an effect at +places other than Harvard, for example, test sites at Ball State +University, Drury College, and numerous small places where opportunities +to use vast amounts of primary data may not exist. One documented effect +is that archaeological, anthropological, and philological research is +being done by the same person instead of by three different people. + +The contextual information in Perseus includes an overview essay, a +fairly linear historical essay on the fifth century B.C. that provides +links into the primary material (e.g., Herodotus, Thucydides, and +Plutarch), via small gray underscoring (on the screen) of linked +passages. These are handmade links into other material. + +To different extents, most of the production work was done at Harvard, +where the people and the equipment are located. Much of the +collaborative activity involved data collection and structuring, because +the main challenge and the emphasis of Perseus is the gathering of +primary material, that is, building a useful environment for studying +classical Greece, collecting data, and making it useful. +Systems-building is definitely not the main concern. Thus, much of the +work has involved writing essays, collecting information, rewriting it, +and tagging it. That can be done off site. The creative link for the +overview essay as well as for both systems and data was collaborative, +and was forged via E-mail and paper mail with professors at Pomona and +Bowdoin. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * PLD's principal focus and contribution to scholarship * +Various questions preparatory to beginning the project * Basis for +project * Basic rule in converting PLD * Concerning the images in PLD * +Running PLD under a variety of retrieval software * Encoding the +database a hard-fought issue * Various features demonstrated * Importance +of user documentation * Limitations of the CD-ROM version * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Eric CALALUCA, vice president, Chadwyck-Healey, Inc., demonstrated a +software interpretation of the Patrologia Latina Database (PLD). PLD's +principal focus from the beginning of the project about three-and-a-half +years ago was on converting Migne's Latin series, and in the end, +CALALUCA suggested, conversion of the text will be the major contribution +to scholarship. CALALUCA stressed that, as possibly the only private +publishing organization at the Workshop, Chadwyck-Healey had sought no +federal funds or national foundation support before embarking upon the +project, but instead had relied upon a great deal of homework and +marketing to accomplish the task of conversion. + +Ever since the possibilities of computer-searching have emerged, scholars +in the field of late ancient and early medieval studies (philosophers, +theologians, classicists, and those studying the history of natural law +and the history of the legal development of Western civilization) have +been longing for a fully searchable version of Western literature, for +example, all the texts of Augustine and Bernard of Clairvaux and +Boethius, not to mention all the secondary and tertiary authors. + +Various questions arose, CALALUCA said. Should one convert Migne? +Should the database be encoded? Is it necessary to do that? How should +it be delivered? What about CD-ROM? Since this is a transitional +medium, why even bother to create software to run on a CD-ROM? Since +everybody knows people will be networking information, why go to the +trouble--which is far greater with CD-ROM than with the production of +magnetic data? Finally, how does one make the data available? Can many +of the hurdles to using electronic information that some publishers have +imposed upon databases be eliminated? + +The PLD project was based on the principle that computer-searching of +texts is most effective when it is done with a large database. Because +PLD represented a collection that serves so many disciplines across so +many periods, it was irresistible. + +The basic rule in converting PLD was to do no harm, to avoid the sins of +intrusion in such a database: no introduction of newer editions, no +on-the-spot changes, no eradicating of all possible falsehoods from an +edition. Thus, PLD is not the final act in electronic publishing for +this discipline, but simply the beginning. The conversion of PLD has +evoked numerous unanticipated questions: How will information be used? +What about networking? Can the rights of a database be protected? +Should one protect the rights of a database? How can it be made +available? + +Those converting PLD also tried to avoid the sins of omission, that is, +excluding portions of the collections or whole sections. What about the +images? PLD is full of images, some are extremely pious +nineteenth-century representations of the Fathers, while others contain +highly interesting elements. The goal was to cover all the text of Migne +(including notes, in Greek and in Hebrew, the latter of which, in +particular, causes problems in creating a search structure), all the +indices, and even the images, which are being scanned in separately +searchable files. + +Several North American institutions that have placed acquisition requests +for the PLD database have requested it in magnetic form without software, +which means they are already running it without software, without +anything demonstrated at the Workshop. + +What cannot practically be done is go back and reconvert and re-encode +data, a time-consuming and extremely costly enterprise. CALALUCA sees +PLD as a database that can, and should, be run under a variety of +retrieval software. This will permit the widest possible searches. +Consequently, the need to produce a CD-ROM of PLD, as well as to develop +software that could handle some 1.3 gigabyte of heavily encoded text, +developed out of conversations with collection development and reference +librarians who wanted software both compassionate enough for the +pedestrian but also capable of incorporating the most detailed +lexicographical studies that a user desires to conduct. In the end, the +encoding and conversion of the data will prove the most enduring +testament to the value of the project. + +The encoding of the database was also a hard-fought issue: Did the +database need to be encoded? Were there normative structures for encoding +humanist texts? Should it be SGML? What about the TEI--will it last, +will it prove useful? CALALUCA expressed some minor doubts as to whether +a data bank can be fully TEI-conformant. Every effort can be made, but +in the end to be TEI-conformant means to accept the need to make some +firm encoding decisions that can, indeed, be disputed. The TEI points +the publisher in a proper direction but does not presume to make all the +decisions for him or her. Essentially, the goal of encoding was to +eliminate, as much as possible, the hindrances to information-networking, +so that if an institution acquires a database, everybody associated with +the institution can have access to it. + +CALALUCA demonstrated a portion of Volume 160, because it had the most +anomalies in it. The software was created by Electronic Book +Technologies of Providence, RI, and is called Dynatext. The software +works only with SGML-coded data. + +Viewing a table of contents on the screen, the audience saw how Dynatext +treats each element as a book and attempts to simplify movement through a +volume. Familiarity with the Patrologia in print (i.e., the text, its +source, and the editions) will make the machine-readable versions highly +useful. (Software with a Windows application was sought for PLD, +CALALUCA said, because this was the main trend for scholarly use.) + +CALALUCA also demonstrated how a user can perform a variety of searches +and quickly move to any part of a volume; the look-up screen provides +some basic, simple word-searching. + +CALALUCA argued that one of the major difficulties is not the software. +Rather, in creating a product that will be used by scholars representing +a broad spectrum of computer sophistication, user documentation proves +to be the most important service one can provide. + +CALALUCA next illustrated a truncated search under mysterium within ten +words of virtus and how one would be able to find its contents throughout +the entire database. He said that the exciting thing about PLD is that +many of the applications in the retrieval software being written for it +will exceed the capabilities of the software employed now for the CD-ROM +version. The CD-ROM faces genuine limitations, in terms of speed and +comprehensiveness, in the creation of a retrieval software to run it. +CALALUCA said he hoped that individual scholars will download the data, +if they wish, to their personal computers, and have ready access to +important texts on a constant basis, which they will be able to use in +their research and from which they might even be able to publish. + +(CALALUCA explained that the blue numbers represented Migne's column numbers, +which are the standard scholarly references. Pulling up a note, he stated +that these texts were heavily edited and the image files would appear simply +as a note as well, so that one could quickly access an image.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER/ERWAY * Several problems with which AM is still wrestling * +Various search and retrieval capabilities * Illustration of automatic +stemming and a truncated search * AM's attempt to find ways to connect +cataloging to the texts * AM's gravitation towards SGML * Striking a +balance between quantity and quality * How AM furnishes users recourse to +images * Conducting a search in a full-text environment * Macintosh and +IBM prototypes of AM * Multimedia aspects of AM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A demonstration of American Memory by its coordinator, Carl FLEISCHHAUER, +and Ricky ERWAY, associate coordinator, Library of Congress, concluded +the morning session. Beginning with a collection of broadsides from the +Continental Congress and the Constitutional Convention, the only text +collection in a presentable form at the time of the Workshop, FLEISCHHAUER +highlighted several of the problems with which AM is still wrestling. +(In its final form, the disk will contain two collections, not only the +broadsides but also the full text with illustrations of a set of +approximately 300 African-American pamphlets from the period 1870 to 1910.) + +As FREEMAN had explained earlier, AM has attempted to use a small amount +of interpretation to introduce collections. In the present case, the +contractor, a company named Quick Source, in Silver Spring, MD., used +software called Toolbook and put together a modestly interactive +introduction to the collection. Like the two preceding speakers, +FLEISCHHAUER argued that the real asset was the underlying collection. + +FLEISCHHAUER proceeded to describe various search and retrieval +capabilities while ERWAY worked the computer. In this particular package +the "go to" pull-down allowed the user in effect to jump out of Toolbook, +where the interactive program was located, and enter the third-party +software used by AM for this text collection, which is called Personal +Librarian. This was the Windows version of Personal Librarian, a +software application put together by a company in Rockville, Md. + +Since the broadsides came from the Revolutionary War period, a search was +conducted using the words British or war, with the default operator reset +as or. FLEISCHHAUER demonstrated both automatic stemming (which finds +other forms of the same root) and a truncated search. One of Personal +Librarian's strongest features, the relevance ranking, was represented by +a chart that indicated how often words being sought appeared in +documents, with the one receiving the most "hits" obtaining the highest +score. The "hit list" that is supplied takes the relevance ranking into +account, making the first hit, in effect, the one the software has +selected as the most relevant example. + +While in the text of one of the broadside documents, FLEISCHHAUER +remarked AM's attempt to find ways to connect cataloging to the texts, +which it does in different ways in different manifestations. In the case +shown, the cataloging was pasted on: AM took MARC records that were +written as on-line records right into one of the Library's mainframe +retrieval programs, pulled them out, and handed them off to the contractor, +who massaged them somewhat to display them in the manner shown. One of +AM's questions is, Does the cataloguing normally performed in the mainframe +work in this context, or had AM ought to think through adjustments? + +FLEISCHHAUER made the additional point that, as far as the text goes, AM +has gravitated towards SGML (he pointed to the boldface in the upper part +of the screen). Although extremely limited in its ability to translate +or interpret SGML, Personal Librarian will furnish both bold and italics +on screen; a fairly easy thing to do, but it is one of the ways in which +SGML is useful. + +Striking a balance between quantity and quality has been a major concern +of AM, with accuracy being one of the places where project staff have +felt that less than 100-percent accuracy was not unacceptable. +FLEISCHHAUER cited the example of the standard of the rekeying industry, +namely 99.95 percent; as one service bureau informed him, to go from +99.95 to 100 percent would double the cost. + +FLEISCHHAUER next demonstrated how AM furnishes users recourse to images, +and at the same time recalled LESK's pointed question concerning the +number of people who would look at those images and the number who would +work only with the text. If the implication of LESK's question was +sound, FLEISCHHAUER said, it raised the stakes for text accuracy and +reduced the value of the strategy for images. + +Contending that preservation is always a bugaboo, FLEISCHHAUER +demonstrated several images derived from a scan of a preservation +microfilm that AM had made. He awarded a grade of C at best, perhaps a +C minus or a C plus, for how well it worked out. Indeed, the matter of +learning if other people had better ideas about scanning in general, and, +in particular, scanning from microfilm, was one of the factors that drove +AM to attempt to think through the agenda for the Workshop. Skew, for +example, was one of the issues that AM in its ignorance had not reckoned +would prove so difficult. + +Further, the handling of images of the sort shown, in a desktop computer +environment, involved a considerable amount of zooming and scrolling. +Ultimately, AM staff feel that perhaps the paper copy that is printed out +might be the most useful one, but they remain uncertain as to how much +on-screen reading users will do. + +Returning to the text, FLEISCHHAUER asked viewers to imagine a person who +might be conducting a search in a full-text environment. With this +scenario, he proceeded to illustrate other features of Personal Librarian +that he considered helpful; for example, it provides the ability to +notice words as one reads. Clicking the "include" button on the bottom +of the search window pops the words that have been highlighted into the +search. Thus, a user can refine the search as he or she reads, +re-executing the search and continuing to find things in the quest for +materials. This software not only contains relevance ranking, Boolean +operators, and truncation, it also permits one to perform word algebra, +so to say, where one puts two or three words in parentheses and links +them with one Boolean operator and then a couple of words in another set +of parentheses and asks for things within so many words of others. + +Until they became acquainted recently with some of the work being done in +classics, the AM staff had not realized that a large number of the +projects that involve electronic texts were being done by people with a +profound interest in language and linguistics. Their search strategies +and thinking are oriented to those fields, as is shown in particular by +the Perseus example. As amateur historians, the AM staff were thinking +more of searching for concepts and ideas than for particular words. +Obviously, FLEISCHHAUER conceded, searching for concepts and ideas and +searching for words may be two rather closely related things. + +While displaying several images, FLEISCHHAUER observed that the Macintosh +prototype built by AM contains a greater diversity of formats. Echoing a +previous speaker, he said that it was easier to stitch things together in +the Macintosh, though it tended to be a little more anemic in search and +retrieval. AM, therefore, increasingly has been investigating +sophisticated retrieval engines in the IBM format. + +FLEISCHHAUER demonstrated several additional examples of the prototype +interfaces: One was AM's metaphor for the network future, in which a +kind of reading-room graphic suggests how one would be able to go around +to different materials. AM contains a large number of photographs in +analog video form worked up from a videodisc, which enable users to make +copies to print or incorporate in digital documents. A frame-grabber is +built into the system, making it possible to bring an image into a window +and digitize or print it out. + +FLEISCHHAUER next demonstrated sound recording, which included texts. +Recycled from a previous project, the collection included sixty 78-rpm +phonograph records of political speeches that were made during and +immediately after World War I. These constituted approximately three +hours of audio, as AM has digitized it, which occupy 150 megabytes on a +CD. Thus, they are considerably compressed. From the catalogue card, +FLEISCHHAUER proceeded to a transcript of a speech with the audio +available and with highlighted text following it as it played. +A photograph has been added and a transcription made. + +Considerable value has been added beyond what the Library of Congress +normally would do in cataloguing a sound recording, which raises several +questions for AM concerning where to draw lines about how much value it can +afford to add and at what point, perhaps, this becomes more than AM could +reasonably do or reasonably wish to do. FLEISCHHAUER also demonstrated +a motion picture. As FREEMAN had reported earlier, the motion picture +materials have proved the most popular, not surprisingly. This says more +about the medium, he thought, than about AM's presentation of it. + +Because AM's goal was to bring together things that could be used by +historians or by people who were curious about history, +turn-of-the-century footage seemed to represent the most appropriate +collections from the Library of Congress in motion pictures. These were +the very first films made by Thomas Edison's company and some others at +that time. The particular example illustrated was a Biograph film, +brought in with a frame-grabber into a window. A single videodisc +contains about fifty titles and pieces of film from that period, all of +New York City. Taken together, AM believes, they provide an interesting +documentary resource. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Using the frame-grabber in AM * Volume of material processed +and to be processed * Purpose of AM within LC * Cataloguing and the +nature of AM's material * SGML coding and the question of quality versus +quantity * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed FLEISCHHAUER's +presentation, several clarifications were made. + +AM is bringing in motion pictures from a videodisc. The frame-grabber +devices create a window on a computer screen, which permits users to +digitize a single frame of the movie or one of the photographs. It +produces a crude, rough-and-ready image that high school students can +incorporate into papers, and that has worked very nicely in this way. + +Commenting on FLEISCHHAUER's assertion that AM was looking more at +searching ideas than words, MYLONAS argued that without words an idea +does not exist. FLEISCHHAUER conceded that he ought to have articulated +his point more clearly. MYLONAS stated that they were in fact both +talking about the same thing. By searching for words and by forcing +people to focus on the word, the Perseus Project felt that they would get +them to the idea. The way one reviews results is tailored more to one +kind of user than another. + +Concerning the total volume of material that has been processed in this +way, AM at this point has in retrievable form seven or eight collections, +all of them photographic. In the Macintosh environment, for example, +there probably are 35,000-40,000 photographs. The sound recordings +number sixty items. The broadsides number about 300 items. There are +500 political cartoons in the form of drawings. The motion pictures, as +individual items, number sixty to seventy. + +AM also has a manuscript collection, the life history portion of one of +the federal project series, which will contain 2,900 individual +documents, all first-person narratives. AM has in process about 350 +African-American pamphlets, or about 12,000 printed pages for the period +1870-1910. Also in the works are some 4,000 panoramic photographs. AM +has recycled a fair amount of the work done by LC's Prints and +Photographs Division during the Library's optical disk pilot project in +the 1980s. For example, a special division of LC has tooled up and +thought through all the ramifications of electronic presentation of +photographs. Indeed, they are wheeling them out in great barrel loads. +The purpose of AM within the Library, it is hoped, is to catalyze several +of the other special collection divisions which have no particular +experience with, in some cases, mixed feelings about, an activity such as +AM. Moreover, in many cases the divisions may be characterized as not +only lacking experience in "electronifying" things but also in automated +cataloguing. MARC cataloguing as practiced in the United States is +heavily weighted toward the description of monograph and serial +materials, but is much thinner when one enters the world of manuscripts +and things that are held in the Library's music collection and other +units. In response to a comment by LESK, that AM's material is very +heavily photographic, and is so primarily because individual records have +been made for each photograph, FLEISCHHAUER observed that an item-level +catalog record exists, for example, for each photograph in the Detroit +Publishing collection of 25,000 pictures. In the case of the Federal +Writers Project, for which nearly 3,000 documents exist, representing +information from twenty-six different states, AM with the assistance of +Karen STUART of the Manuscript Division will attempt to find some way not +only to have a collection-level record but perhaps a MARC record for each +state, which will then serve as an umbrella for the 100-200 documents +that come under it. But that drama remains to be enacted. The AM staff +is conservative and clings to cataloguing, though of course visitors tout +artificial intelligence and neural networks in a manner that suggests that +perhaps one need not have cataloguing or that much of it could be put aside. + +The matter of SGML coding, FLEISCHHAUER conceded, returned the discussion +to the earlier treated question of quality versus quantity in the Library +of Congress. Of course, text conversion can be done with 100-percent +accuracy, but it means that when one's holdings are as vast as LC's only +a tiny amount will be exposed, whereas permitting lower levels of +accuracy can lead to exposing or sharing larger amounts, but with the +quality correspondingly impaired. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TWOHIG * A contrary experience concerning electronic options * Volume of +material in the Washington papers and a suggestion of David Packard * +Implications of Packard's suggestion * Transcribing the documents for the +CD-ROM * Accuracy of transcriptions * The CD-ROM edition of the Founding +Fathers documents * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Finding encouragement in a comment of MICHELSON's from the morning +session--that numerous people in the humanities were choosing electronic +options to do their work--Dorothy TWOHIG, editor, The Papers of George +Washington, opened her illustrated talk by noting that her experience +with literary scholars and numerous people in editing was contrary to +MICHELSON's. TWOHIG emphasized literary scholars' complete ignorance of +the technological options available to them or their reluctance or, in +some cases, their downright hostility toward these options. + +After providing an overview of the five Founding Fathers projects +(Jefferson at Princeton, Franklin at Yale, John Adams at the +Massachusetts Historical Society, and Madison down the hall from her at +the University of Virginia), TWOHIG observed that the Washington papers, +like all of the projects, include both sides of the Washington +correspondence and deal with some 135,000 documents to be published with +extensive annotation in eighty to eighty-five volumes, a project that +will not be completed until well into the next century. Thus, it was +with considerable enthusiasm several years ago that the Washington Papers +Project (WPP) greeted David Packard's suggestion that the papers of the +Founding Fathers could be published easily and inexpensively, and to the +great benefit of American scholarship, via CD-ROM. + +In pragmatic terms, funding from the Packard Foundation would expedite +the transcription of thousands of documents waiting to be put on disk in +the WPP offices. Further, since the costs of collecting, editing, and +converting the Founding Fathers documents into letterpress editions were +running into the millions of dollars, and the considerable staffs +involved in all of these projects were devoting their careers to +producing the work, the Packard Foundation's suggestion had a +revolutionary aspect: Transcriptions of the entire corpus of the +Founding Fathers papers would be available on CD-ROM to public and +college libraries, even high schools, at a fraction of the cost-- +$100-$150 for the annual license fee--to produce a limited university +press run of 1,000 of each volume of the published papers at $45-$150 per +printed volume. Given the current budget crunch in educational systems +and the corresponding constraints on librarians in smaller institutions +who wish to add these volumes to their collections, producing the +documents on CD-ROM would likely open a greatly expanded audience for the +papers. TWOHIG stressed, however, that development of the Founding +Fathers CD-ROM is still in its infancy. Serious software problems remain +to be resolved before the material can be put into readable form. + +Funding from the Packard Foundation resulted in a major push to +transcribe the 75,000 or so documents of the Washington papers remaining +to be transcribed onto computer disks. Slides illustrated several of the +problems encountered, for example, the present inability of CD-ROM to +indicate the cross-outs (deleted material) in eighteenth century +documents. TWOHIG next described documents from various periods in the +eighteenth century that have been transcribed in chronological order and +delivered to the Packard offices in California, where they are converted +to the CD-ROM, a process that is expected to consume five years to +complete (that is, reckoning from David Packard's suggestion made several +years ago, until about July 1994). TWOHIG found an encouraging +indication of the project's benefits in the ongoing use made by scholars +of the search functions of the CD-ROM, particularly in reducing the time +spent in manually turning the pages of the Washington papers. + +TWOHIG next furnished details concerning the accuracy of transcriptions. +For instance, the insertion of thousands of documents on the CD-ROM +currently does not permit each document to be verified against the +original manuscript several times as in the case of documents that appear +in the published edition. However, the transcriptions receive a cursory +check for obvious typos, the misspellings of proper names, and other +errors from the WPP CD-ROM editor. Eventually, all documents that appear +in the electronic version will be checked by project editors. Although +this process has met with opposition from some of the editors on the +grounds that imperfect work may leave their offices, the advantages in +making this material available as a research tool outweigh fears about the +misspelling of proper names and other relatively minor editorial matters. + +Completion of all five Founding Fathers projects (i.e., retrievability +and searchability of all of the documents by proper names, alternate +spellings, or varieties of subjects) will provide one of the richest +sources of this size for the history of the United States in the latter +part of the eighteenth century. Further, publication on CD-ROM will +allow editors to include even minutiae, such as laundry lists, not +included in the printed volumes. + +It seems possible that the extensive annotation provided in the printed +volumes eventually will be added to the CD-ROM edition, pending +negotiations with the publishers of the papers. At the moment, the +Founding Fathers CD-ROM is accessible only on the IBYCUS, a computer +developed out of the Thesaurus Linguae Graecae project and designed for +the use of classical scholars. There are perhaps 400 IBYCUS computers in +the country, most of which are in university classics departments. +Ultimately, it is anticipated that the CD-ROM edition of the Founding +Fathers documents will run on any IBM-compatible or Macintosh computer +with a CD-ROM drive. Numerous changes in the software will also occur +before the project is completed. (Editor's note: an IBYCUS was +unavailable to demonstrate the CD-ROM.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Several additional features of WPP clarified * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Discussion following TWOHIG's presentation served to clarify several +additional features, including (1) that the project's primary +intellectual product consists in the electronic transcription of the +material; (2) that the text transmitted to the CD-ROM people is not +marked up; (3) that cataloging and subject-indexing of the material +remain to be worked out (though at this point material can be retrieved +by name); and (4) that because all the searching is done in the hardware, +the IBYCUS is designed to read a CD-ROM which contains only sequential +text files. Technically, it then becomes very easy to read the material +off and put it on another device. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LEBRON * Overview of the history of the joint project between AAAS and +OCLC * Several practices the on-line environment shares with traditional +publishing on hard copy * Several technical and behavioral barriers to +electronic publishing * How AAAS and OCLC arrived at the subject of +clinical trials * Advantages of the electronic format and other features +of OJCCT * An illustrated tour of the journal * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Maria LEBRON, managing editor, The Online Journal of Current Clinical +Trials (OJCCT), presented an illustrated overview of the history of the +joint project between the American Association for the Advancement of +Science (AAAS) and the Online Computer Library Center, Inc. (OCLC). The +joint venture between AAAS and OCLC owes its beginning to a +reorganization launched by the new chief executive officer at OCLC about +three years ago and combines the strengths of these two disparate +organizations. In short, OJCCT represents the process of scholarly +publishing on line. + +LEBRON next discussed several practices the on-line environment shares +with traditional publishing on hard copy--for example, peer review of +manuscripts--that are highly important in the academic world. LEBRON +noted in particular the implications of citation counts for tenure +committees and grants committees. In the traditional hard-copy +environment, citation counts are readily demonstrable, whereas the +on-line environment represents an ethereal medium to most academics. + +LEBRON remarked several technical and behavioral barriers to electronic +publishing, for instance, the problems in transmission created by special +characters or by complex graphics and halftones. In addition, she noted +economic limitations such as the storage costs of maintaining back issues +and market or audience education. + +Manuscripts cannot be uploaded to OJCCT, LEBRON explained, because it is +not a bulletin board or E-mail, forms of electronic transmission of +information that have created an ambience clouding people's understanding +of what the journal is attempting to do. OJCCT, which publishes +peer-reviewed medical articles dealing with the subject of clinical +trials, includes text, tabular material, and graphics, although at this +time it can transmit only line illustrations. + +Next, LEBRON described how AAAS and OCLC arrived at the subject of +clinical trials: It is 1) a highly statistical discipline that 2) does +not require halftones but can satisfy the needs of its audience with line +illustrations and graphic material, and 3) there is a need for the speedy +dissemination of high-quality research results. Clinical trials are +research activities that involve the administration of a test treatment +to some experimental unit in order to test its usefulness before it is +made available to the general population. LEBRON proceeded to give +additional information on OJCCT concerning its editor-in-chief, editorial +board, editorial content, and the types of articles it publishes +(including peer-reviewed research reports and reviews), as well as +features shared by other traditional hard-copy journals. + +Among the advantages of the electronic format are faster dissemination of +information, including raw data, and the absence of space constraints +because pages do not exist. (This latter fact creates an interesting +situation when it comes to citations.) Nor are there any issues. AAAS's +capacity to download materials directly from the journal to a +subscriber's printer, hard drive, or floppy disk helps ensure highly +accurate transcription. Other features of OJCCT include on-screen alerts +that allow linkage of subsequently published documents to the original +documents; on-line searching by subject, author, title, etc.; indexing of +every single word that appears in an article; viewing access to an +article by component (abstract, full text, or graphs); numbered +paragraphs to replace page counts; publication in Science every thirty +days of indexing of all articles published in the journal; +typeset-quality screens; and Hypertext links that enable subscribers to +bring up Medline abstracts directly without leaving the journal. + +After detailing the two primary ways to gain access to the journal, +through the OCLC network and Compuserv if one desires graphics or through +the Internet if just an ASCII file is desired, LEBRON illustrated the +speedy editorial process and the coding of the document using SGML tags +after it has been accepted for publication. She also gave an illustrated +tour of the journal, its search-and-retrieval capabilities in particular, +but also including problems associated with scanning in illustrations, +and the importance of on-screen alerts to the medical profession re +retractions or corrections, or more frequently, editorials, letters to +the editors, or follow-up reports. She closed by inviting the audience +to join AAAS on 1 July, when OJCCT was scheduled to go on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional features of OJCCT * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the lengthy discussion that followed LEBRON's presentation, these +points emerged: + + * The SGML text can be tailored as users wish. + + * All these articles have a fairly simple document definition. + + * Document-type definitions (DTDs) were developed and given to OJCCT + for coding. + + * No articles will be removed from the journal. (Because there are + no back issues, there are no lost issues either. Once a subscriber + logs onto the journal he or she has access not only to the currently + published materials, but retrospectively to everything that has been + published in it. Thus the table of contents grows bigger. The date + of publication serves to distinguish between currently published + materials and older materials.) + + * The pricing system for the journal resembles that for most medical + journals: for 1992, $95 for a year, plus telecommunications charges + (there are no connect time charges); for 1993, $110 for the + entire year for single users, though the journal can be put on a + local area network (LAN). However, only one person can access the + journal at a time. Site licenses may come in the future. + + * AAAS is working closely with colleagues at OCLC to display + mathematical equations on screen. + + * Without compromising any steps in the editorial process, the + technology has reduced the time lag between when a manuscript is + originally submitted and the time it is accepted; the review process + does not differ greatly from the standard six-to-eight weeks + employed by many of the hard-copy journals. The process still + depends on people. + + * As far as a preservation copy is concerned, articles will be + maintained on the computer permanently and subscribers, as part of + their subscription, will receive a microfiche-quality archival copy + of everything published during that year; in addition, reprints can + be purchased in much the same way as in a hard-copy environment. + Hard copies are prepared but are not the primary medium for the + dissemination of the information. + + * Because OJCCT is not yet on line, it is difficult to know how many + people would simply browse through the journal on the screen as + opposed to downloading the whole thing and printing it out; a mix of + both types of users likely will result. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PERSONIUS * Developments in technology over the past decade * The CLASS +Project * Advantages for technology and for the CLASS Project * +Developing a network application an underlying assumption of the project +* Details of the scanning process * Print-on-demand copies of books * +Future plans include development of a browsing tool * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Lynne PERSONIUS, assistant director, Cornell Information Technologies for +Scholarly Information Services, Cornell University, first commented on +the tremendous impact that developments in technology over the past ten +years--networking, in particular--have had on the way information is +handled, and how, in her own case, these developments have counterbalanced +Cornell's relative geographical isolation. Other significant technologies +include scanners, which are much more sophisticated than they were ten years +ago; mass storage and the dramatic savings that result from it in terms of +both space and money relative to twenty or thirty years ago; new and +improved printing technologies, which have greatly affected the distribution +of information; and, of course, digital technologies, whose applicability to +library preservation remains at issue. + +Given that context, PERSONIUS described the College Library Access and +Storage System (CLASS) Project, a library preservation project, +primarily, and what has been accomplished. Directly funded by the +Commission on Preservation and Access and by the Xerox Corporation, which +has provided a significant amount of hardware, the CLASS Project has been +working with a development team at Xerox to develop a software +application tailored to library preservation requirements. Within +Cornell, participants in the project have been working jointly with both +library and information technologies. The focus of the project has been +on reformatting and saving books that are in brittle condition. +PERSONIUS showed Workshop participants a brittle book, and described how +such books were the result of developments in papermaking around the +beginning of the Industrial Revolution. The papermaking process was +changed so that a significant amount of acid was introduced into the +actual paper itself, which deteriorates as it sits on library shelves. + +One of the advantages for technology and for the CLASS Project is that +the information in brittle books is mostly out of copyright and thus +offers an opportunity to work with material that requires library +preservation, and to create and work on an infrastructure to save the +material. Acknowledging the familiarity of those working in preservation +with this information, PERSONIUS noted that several things are being +done: the primary preservation technology used today is photocopying of +brittle material. Saving the intellectual content of the material is the +main goal. With microfilm copy, the intellectual content is preserved on +the assumption that in the future the image can be reformatted in any +other way that then exists. + +An underlying assumption of the CLASS Project from the beginning was +that it would develop a network application. Project staff scan books +at a workstation located in the library, near the brittle material. +An image-server filing system is located at a distance from that +workstation, and a printer is located in another building. All of the +materials digitized and stored on the image-filing system are cataloged +in the on-line catalogue. In fact, a record for each of these electronic +books is stored in the RLIN database so that a record exists of what is +in the digital library throughout standard catalogue procedures. In the +future, researchers working from their own workstations in their offices, +or their networks, will have access--wherever they might be--through a +request server being built into the new digital library. A second +assumption is that the preferred means of finding the material will be by +looking through a catalogue. PERSONIUS described the scanning process, +which uses a prototype scanner being developed by Xerox and which scans a +very high resolution image at great speed. Another significant feature, +because this is a preservation application, is the placing of the pages +that fall apart one for one on the platen. Ordinarily, a scanner could +be used with some sort of a document feeder, but because of this +application that is not feasible. Further, because CLASS is a +preservation application, after the paper replacement is made there, a +very careful quality control check is performed. An original book is +compared to the printed copy and verification is made, before proceeding, +that all of the image, all of the information, has been captured. Then, +a new library book is produced: The printed images are rebound by a +commercial binder and a new book is returned to the shelf. +Significantly, the books returned to the library shelves are beautiful +and useful replacements on acid-free paper that should last a long time, +in effect, the equivalent of preservation photocopies. Thus, the project +has a library of digital books. In essence, CLASS is scanning and +storing books as 600 dot-per-inch bit-mapped images, compressed using +Group 4 CCITT (i.e., the French acronym for International Consultative +Committee for Telegraph and Telephone) compression. They are stored as +TIFF files on an optical filing system that is composed of a database +used for searching and locating the books and an optical jukebox that +stores 64 twelve-inch platters. A very-high-resolution printed copy of +these books at 600 dots per inch is created, using a Xerox DocuTech +printer to make the paper replacements on acid-free paper. + +PERSONIUS maintained that the CLASS Project presents an opportunity to +introduce people to books as digital images by using a paper medium. +Books are returned to the shelves while people are also given the ability +to print on demand--to make their own copies of books. (PERSONIUS +distributed copies of an engineering journal published by engineering +students at Cornell around 1900 as an example of what a print-on-demand +copy of material might be like. This very cheap copy would be available +to people to use for their own research purposes and would bridge the gap +between an electronic work and the paper that readers like to have.) +PERSONIUS then attempted to illustrate a very early prototype of +networked access to this digital library. Xerox Corporation has +developed a prototype of a view station that can send images across the +network to be viewed. + +The particular library brought down for demonstration contained two +mathematics books. CLASS is developing and will spend the next year +developing an application that allows people at workstations to browse +the books. Thus, CLASS is developing a browsing tool, on the assumption +that users do not want to read an entire book from a workstation, but +would prefer to be able to look through and decide if they would like to +have a printed copy of it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Re retrieval software * "Digital file copyright" * Scanning +rate during production * Autosegmentation * Criteria employed in +selecting books for scanning * Compression and decompression of images * +OCR not precluded * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed her presentation, +PERSONIUS made these additional points: + + * Re retrieval software, Cornell is developing a Unix-based server + as well as clients for the server that support multiple platforms + (Macintosh, IBM and Sun workstations), in the hope that people from + any of those platforms will retrieve books; a further operating + assumption is that standard interfaces will be used as much as + possible, where standards can be put in place, because CLASS + considers this retrieval software a library application and would + like to be able to look at material not only at Cornell but at other + institutions. + + * The phrase "digital file copyright by Cornell University" was + added at the advice of Cornell's legal staff with the caveat that it + probably would not hold up in court. Cornell does not want people + to copy its books and sell them but would like to keep them + available for use in a library environment for library purposes. + + * In production the scanner can scan about 300 pages per hour, + capturing 600 dots per inch. + + * The Xerox software has filters to scan halftone material and avoid + the moire patterns that occur when halftone material is scanned. + Xerox has been working on hardware and software that would enable + the scanner itself to recognize this situation and deal with it + appropriately--a kind of autosegmentation that would enable the + scanner to handle halftone material as well as text on a single page. + + * The books subjected to the elaborate process described above were + selected because CLASS is a preservation project, with the first 500 + books selected coming from Cornell's mathematics collection, because + they were still being heavily used and because, although they were + in need of preservation, the mathematics library and the mathematics + faculty were uncomfortable having them microfilmed. (They wanted a + printed copy.) Thus, these books became a logical choice for this + project. Other books were chosen by the project's selection committees + for experiments with the technology, as well as to meet a demand or need. + + * Images will be decompressed before they are sent over the line; at + this time they are compressed and sent to the image filing system + and then sent to the printer as compressed images; they are returned + to the workstation as compressed 600-dpi images and the workstation + decompresses and scales them for display--an inefficient way to + access the material though it works quite well for printing and + other purposes. + + * CLASS is also decompressing on Macintosh and IBM, a slow process + right now. Eventually, compression and decompression will take + place on an image conversion server. Trade-offs will be made, based + on future performance testing, concerning where the file is + compressed and what resolution image is sent. + + * OCR has not been precluded; images are being stored that have been + scanned at a high resolution, which presumably would suit them well + to an OCR process. Because the material being scanned is about 100 + years old and was printed with less-than-ideal technologies, very + early and preliminary tests have not produced good results. But the + project is capturing an image that is of sufficient resolution to be + subjected to OCR in the future. Moreover, the system architecture + and the system plan have a logical place to store an OCR image if it + has been captured. But that is not being done now. + + ****** + +SESSION III. DISTRIBUTION, NETWORKS, AND NETWORKING: OPTIONS FOR +DISSEMINATION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZICH * Issues pertaining to CD-ROMs * Options for publishing in CD-ROM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Robert ZICH, special assistant to the associate librarian for special +projects, Library of Congress, and moderator of this session, first noted +the blessed but somewhat awkward circumstance of having four very +distinguished people representing networks and networking or at least +leaning in that direction, while lacking anyone to speak from the +strongest possible background in CD-ROMs. ZICH expressed the hope that +members of the audience would join the discussion. He stressed the +subtitle of this particular session, "Options for Dissemination," and, +concerning CD-ROMs, the importance of determining when it would be wise +to consider dissemination in CD-ROM versus networks. A shopping list of +issues pertaining to CD-ROMs included: the grounds for selecting +commercial publishers, and in-house publication where possible versus +nonprofit or government publication. A similar list for networks +included: determining when one should consider dissemination through a +network, identifying the mechanisms or entities that exist to place items +on networks, identifying the pool of existing networks, determining how a +producer would choose between networks, and identifying the elements of +a business arrangement in a network. + +Options for publishing in CD-ROM: an outside publisher versus +self-publication. If an outside publisher is used, it can be nonprofit, +such as the Government Printing Office (GPO) or the National Technical +Information Service (NTIS), in the case of government. The pros and cons +associated with employing an outside publisher are obvious. Among the +pros, there is no trouble getting accepted. One pays the bill and, in +effect, goes one's way. Among the cons, when one pays an outside +publisher to perform the work, that publisher will perform the work it is +obliged to do, but perhaps without the production expertise and skill in +marketing and dissemination that some would seek. There is the body of +commercial publishers that do possess that kind of expertise in +distribution and marketing but that obviously are selective. In +self-publication, one exercises full control, but then one must handle +matters such as distribution and marketing. Such are some of the options +for publishing in the case of CD-ROM. + +In the case of technical and design issues, which are also important, +there are many matters which many at the Workshop already knew a good +deal about: retrieval system requirements and costs, what to do about +images, the various capabilities and platforms, the trade-offs between +cost and performance, concerns about local-area networkability, +interoperability, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LYNCH * Creating networked information is different from using networks +as an access or dissemination vehicle * Networked multimedia on a large +scale does not yet work * Typical CD-ROM publication model a two-edged +sword * Publishing information on a CD-ROM in the present world of +immature standards * Contrast between CD-ROM and network pricing * +Examples demonstrated earlier in the day as a set of insular information +gems * Paramount need to link databases * Layering to become increasingly +necessary * Project NEEDS and the issues of information reuse and active +versus passive use * X-Windows as a way of differentiating between +network access and networked information * Barriers to the distribution +of networked multimedia information * Need for good, real-time delivery +protocols * The question of presentation integrity in client-server +computing in the academic world * Recommendations for producing multimedia ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Clifford LYNCH, director, Library Automation, University of California, +opened his talk with the general observation that networked information +constituted a difficult and elusive topic because it is something just +starting to develop and not yet fully understood. LYNCH contended that +creating genuinely networked information was different from using +networks as an access or dissemination vehicle and was more sophisticated +and more subtle. He invited the members of the audience to extrapolate, +from what they heard about the preceding demonstration projects, to what +sort of a world of electronics information--scholarly, archival, +cultural, etc.--they wished to end up with ten or fifteen years from now. +LYNCH suggested that to extrapolate directly from these projects would +produce unpleasant results. + +Putting the issue of CD-ROM in perspective before getting into +generalities on networked information, LYNCH observed that those engaged +in multimedia today who wish to ship a product, so to say, probably do +not have much choice except to use CD-ROM: networked multimedia on a +large scale basically does not yet work because the technology does not +exist. For example, anybody who has tried moving images around over the +Internet knows that this is an exciting touch-and-go process, a +fascinating and fertile area for experimentation, research, and +development, but not something that one can become deeply enthusiastic +about committing to production systems at this time. + +This situation will change, LYNCH said. He differentiated CD-ROM from +the practices that have been followed up to now in distributing data on +CD-ROM. For LYNCH the problem with CD-ROM is not its portability or its +slowness but the two-edged sword of having the retrieval application and +the user interface inextricably bound up with the data, which is the +typical CD-ROM publication model. It is not a case of publishing data +but of distributing a typically stand-alone, typically closed system, +all--software, user interface, and data--on a little disk. Hence, all +the between-disk navigational issues as well as the impossibility in most +cases of integrating data on one disk with that on another. Most CD-ROM +retrieval software does not network very gracefully at present. However, +in the present world of immature standards and lack of understanding of +what network information is or what the ground rules are for creating or +using it, publishing information on a CD-ROM does add value in a very +real sense. + +LYNCH drew a contrast between CD-ROM and network pricing and in doing so +highlighted something bizarre in information pricing. A large +institution such as the University of California has vendors who will +offer to sell information on CD-ROM for a price per year in four digits, +but for the same data (e.g., an abstracting and indexing database) on +magnetic tape, regardless of how many people may use it concurrently, +will quote a price in six digits. + +What is packaged with the CD-ROM in one sense adds value--a complete +access system, not just raw, unrefined information--although it is not +generally perceived that way. This is because the access software, +although it adds value, is viewed by some people, particularly in the +university environment where there is a very heavy commitment to +networking, as being developed in the wrong direction. + +Given that context, LYNCH described the examples demonstrated as a set of +insular information gems--Perseus, for example, offers nicely linked +information, but would be very difficult to integrate with other +databases, that is, to link together seamlessly with other source files +from other sources. It resembles an island, and in this respect is +similar to numerous stand-alone projects that are based on videodiscs, +that is, on the single-workstation concept. + +As scholarship evolves in a network environment, the paramount need will +be to link databases. We must link personal databases to public +databases, to group databases, in fairly seamless ways--which is +extremely difficult in the environments under discussion with copies of +databases proliferating all over the place. + +The notion of layering also struck LYNCH as lurking in several of the +projects demonstrated. Several databases in a sense constitute +information archives without a significant amount of navigation built in. +Educators, critics, and others will want a layered structure--one that +defines or links paths through the layers to allow users to reach +specific points. In LYNCH's view, layering will become increasingly +necessary, and not just within a single resource but across resources +(e.g., tracing mythology and cultural themes across several classics +databases as well as a database of Renaissance culture). This ability to +organize resources, to build things out of multiple other things on the +network or select pieces of it, represented for LYNCH one of the key +aspects of network information. + +Contending that information reuse constituted another significant issue, +LYNCH commended to the audience's attention Project NEEDS (i.e., National +Engineering Education Delivery System). This project's objective is to +produce a database of engineering courseware as well as the components +that can be used to develop new courseware. In a number of the existing +applications, LYNCH said, the issue of reuse (how much one can take apart +and reuse in other applications) was not being well considered. He also +raised the issue of active versus passive use, one aspect of which is +how much information will be manipulated locally by users. Most people, +he argued, may do a little browsing and then will wish to print. LYNCH +was uncertain how these resources would be used by the vast majority of +users in the network environment. + +LYNCH next said a few words about X-Windows as a way of differentiating +between network access and networked information. A number of the +applications demonstrated at the Workshop could be rewritten to use X +across the network, so that one could run them from any X-capable device- +-a workstation, an X terminal--and transact with a database across the +network. Although this opens up access a little, assuming one has enough +network to handle it, it does not provide an interface to develop a +program that conveniently integrates information from multiple databases. +X is a viewing technology that has limits. In a real sense, it is just a +graphical version of remote log-in across the network. X-type applications +represent only one step in the progression towards real access. + +LYNCH next discussed barriers to the distribution of networked multimedia +information. The heart of the problem is a lack of standards to provide +the ability for computers to talk to each other, retrieve information, +and shuffle it around fairly casually. At the moment, little progress is +being made on standards for networked information; for example, present +standards do not cover images, digital voice, and digital video. A +useful tool kit of exchange formats for basic texts is only now being +assembled. The synchronization of content streams (i.e., synchronizing a +voice track to a video track, establishing temporal relations between +different components in a multimedia object) constitutes another issue +for networked multimedia that is just beginning to receive attention. + +Underlying network protocols also need some work; good, real-time +delivery protocols on the Internet do not yet exist. In LYNCH's view, +highly important in this context is the notion of networked digital +object IDs, the ability of one object on the network to point to another +object (or component thereof) on the network. Serious bandwidth issues +also exist. LYNCH was uncertain if billion-bit-per-second networks would +prove sufficient if numerous people ran video in parallel. + +LYNCH concluded by offering an issue for database creators to consider, +as well as several comments about what might constitute good trial +multimedia experiments. In a networked information world the database +builder or service builder (publisher) does not exercise the same +extensive control over the integrity of the presentation; strange +programs "munge" with one's data before the user sees it. Serious +thought must be given to what guarantees integrity of presentation. Part +of that is related to where one draws the boundaries around a networked +information service. This question of presentation integrity in +client-server computing has not been stressed enough in the academic +world, LYNCH argued, though commercial service providers deal with it +regularly. + +Concerning multimedia, LYNCH observed that good multimedia at the moment +is hideously expensive to produce. He recommended producing multimedia +with either very high sale value, or multimedia with a very long life +span, or multimedia that will have a very broad usage base and whose +costs therefore can be amortized among large numbers of users. In this +connection, historical and humanistically oriented material may be a good +place to start, because it tends to have a longer life span than much of +the scientific material, as well as a wider user base. LYNCH noted, for +example, that American Memory fits many of the criteria outlined. He +remarked the extensive discussion about bringing the Internet or the +National Research and Education Network (NREN) into the K-12 environment +as a way of helping the American educational system. + +LYNCH closed by noting that the kinds of applications demonstrated struck +him as excellent justifications of broad-scale networking for K-12, but +that at this time no "killer" application exists to mobilize the K-12 +community to obtain connectivity. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Dearth of genuinely interesting applications on the network +a slow-changing situation * The issue of the integrity of presentation in +a networked environment * Several reasons why CD-ROM software does not +network * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period that followed LYNCH's presentation, several +additional points were made. + +LYNCH reiterated even more strongly his contention that, historically, +once one goes outside high-end science and the group of those who need +access to supercomputers, there is a great dearth of genuinely +interesting applications on the network. He saw this situation changing +slowly, with some of the scientific databases and scholarly discussion +groups and electronic journals coming on as well as with the availability +of Wide Area Information Servers (WAIS) and some of the databases that +are being mounted there. However, many of those things do not seem to +have piqued great popular interest. For instance, most high school +students of LYNCH's acquaintance would not qualify as devotees of serious +molecular biology. + +Concerning the issue of the integrity of presentation, LYNCH believed +that a couple of information providers have laid down the law at least on +certain things. For example, his recollection was that the National +Library of Medicine feels strongly that one needs to employ the +identifier field if he or she is to mount a database commercially. The +problem with a real networked environment is that one does not know who +is reformatting and reprocessing one's data when one enters a client +server mode. It becomes anybody's guess, for example, if the network +uses a Z39.50 server, or what clients are doing with one's data. A data +provider can say that his contract will only permit clients to have +access to his data after he vets them and their presentation and makes +certain it suits him. But LYNCH held out little expectation that the +network marketplace would evolve in that way, because it required too +much prior negotiation. + +CD-ROM software does not network for a variety of reasons, LYNCH said. +He speculated that CD-ROM publishers are not eager to have their products +really hook into wide area networks, because they fear it will make their +data suppliers nervous. Moreover, until relatively recently, one had to +be rather adroit to run a full TCP/IP stack plus applications on a +PC-size machine, whereas nowadays it is becoming easier as PCs grow +bigger and faster. LYNCH also speculated that software providers had not +heard from their customers until the last year or so, or had not heard +from enough of their customers. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BESSER * Implications of disseminating images on the network; planning +the distribution of multimedia documents poses two critical +implementation problems * Layered approach represents the way to deal +with users' capabilities * Problems in platform design; file size and its +implications for networking * Transmission of megabyte size images +impractical * Compression and decompression at the user's end * Promising +trends for compression * A disadvantage of using X-Windows * A project at +the Smithsonian that mounts images on several networks * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Howard BESSER, School of Library and Information Science, University of +Pittsburgh, spoke primarily about multimedia, focusing on images and the +broad implications of disseminating them on the network. He argued that +planning the distribution of multimedia documents posed two critical +implementation problems, which he framed in the form of two questions: +1) What platform will one use and what hardware and software will users +have for viewing of the material? and 2) How can one deliver a +sufficiently robust set of information in an accessible format in a +reasonable amount of time? Depending on whether network or CD-ROM is the +medium used, this question raises different issues of storage, +compression, and transmission. + +Concerning the design of platforms (e.g., sound, gray scale, simple +color, etc.) and the various capabilities users may have, BESSER +maintained that a layered approach was the way to deal with users' +capabilities. A result would be that users with less powerful +workstations would simply have less functionality. He urged members of +the audience to advocate standards and accompanying software that handle +layered functionality across a wide variety of platforms. + +BESSER also addressed problems in platform design, namely, deciding how +large a machine to design for situations when the largest number of users +have the lowest level of the machine, and one desires higher +functionality. BESSER then proceeded to the question of file size and +its implications for networking. He discussed still images in the main. +For example, a digital color image that fills the screen of a standard +mega-pel workstation (Sun or Next) will require one megabyte of storage +for an eight-bit image or three megabytes of storage for a true color or +twenty-four-bit image. Lossless compression algorithms (that is, +computational procedures in which no data is lost in the process of +compressing [and decompressing] an image--the exact bit-representation is +maintained) might bring storage down to a third of a megabyte per image, +but not much further than that. The question of size makes it difficult +to fit an appropriately sized set of these images on a single disk or to +transmit them quickly enough on a network. + +With these full screen mega-pel images that constitute a third of a +megabyte, one gets 1,000-3,000 full-screen images on a one-gigabyte disk; +a standard CD-ROM represents approximately 60 percent of that. Storing +images the size of a PC screen (just 8 bit color) increases storage +capacity to 4,000-12,000 images per gigabyte; 60 percent of that gives +one the size of a CD-ROM, which in turn creates a major problem. One +cannot have full-screen, full-color images with lossless compression; one +must compress them or use a lower resolution. For megabyte-size images, +anything slower than a T-1 speed is impractical. For example, on a +fifty-six-kilobaud line, it takes three minutes to transfer a +one-megabyte file, if it is not compressed; and this speed assumes ideal +circumstances (no other user contending for network bandwidth). Thus, +questions of disk access, remote display, and current telephone +connection speed make transmission of megabyte-size images impractical. + +BESSER then discussed ways to deal with these large images, for example, +compression and decompression at the user's end. In this connection, the +issues of how much one is willing to lose in the compression process and +what image quality one needs in the first place are unknown. But what is +known is that compression entails some loss of data. BESSER urged that +more studies be conducted on image quality in different situations, for +example, what kind of images are needed for what kind of disciplines, and +what kind of image quality is needed for a browsing tool, an intermediate +viewing tool, and archiving. + +BESSER remarked two promising trends for compression: from a technical +perspective, algorithms that use what is called subjective redundancy +employ principles from visual psycho-physics to identify and remove +information from the image that the human eye cannot perceive; from an +interchange and interoperability perspective, the JPEG (i.e., Joint +Photographic Experts Group, an ISO standard) compression algorithms also +offer promise. These issues of compression and decompression, BESSER +argued, resembled those raised earlier concerning the design of different +platforms. Gauging the capabilities of potential users constitutes a +primary goal. BESSER advocated layering or separating the images from +the applications that retrieve and display them, to avoid tying them to +particular software. + +BESSER detailed several lessons learned from his work at Berkeley with +Imagequery, especially the advantages and disadvantages of using +X-Windows. In the latter category, for example, retrieval is tied +directly to one's data, an intolerable situation in the long run on a +networked system. Finally, BESSER described a project of Jim Wallace at +the Smithsonian Institution, who is mounting images in a extremely +rudimentary way on the Compuserv and Genie networks and is preparing to +mount them on America On Line. Although the average user takes over +thirty minutes to download these images (assuming a fairly fast modem), +nevertheless, images have been downloaded 25,000 times. + +BESSER concluded his talk with several comments on the business +arrangement between the Smithsonian and Compuserv. He contended that not +enough is known concerning the value of images. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating digitized photographic collections nearly +impossible except with large organizations like museums * Need for study +to determine quality of images users will tolerate * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief exchange between LESK and BESSER that followed, several +clarifications emerged. + +LESK argued that the photographers were far ahead of BESSER: It is +almost impossible to create such digitized photographic collections +except with large organizations like museums, because all the +photographic agencies have been going crazy about this and will not sign +licensing agreements on any sort of reasonable terms. LESK had heard +that National Geographic, for example, had tried to buy the right to use +some image in some kind of educational production for $100 per image, but +the photographers will not touch it. They want accounting and payment +for each use, which cannot be accomplished within the system. BESSER +responded that a consortium of photographers, headed by a former National +Geographic photographer, had started assembling its own collection of +electronic reproductions of images, with the money going back to the +cooperative. + +LESK contended that BESSER was unnecessarily pessimistic about multimedia +images, because people are accustomed to low-quality images, particularly +from video. BESSER urged the launching of a study to determine what +users would tolerate, what they would feel comfortable with, and what +absolutely is the highest quality they would ever need. Conceding that +he had adopted a dire tone in order to arouse people about the issue, +BESSER closed on a sanguine note by saying that he would not be in this +business if he did not think that things could be accomplished. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LARSEN * Issues of scalability and modularity * Geometric growth of the +Internet and the role played by layering * Basic functions sustaining +this growth * A library's roles and functions in a network environment * +Effects of implementation of the Z39.50 protocol for information +retrieval on the library system * The trade-off between volumes of data +and its potential usage * A snapshot of current trends * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ronald LARSEN, associate director for information technology, University +of Maryland at College Park, first addressed the issues of scalability +and modularity. He noted the difficulty of anticipating the effects of +orders-of-magnitude growth, reflecting on the twenty years of experience +with the Arpanet and Internet. Recalling the day's demonstrations of +CD-ROM and optical disk material, he went on to ask if the field has yet +learned how to scale new systems to enable delivery and dissemination +across large-scale networks. + +LARSEN focused on the geometric growth of the Internet from its inception +circa 1969 to the present, and the adjustments required to respond to +that rapid growth. To illustrate the issue of scalability, LARSEN +considered computer networks as including three generic components: +computers, network communication nodes, and communication media. Each +component scales (e.g., computers range from PCs to supercomputers; +network nodes scale from interface cards in a PC through sophisticated +routers and gateways; and communication media range from 2,400-baud +dial-up facilities through 4.5-Mbps backbone links, and eventually to +multigigabit-per-second communication lines), and architecturally, the +components are organized to scale hierarchically from local area networks +to international-scale networks. Such growth is made possible by +building layers of communication protocols, as BESSER pointed out. +By layering both physically and logically, a sense of scalability is +maintained from local area networks in offices, across campuses, through +bridges, routers, campus backbones, fiber-optic links, etc., up into +regional networks and ultimately into national and international +networks. + +LARSEN then illustrated the geometric growth over a two-year period-- +through September 1991--of the number of networks that comprise the +Internet. This growth has been sustained largely by the availability of +three basic functions: electronic mail, file transfer (ftp), and remote +log-on (telnet). LARSEN also reviewed the growth in the kind of traffic +that occurs on the network. Network traffic reflects the joint contributions +of a larger population of users and increasing use per user. Today one sees +serious applications involving moving images across the network--a rarity +ten years ago. LARSEN recalled and concurred with BESSER's main point +that the interesting problems occur at the application level. + +LARSEN then illustrated a model of a library's roles and functions in a +network environment. He noted, in particular, the placement of on-line +catalogues onto the network and patrons obtaining access to the library +increasingly through local networks, campus networks, and the Internet. +LARSEN supported LYNCH's earlier suggestion that we need to address +fundamental questions of networked information in order to build +environments that scale in the information sense as well as in the +physical sense. + +LARSEN supported the role of the library system as the access point into +the nation's electronic collections. Implementation of the Z39.50 +protocol for information retrieval would make such access practical and +feasible. For example, this would enable patrons in Maryland to search +California libraries, or other libraries around the world that are +conformant with Z39.50 in a manner that is familiar to University of +Maryland patrons. This client-server model also supports moving beyond +secondary content into primary content. (The notion of how one links +from secondary content to primary content, LARSEN said, represents a +fundamental problem that requires rigorous thought.) After noting +numerous network experiments in accessing full-text materials, including +projects supporting the ordering of materials across the network, LARSEN +revisited the issue of transmitting high-density, high-resolution color +images across the network and the large amounts of bandwidth they +require. He went on to address the bandwidth and synchronization +problems inherent in sending full-motion video across the network. + +LARSEN illustrated the trade-off between volumes of data in bytes or +orders of magnitude and the potential usage of that data. He discussed +transmission rates (particularly, the time it takes to move various forms +of information), and what one could do with a network supporting +multigigabit-per-second transmission. At the moment, the network +environment includes a composite of data-transmission requirements, +volumes and forms, going from steady to bursty (high-volume) and from +very slow to very fast. This aggregate must be considered in the design, +construction, and operation of multigigabyte networks. + +LARSEN's objective is to use the networks and library systems now being +constructed to increase access to resources wherever they exist, and +thus, to evolve toward an on-line electronic virtual library. + +LARSEN concluded by offering a snapshot of current trends: continuing +geometric growth in network capacity and number of users; slower +development of applications; and glacial development and adoption of +standards. The challenge is to design and develop each new application +system with network access and scalability in mind. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BROWNRIGG * Access to the Internet cannot be taken for granted * Packet +radio and the development of MELVYL in 1980-81 in the Division of Library +Automation at the University of California * Design criteria for packet +radio * A demonstration project in San Diego and future plans * Spread +spectrum * Frequencies at which the radios will run and plans to +reimplement the WAIS server software in the public domain * Need for an +infrastructure of radios that do not move around * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Edwin BROWNRIGG, executive director, Memex Research Institute, first +polled the audience in order to seek out regular users of the Internet as +well as those planning to use it some time in the future. With nearly +everybody in the room falling into one category or the other, BROWNRIGG +made a point re access, namely that numerous individuals, especially those +who use the Internet every day, take for granted their access to it, the +speeds with which they are connected, and how well it all works. +However, as BROWNRIGG discovered between 1987 and 1989 in Australia, +if one wants access to the Internet but cannot afford it or has some +physical boundary that prevents her or him from gaining access, it can +be extremely frustrating. He suggested that because of economics and +physical barriers we were beginning to create a world of haves and have-nots +in the process of scholarly communication, even in the United States. + +BROWNRIGG detailed the development of MELVYL in academic year 1980-81 in +the Division of Library Automation at the University of California, in +order to underscore the issue of access to the system, which at the +outset was extremely limited. In short, the project needed to build a +network, which at that time entailed use of satellite technology, that is, +putting earth stations on campus and also acquiring some terrestrial links +from the State of California's microwave system. The installation of +satellite links, however, did not solve the problem (which actually +formed part of a larger problem involving politics and financial resources). +For while the project team could get a signal onto a campus, it had no means +of distributing the signal throughout the campus. The solution involved +adopting a recent development in wireless communication called packet radio, +which combined the basic notion of packet-switching with radio. The project +used this technology to get the signal from a point on campus where it +came down, an earth station for example, into the libraries, because it +found that wiring the libraries, especially the older marble buildings, +would cost $2,000-$5,000 per terminal. + +BROWNRIGG noted that, ten years ago, the project had neither the public +policy nor the technology that would have allowed it to use packet radio +in any meaningful way. Since then much had changed. He proceeded to +detail research and development of the technology, how it is being +deployed in California, and what direction he thought it would take. +The design criteria are to produce a high-speed, one-time, low-cost, +high-quality, secure, license-free device (packet radio) that one can +plug in and play today, forget about it, and have access to the Internet. +By high speed, BROWNRIGG meant 1 megabyte and 1.5 megabytes. Those units +have been built, he continued, and are in the process of being +type-certified by an independent underwriting laboratory so that they can +be type-licensed by the Federal Communications Commission. As is the +case with citizens band, one will be able to purchase a unit and not have +to worry about applying for a license. + +The basic idea, BROWNRIGG elaborated, is to take high-speed radio data +transmission and create a backbone network that at certain strategic +points in the network will "gateway" into a medium-speed packet radio +(i.e., one that runs at 38.4 kilobytes), so that perhaps by 1994-1995 +people, like those in the audience for the price of a VCR could purchase +a medium-speed radio for the office or home, have full network connectivity +to the Internet, and partake of all its services, with no need for an FCC +license and no regular bill from the local common carrier. BROWNRIGG +presented several details of a demonstration project currently taking +place in San Diego and described plans, pending funding, to install a +full-bore network in the San Francisco area. This network will have 600 +nodes running at backbone speeds, and 100 of these nodes will be libraries, +which in turn will be the gateway ports to the 38.4 kilobyte radios that +will give coverage for the neighborhoods surrounding the libraries. + +BROWNRIGG next explained Part 15.247, a new rule within Title 47 of the +Code of Federal Regulations enacted by the FCC in 1985. This rule +challenged the industry, which has only now risen to the occasion, to +build a radio that would run at no more than one watt of output power and +use a fairly exotic method of modulating the radio wave called spread +spectrum. Spread spectrum in fact permits the building of networks so +that numerous data communications can occur simultaneously, without +interfering with each other, within the same wide radio channel. + +BROWNRIGG explained that the frequencies at which the radios would run +are very short wave signals. They are well above standard microwave and +radar. With a radio wave that small, one watt becomes a tremendous punch +per bit and thus makes transmission at reasonable speed possible. In +order to minimize the potential for congestion, the project is +undertaking to reimplement software which has been available in the +networking business and is taken for granted now, for example, TCP/IP, +routing algorithms, bridges, and gateways. In addition, the project +plans to take the WAIS server software in the public domain and +reimplement it so that one can have a WAIS server on a Mac instead of a +Unix machine. The Memex Research Institute believes that libraries, in +particular, will want to use the WAIS servers with packet radio. This +project, which has a team of about twelve people, will run through 1993 +and will include the 100 libraries already mentioned as well as other +professionals such as those in the medical profession, engineering, and +law. Thus, the need is to create an infrastructure of radios that do not +move around, which, BROWNRIGG hopes, will solve a problem not only for +libraries but for individuals who, by and large today, do not have access +to the Internet from their homes and offices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Project operating frequencies * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During a brief discussion period, which also concluded the day's +proceedings, BROWNRIGG stated that the project was operating in four +frequencies. The slow speed is operating at 435 megahertz, and it would +later go up to 920 megahertz. With the high-speed frequency, the +one-megabyte radios will run at 2.4 gigabits, and 1.5 will run at 5.7. +At 5.7, rain can be a factor, but it would have to be tropical rain, +unlike what falls in most parts of the United States. + + ****** + +SESSION IV. IMAGE CAPTURE, TEXT CAPTURE, OVERVIEW OF TEXT AND + IMAGE STORAGE FORMATS + +William HOOTON, vice president of operations, I-NET, moderated this session. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +KENNEY * Factors influencing development of CXP * Advantages of using +digital technology versus photocopy and microfilm * A primary goal of +CXP; publishing challenges * Characteristics of copies printed * Quality +of samples achieved in image capture * Several factors to be considered +in choosing scanning * Emphasis of CXP on timely and cost-effective +production of black-and-white printed facsimiles * Results of producing +microfilm from digital files * Advantages of creating microfilm * Details +concerning production * Costs * Role of digital technology in library +preservation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Anne KENNEY, associate director, Department of Preservation and +Conservation, Cornell University, opened her talk by observing that the +Cornell Xerox Project (CXP) has been guided by the assumption that the +ability to produce printed facsimiles or to replace paper with paper +would be important, at least for the present generation of users and +equipment. She described three factors that influenced development of +the project: 1) Because the project has emphasized the preservation of +deteriorating brittle books, the quality of what was produced had to be +sufficiently high to return a paper replacement to the shelf. CXP was +only interested in using: 2) a system that was cost-effective, which +meant that it had to be cost-competitive with the processes currently +available, principally photocopy and microfilm, and 3) new or currently +available product hardware and software. + +KENNEY described the advantages that using digital technology offers over +both photocopy and microfilm: 1) The potential exists to create a higher +quality reproduction of a deteriorating original than conventional +light-lens technology. 2) Because a digital image is an encoded +representation, it can be reproduced again and again with no resulting +loss of quality, as opposed to the situation with light-lens processes, +in which there is discernible difference between a second and a +subsequent generation of an image. 3) A digital image can be manipulated +in a number of ways to improve image capture; for example, Xerox has +developed a windowing application that enables one to capture a page +containing both text and illustrations in a manner that optimizes the +reproduction of both. (With light-lens technology, one must choose which +to optimize, text or the illustration; in preservation microfilming, the +current practice is to shoot an illustrated page twice, once to highlight +the text and the second time to provide the best capture for the +illustration.) 4) A digital image can also be edited, density levels +adjusted to remove underlining and stains, and to increase legibility for +faint documents. 5) On-screen inspection can take place at the time of +initial setup and adjustments made prior to scanning, factors that +substantially reduce the number of retakes required in quality control. + +A primary goal of CXP has been to evaluate the paper output printed on +the Xerox DocuTech, a high-speed printer that produces 600-dpi pages from +scanned images at a rate of 135 pages a minute. KENNEY recounted several +publishing challenges to represent faithful and legible reproductions of +the originals that the 600-dpi copy for the most part successfully +captured. For example, many of the deteriorating volumes in the project +were heavily illustrated with fine line drawings or halftones or came in +languages such as Japanese, in which the buildup of characters comprised +of varying strokes is difficult to reproduce at lower resolutions; a +surprising number of them came with annotations and mathematical +formulas, which it was critical to be able to duplicate exactly. + +KENNEY noted that 1) the copies are being printed on paper that meets the +ANSI standards for performance, 2) the DocuTech printer meets the machine +and toner requirements for proper adhesion of print to page, as described +by the National Archives, and thus 3) paper product is considered to be +the archival equivalent of preservation photocopy. + +KENNEY then discussed several samples of the quality achieved in the +project that had been distributed in a handout, for example, a copy of a +print-on-demand version of the 1911 Reed lecture on the steam turbine, +which contains halftones, line drawings, and illustrations embedded in +text; the first four loose pages in the volume compared the capture +capabilities of scanning to photocopy for a standard test target, the +IEEE standard 167A 1987 test chart. In all instances scanning proved +superior to photocopy, though only slightly more so in one. + +Conceding the simplistic nature of her review of the quality of scanning +to photocopy, KENNEY described it as one representation of the kinds of +settings that could be used with scanning capabilities on the equipment +CXP uses. KENNEY also pointed out that CXP investigated the quality +achieved with binary scanning only, and noted the great promise in gray +scale and color scanning, whose advantages and disadvantages need to be +examined. She argued further that scanning resolutions and file formats +can represent a complex trade-off between the time it takes to capture +material, file size, fidelity to the original, and on-screen display; and +printing and equipment availability. All these factors must be taken +into consideration. + +CXP placed primary emphasis on the production in a timely and +cost-effective manner of printed facsimiles that consisted largely of +black-and-white text. With binary scanning, large files may be +compressed efficiently and in a lossless manner (i.e., no data is lost in +the process of compressing [and decompressing] an image--the exact +bit-representation is maintained) using Group 4 CCITT (i.e., the French +acronym for International Consultative Committee for Telegraph and +Telephone) compression. CXP was getting compression ratios of about +forty to one. Gray-scale compression, which primarily uses JPEG, is much +less economical and can represent a lossy compression (i.e., not +lossless), so that as one compresses and decompresses, the illustration +is subtly changed. While binary files produce a high-quality printed +version, it appears 1) that other combinations of spatial resolution with +gray and/or color hold great promise as well, and 2) that gray scale can +represent a tremendous advantage for on-screen viewing. The quality +associated with binary and gray scale also depends on the equipment used. +For instance, binary scanning produces a much better copy on a binary +printer. + +Among CXP's findings concerning the production of microfilm from digital +files, KENNEY reported that the digital files for the same Reed lecture +were used to produce sample film using an electron beam recorder. The +resulting film was faithful to the image capture of the digital files, +and while CXP felt that the text and image pages represented in the Reed +lecture were superior to that of the light-lens film, the resolution +readings for the 600 dpi were not as high as standard microfilming. +KENNEY argued that the standards defined for light-lens technology are +not totally transferable to a digital environment. Moreover, they are +based on definition of quality for a preservation copy. Although making +this case will prove to be a long, uphill struggle, CXP plans to continue +to investigate the issue over the course of the next year. + +KENNEY concluded this portion of her talk with a discussion of the +advantages of creating film: it can serve as a primary backup and as a +preservation master to the digital file; it could then become the print +or production master and service copies could be paper, film, optical +disks, magnetic media, or on-screen display. + +Finally, KENNEY presented details re production: + + * Development and testing of a moderately-high resolution production + scanning workstation represented a third goal of CXP; to date, 1,000 + volumes have been scanned, or about 300,000 images. + + * The resulting digital files are stored and used to produce + hard-copy replacements for the originals and additional prints on + demand; although the initial costs are high, scanning technology + offers an affordable means for reformatting brittle material. + + * A technician in production mode can scan 300 pages per hour when + performing single-sheet scanning, which is a necessity when working + with truly brittle paper; this figure is expected to increase + significantly with subsequent iterations of the software from Xerox; + a three-month time-and-cost study of scanning found that the average + 300-page book would take about an hour and forty minutes to scan + (this figure included the time for setup, which involves keying in + primary bibliographic data, going into quality control mode to + define page size, establishing front-to-back registration, and + scanning sample pages to identify a default range of settings for + the entire book--functions not dissimilar to those performed by + filmers or those preparing a book for photocopy). + + * The final step in the scanning process involved rescans, which + happily were few and far between, representing well under 1 percent + of the total pages scanned. + +In addition to technician time, CXP costed out equipment, amortized over +four years, the cost of storing and refreshing the digital files every +four years, and the cost of printing and binding, book-cloth binding, a +paper reproduction. The total amounted to a little under $65 per single +300-page volume, with 30 percent overhead included--a figure competitive +with the prices currently charged by photocopy vendors. + +Of course, with scanning, in addition to the paper facsimile, one is left +with a digital file from which subsequent copies of the book can be +produced for a fraction of the cost of photocopy, with readers afforded +choices in the form of these copies. + +KENNEY concluded that digital technology offers an electronic means for a +library preservation effort to pay for itself. If a brittle-book program +included the means of disseminating reprints of books that are in demand +by libraries and researchers alike, the initial investment in capture +could be recovered and used to preserve additional but less popular +books. She disclosed that an economic model for a self-sustaining +program could be developed for CXP's report to the Commission on +Preservation and Access (CPA). + +KENNEY stressed that the focus of CXP has been on obtaining high quality +in a production environment. The use of digital technology is viewed as +an affordable alternative to other reformatting options. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ANDRE * Overview and history of NATDP * Various agricultural CD-ROM +products created inhouse and by service bureaus * Pilot project on +Internet transmission * Additional products in progress * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Pamela ANDRE, associate director for automation, National Agricultural +Text Digitizing Program (NATDP), National Agricultural Library (NAL), +presented an overview of NATDP, which has been underway at NAL the last +four years, before Judith ZIDAR discussed the technical details. ANDRE +defined agricultural information as a broad range of material going from +basic and applied research in the hard sciences to the one-page pamphlets +that are distributed by the cooperative state extension services on such +things as how to grow blueberries. + +NATDP began in late 1986 with a meeting of representatives from the +land-grant library community to deal with the issue of electronic +information. NAL and forty-five of these libraries banded together to +establish this project--to evaluate the technology for converting what +were then source documents in paper form into electronic form, to provide +access to that digital information, and then to distribute it. +Distributing that material to the community--the university community as +well as the extension service community, potentially down to the county +level--constituted the group's chief concern. + +Since January 1988 (when the microcomputer-based scanning system was +installed at NAL), NATDP has done a variety of things, concerning which +ZIDAR would provide further details. For example, the first technology +considered in the project's discussion phase was digital videodisc, which +indicates how long ago it was conceived. + +Over the four years of this project, four separate CD-ROM products on +four different agricultural topics were created, two at a +scanning-and-OCR station installed at NAL, and two by service bureaus. +Thus, NATDP has gained comparative information in terms of those relative +costs. Each of these products contained the full ASCII text as well as +page images of the material, or between 4,000 and 6,000 pages of material +on these disks. Topics included aquaculture, food, agriculture and +science (i.e., international agriculture and research), acid rain, and +Agent Orange, which was the final product distributed (approximately +eighteen months before the Workshop). + +The third phase of NATDP focused on delivery mechanisms other than +CD-ROM. At the suggestion of Clifford LYNCH, who was a technical +consultant to the project at this point, NATDP became involved with the +Internet and initiated a project with the help of North Carolina State +University, in which fourteen of the land-grant university libraries are +transmitting digital images over the Internet in response to interlibrary +loan requests--a topic for another meeting. At this point, the pilot +project had been completed for about a year and the final report would be +available shortly after the Workshop. In the meantime, the project's +success had led to its extension. (ANDRE noted that one of the first +things done under the program title was to select a retrieval package to +use with subsequent products; Windows Personal Librarian was the package +of choice after a lengthy evaluation.) + +Three additional products had been planned and were in progress: + + 1) An arrangement with the American Society of Agronomy--a + professional society that has published the Agronomy Journal since + about 1908--to scan and create bit-mapped images of its journal. + ASA granted permission first to put and then to distribute this + material in electronic form, to hold it at NAL, and to use these + electronic images as a mechanism to deliver documents or print out + material for patrons, among other uses. Effectively, NAL has the + right to use this material in support of its program. + (Significantly, this arrangement offers a potential cooperative + model for working with other professional societies in agriculture + to try to do the same thing--put the journals of particular interest + to agriculture research into electronic form.) + + 2) An extension of the earlier product on aquaculture. + + 3) The George Washington Carver Papers--a joint project with + Tuskegee University to scan and convert from microfilm some 3,500 + images of Carver's papers, letters, and drawings. + +It was anticipated that all of these products would appear no more than +six months after the Workshop. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * (A separate arena for scanning) * Steps in creating a database * +Image capture, with and without performing OCR * Keying in tracking data +* Scanning, with electronic and manual tracking * Adjustments during +scanning process * Scanning resolutions * Compression * De-skewing and +filtering * Image capture from microform: the papers and letters of +George Washington Carver * Equipment used for a scanning system * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), illustrated the technical +details of NATDP, including her primary responsibility, scanning and +creating databases on a topic and putting them on CD-ROM. + +(ZIDAR remarked a separate arena from the CD-ROM projects, although the +processing of the material is nearly identical, in which NATDP is also +scanning material and loading it on a Next microcomputer, which in turn +is linked to NAL's integrated library system. Thus, searches in NAL's +bibliographic database will enable people to pull up actual page images +and text for any documents that have been entered.) + +In accordance with the session's topic, ZIDAR focused her illustrated +talk on image capture, offering a primer on the three main steps in the +process: 1) assemble the printed publications; 2) design the database +(database design occurs in the process of preparing the material for +scanning; this step entails reviewing and organizing the material, +defining the contents--what will constitute a record, what kinds of +fields will be captured in terms of author, title, etc.); 3) perform a +certain amount of markup on the paper publications. NAL performs this +task record by record, preparing work sheets or some other sort of +tracking material and designing descriptors and other enhancements to be +added to the data that will not be captured from the printed publication. +Part of this process also involves determining NATDP's file and directory +structure: NATDP attempts to avoid putting more than approximately 100 +images in a directory, because placing more than that on a CD-ROM would +reduce the access speed. + +This up-front process takes approximately two weeks for a +6,000-7,000-page database. The next step is to capture the page images. +How long this process takes is determined by the decision whether or not +to perform OCR. Not performing OCR speeds the process, whereas text +capture requires greater care because of the quality of the image: it +has to be straighter and allowance must be made for text on a page, not +just for the capture of photographs. + +NATDP keys in tracking data, that is, a standard bibliographic record +including the title of the book and the title of the chapter, which will +later either become the access information or will be attached to the +front of a full-text record so that it is searchable. + +Images are scanned from a bound or unbound publication, chiefly from +bound publications in the case of NATDP, however, because often they are +the only copies and the publications are returned to the shelves. NATDP +usually scans one record at a time, because its database tracking system +tracks the document in that way and does not require further logical +separating of the images. After performing optical character +recognition, NATDP moves the images off the hard disk and maintains a +volume sheet. Though the system tracks electronically, all the +processing steps are also tracked manually with a log sheet. + +ZIDAR next illustrated the kinds of adjustments that one can make when +scanning from paper and microfilm, for example, redoing images that need +special handling, setting for dithering or gray scale, and adjusting for +brightness or for the whole book at one time. + +NATDP is scanning at 300 dots per inch, a standard scanning resolution. +Though adequate for capturing text that is all of a standard size, 300 +dpi is unsuitable for any kind of photographic material or for very small +text. Many scanners allow for different image formats, TIFF, of course, +being a de facto standard. But if one intends to exchange images with +other people, the ability to scan other image formats, even if they are +less common, becomes highly desirable. + +CCITT Group 4 is the standard compression for normal black-and-white +images, JPEG for gray scale or color. ZIDAR recommended 1) using the +standard compressions, particularly if one attempts to make material +available and to allow users to download images and reuse them from +CD-ROMs; and 2) maintaining the ability to output an uncompressed image, +because in image exchange uncompressed images are more likely to be able +to cross platforms. + +ZIDAR emphasized the importance of de-skewing and filtering as +requirements on NATDP's upgraded system. For instance, scanning bound +books, particularly books published by the federal government whose pages +are skewed, and trying to scan them straight if OCR is to be performed, +is extremely time-consuming. The same holds for filtering of +poor-quality or older materials. + +ZIDAR described image capture from microform, using as an example three +reels from a sixty-seven-reel set of the papers and letters of George +Washington Carver that had been produced by Tuskegee University. These +resulted in approximately 3,500 images, which NATDP had had scanned by +its service contractor, Science Applications International Corporation +(SAIC). NATDP also created bibliographic records for access. (NATDP did +not have such specialized equipment as a microfilm scanner. + +Unfortunately, the process of scanning from microfilm was not an +unqualified success, ZIDAR reported: because microfilm frame sizes vary, +occasionally some frames were missed, which without spending much time +and money could not be recaptured. + +OCR could not be performed from the scanned images of the frames. The +bleeding in the text simply output text, when OCR was run, that could not +even be edited. NATDP tested for negative versus positive images, +landscape versus portrait orientation, and single- versus dual-page +microfilm, none of which seemed to affect the quality of the image; but +also on none of them could OCR be performed. + +In selecting the microfilm they would use, therefore, NATDP had other +factors in mind. ZIDAR noted two factors that influenced the quality of +the images: 1) the inherent quality of the original and 2) the amount of +size reduction on the pages. + +The Carver papers were selected because they are informative and visually +interesting, treat a single subject, and are valuable in their own right. +The images were scanned and divided into logical records by SAIC, then +delivered, and loaded onto NATDP's system, where bibliographic +information taken directly from the images was added. Scanning was +completed in summer 1991 and by the end of summer 1992 the disk was +scheduled to be published. + +Problems encountered during processing included the following: Because +the microfilm scanning had to be done in a batch, adjustment for +individual page variations was not possible. The frame size varied on +account of the nature of the material, and therefore some of the frames +were missed while others were just partial frames. The only way to go +back and capture this material was to print out the page with the +microfilm reader from the missing frame and then scan it in from the +page, which was extremely time-consuming. The quality of the images +scanned from the printout of the microfilm compared unfavorably with that +of the original images captured directly from the microfilm. The +inability to perform OCR also was a major disappointment. At the time, +computer output microfilm was unavailable to test. + +The equipment used for a scanning system was the last topic addressed by +ZIDAR. The type of equipment that one would purchase for a scanning +system included: a microcomputer, at least a 386, but preferably a 486; +a large hard disk, 380 megabyte at minimum; a multi-tasking operating +system that allows one to run some things in batch in the background +while scanning or doing text editing, for example, Unix or OS/2 and, +theoretically, Windows; a high-speed scanner and scanning software that +allows one to make the various adjustments mentioned earlier; a +high-resolution monitor (150 dpi ); OCR software and hardware to perform +text recognition; an optical disk subsystem on which to archive all the +images as the processing is done; file management and tracking software. + +ZIDAR opined that the software one purchases was more important than the +hardware and might also cost more than the hardware, but it was likely to +prove critical to the success or failure of one's system. In addition to +a stand-alone scanning workstation for image capture, then, text capture +requires one or two editing stations networked to this scanning station +to perform editing. Editing the text takes two or three times as long as +capturing the images. + +Finally, ZIDAR stressed the importance of buying an open system that allows +for more than one vendor, complies with standards, and can be upgraded. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WATERS *Yale University Library's master plan to convert microfilm to +digital imagery (POB) * The place of electronic tools in the library of +the future * The uses of images and an image library * Primary input from +preservation microfilm * Features distinguishing POB from CXP and key +hypotheses guiding POB * Use of vendor selection process to facilitate +organizational work * Criteria for selecting vendor * Finalists and +results of process for Yale * Key factor distinguishing vendors * +Components, design principles, and some estimated costs of POB * Role of +preservation materials in developing imaging market * Factors affecting +quality and cost * Factors affecting the usability of complex documents +in image form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Donald WATERS, head of the Systems Office, Yale University Library, +reported on the progress of a master plan for a project at Yale to +convert microfilm to digital imagery, Project Open Book (POB). Stating +that POB was in an advanced stage of planning, WATERS detailed, in +particular, the process of selecting a vendor partner and several key +issues under discussion as Yale prepares to move into the project itself. +He commented first on the vision that serves as the context of POB and +then described its purpose and scope. + +WATERS sees the library of the future not necessarily as an electronic +library but as a place that generates, preserves, and improves for its +clients ready access to both intellectual and physical recorded +knowledge. Electronic tools must find a place in the library in the +context of this vision. Several roles for electronic tools include +serving as: indirect sources of electronic knowledge or as "finding" +aids (the on-line catalogues, the article-level indices, registers for +documents and archives); direct sources of recorded knowledge; full-text +images; and various kinds of compound sources of recorded knowledge (the +so-called compound documents of Hypertext, mixed text and image, +mixed-text image format, and multimedia). + +POB is looking particularly at images and an image library, the uses to +which images will be put (e.g., storage, printing, browsing, and then use +as input for other processes), OCR as a subsequent process to image +capture, or creating an image library, and also possibly generating +microfilm. + +While input will come from a variety of sources, POB is considering +especially input from preservation microfilm. A possible outcome is that +the film and paper which provide the input for the image library +eventually may go off into remote storage, and that the image library may +be the primary access tool. + +The purpose and scope of POB focus on imaging. Though related to CXP, +POB has two features which distinguish it: 1) scale--conversion of +10,000 volumes into digital image form; and 2) source--conversion from +microfilm. Given these features, several key working hypotheses guide +POB, including: 1) Since POB is using microfilm, it is not concerned with +the image library as a preservation medium. 2) Digital imagery can improve +access to recorded knowledge through printing and network distribution at +a modest incremental cost of microfilm. 3) Capturing and storing documents +in a digital image form is necessary to further improvements in access. +(POB distinguishes between the imaging, digitizing process and OCR, +which at this stage it does not plan to perform.) + +Currently in its first or organizational phase, POB found that it could +use a vendor selection process to facilitate a good deal of the +organizational work (e.g., creating a project team and advisory board, +confirming the validity of the plan, establishing the cost of the project +and a budget, selecting the materials to convert, and then raising the +necessary funds). + +POB developed numerous selection criteria, including: a firm committed +to image-document management, the ability to serve as systems integrator +in a large-scale project over several years, interest in developing the +requisite software as a standard rather than a custom product, and a +willingness to invest substantial resources in the project itself. + +Two vendors, DEC and Xerox, were selected as finalists in October 1991, +and with the support of the Commission on Preservation and Access, each +was commissioned to generate a detailed requirements analysis for the +project and then to submit a formal proposal for the completion of the +project, which included a budget and costs. The terms were that POB would +pay the loser. The results for Yale of involving a vendor included: +broad involvement of Yale staff across the board at a relatively low +cost, which may have long-term significance in carrying out the project +(twenty-five to thirty university people are engaged in POB); better +understanding of the factors that affect corporate response to markets +for imaging products; a competitive proposal; and a more sophisticated +view of the imaging markets. + +The most important factor that distinguished the vendors under +consideration was their identification with the customer. The size and +internal complexity of the company also was an important factor. POB was +looking at large companies that had substantial resources. In the end, +the process generated for Yale two competitive proposals, with Xerox's +the clear winner. WATERS then described the components of the proposal, +the design principles, and some of the costs estimated for the process. + +Components are essentially four: a conversion subsystem, a +network-accessible storage subsystem for 10,000 books (and POB expects +200 to 600 dpi storage), browsing stations distributed on the campus +network, and network access to the image printers. + +Among the design principles, POB wanted conversion at the highest +possible resolution. Assuming TIFF files, TIFF files with Group 4 +compression, TCP/IP, and ethernet network on campus, POB wanted a +client-server approach with image documents distributed to the +workstations and made accessible through native workstation interfaces +such as Windows. POB also insisted on a phased approach to +implementation: 1) a stand-alone, single-user, low-cost entry into the +business with a workstation focused on conversion and allowing POB to +explore user access; 2) movement into a higher-volume conversion with +network-accessible storage and multiple access stations; and 3) a +high-volume conversion, full-capacity storage, and multiple browsing +stations distributed throughout the campus. + +The costs proposed for start-up assumed the existence of the Yale network +and its two DocuTech image printers. Other start-up costs are estimated +at $1 million over the three phases. At the end of the project, the annual +operating costs estimated primarily for the software and hardware proposed +come to about $60,000, but these exclude costs for labor needed in the +conversion process, network and printer usage, and facilities management. + +Finally, the selection process produced for Yale a more sophisticated +view of the imaging markets: the management of complex documents in +image form is not a preservation problem, not a library problem, but a +general problem in a broad, general industry. Preservation materials are +useful for developing that market because of the qualities of the +material. For example, much of it is out of copyright. The resolution +of key issues such as the quality of scanning and image browsing also +will affect development of that market. + +The technology is readily available but changing rapidly. In this +context of rapid change, several factors affect quality and cost, to +which POB intends to pay particular attention, for example, the various +levels of resolution that can be achieved. POB believes it can bring +resolution up to 600 dpi, but an interpolation process from 400 to 600 is +more likely. The variation quality in microfilm will prove to be a +highly important factor. POB may reexamine the standards used to film in +the first place by looking at this process as a follow-on to microfilming. + +Other important factors include: the techniques available to the +operator for handling material, the ways of integrating quality control +into the digitizing work flow, and a work flow that includes indexing and +storage. POB's requirement was to be able to deal with quality control +at the point of scanning. Thus, thanks to Xerox, POB anticipates having +a mechanism which will allow it not only to scan in batch form, but to +review the material as it goes through the scanner and control quality +from the outset. + +The standards for measuring quality and costs depend greatly on the uses +of the material, including subsequent OCR, storage, printing, and +browsing. But especially at issue for POB is the facility for browsing. +This facility, WATERS said, is perhaps the weakest aspect of imaging +technology and the most in need of development. + +A variety of factors affect the usability of complex documents in image +form, among them: 1) the ability of the system to handle the full range +of document types, not just monographs but serials, multi-part +monographs, and manuscripts; 2) the location of the database of record +for bibliographic information about the image document, which POB wants +to enter once and in the most useful place, the on-line catalog; 3) a +document identifier for referencing the bibliographic information in one +place and the images in another; 4) the technique for making the basic +internal structure of the document accessible to the reader; and finally, +5) the physical presentation on the CRT of those documents. POB is ready +to complete this phase now. One last decision involves deciding which +material to scan. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * TIFF files constitute de facto standard * NARA's experience +with image conversion software and text conversion * RFC 1314 * +Considerable flux concerning available hardware and software solutions * +NAL through-put rate during scanning * Window management questions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the question-and-answer period that followed WATERS's presentation, +the following points emerged: + + * ZIDAR's statement about using TIFF files as a standard meant de + facto standard. This is what most people use and typically exchange + with other groups, across platforms, or even occasionally across + display software. + + * HOLMES commented on the unsuccessful experience of NARA in + attempting to run image-conversion software or to exchange between + applications: What are supposedly TIFF files go into other software + that is supposed to be able to accept TIFF but cannot recognize the + format and cannot deal with it, and thus renders the exchange + useless. Re text conversion, he noted the different recognition + rates obtained by substituting the make and model of scanners in + NARA's recent test of an "intelligent" character-recognition product + for a new company. In the selection of hardware and software, + HOLMES argued, software no longer constitutes the overriding factor + it did until about a year ago; rather it is perhaps important to + look at both now. + + * Danny Cohen and Alan Katz of the University of Southern California + Information Sciences Institute began circulating as an Internet RFC + (RFC 1314) about a month ago a standard for a TIFF interchange + format for Internet distribution of monochrome bit-mapped images, + which LYNCH said he believed would be used as a de facto standard. + + * FLEISCHHAUER's impression from hearing these reports and thinking + about AM's experience was that there is considerable flux concerning + available hardware and software solutions. HOOTON agreed and + commented at the same time on ZIDAR's statement that the equipment + employed affects the results produced. One cannot draw a complete + conclusion by saying it is difficult or impossible to perform OCR + from scanning microfilm, for example, with that device, that set of + parameters, and system requirements, because numerous other people + are accomplishing just that, using other components, perhaps. + HOOTON opined that both the hardware and the software were highly + important. Most of the problems discussed today have been solved in + numerous different ways by other people. Though it is good to be + cognizant of various experiences, this is not to say that it will + always be thus. + + * At NAL, the through-put rate of the scanning process for paper, + page by page, performing OCR, ranges from 300 to 600 pages per day; + not performing OCR is considerably faster, although how much faster + is not known. This is for scanning from bound books, which is much + slower. + + * WATERS commented on window management questions: DEC proposed an + X-Windows solution which was problematical for two reasons. One was + POB's requirement to be able to manipulate images on the workstation + and bring them down to the workstation itself and the other was + network usage. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +THOMA * Illustration of deficiencies in scanning and storage process * +Image quality in this process * Different costs entailed by better image +quality * Techniques for overcoming various de-ficiencies: fixed +thresholding, dynamic thresholding, dithering, image merge * Page edge +effects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +George THOMA, chief, Communications Engineering Branch, National Library +of Medicine (NLM), illustrated several of the deficiencies discussed by +the previous speakers. He introduced the topic of special problems by +noting the advantages of electronic imaging. For example, it is regenerable +because it is a coded file, and real-time quality control is possible with +electronic capture, whereas in photographic capture it is not. + +One of the difficulties discussed in the scanning and storage process was +image quality which, without belaboring the obvious, means different +things for maps, medical X-rays, or broadcast television. In the case of +documents, THOMA said, image quality boils down to legibility of the +textual parts, and fidelity in the case of gray or color photo print-type +material. Legibility boils down to scan density, the standard in most +cases being 300 dpi. Increasing the resolution with scanners that +perform 600 or 1200 dpi, however, comes at a cost. + +Better image quality entails at least four different kinds of costs: 1) +equipment costs, because the CCD (i.e., charge-couple device) with +greater number of elements costs more; 2) time costs that translate to +the actual capture costs, because manual labor is involved (the time is +also dependent on the fact that more data has to be moved around in the +machine in the scanning or network devices that perform the scanning as +well as the storage); 3) media costs, because at high resolutions larger +files have to be stored; and 4) transmission costs, because there is just +more data to be transmitted. + +But while resolution takes care of the issue of legibility in image +quality, other deficiencies have to do with contrast and elements on the +page scanned or the image that needed to be removed or clarified. Thus, +THOMA proceeded to illustrate various deficiencies, how they are +manifested, and several techniques to overcome them. + +Fixed thresholding was the first technique described, suitable for +black-and-white text, when the contrast does not vary over the page. One +can have many different threshold levels in scanning devices. Thus, +THOMA offered an example of extremely poor contrast, which resulted from +the fact that the stock was a heavy red. This is the sort of image that +when microfilmed fails to provide any legibility whatsoever. Fixed +thresholding is the way to change the black-to-red contrast to the +desired black-to-white contrast. + +Other examples included material that had been browned or yellowed by +age. This was also a case of contrast deficiency, and correction was +done by fixed thresholding. A final example boils down to the same +thing, slight variability, but it is not significant. Fixed thresholding +solves this problem as well. The microfilm equivalent is certainly legible, +but it comes with dark areas. Though THOMA did not have a slide of the +microfilm in this case, he did show the reproduced electronic image. + +When one has variable contrast over a page or the lighting over the page +area varies, especially in the case where a bound volume has light +shining on it, the image must be processed by a dynamic thresholding +scheme. One scheme, dynamic averaging, allows the threshold level not to +be fixed but to be recomputed for every pixel from the neighboring +characteristics. The neighbors of a pixel determine where the threshold +should be set for that pixel. + +THOMA showed an example of a page that had been made deficient by a +variety of techniques, including a burn mark, coffee stains, and a yellow +marker. Application of a fixed-thresholding scheme, THOMA argued, might +take care of several deficiencies on the page but not all of them. +Performing the calculation for a dynamic threshold setting, however, +removes most of the deficiencies so that at least the text is legible. + +Another problem is representing a gray level with black-and-white pixels +by a process known as dithering or electronic screening. But dithering +does not provide good image quality for pure black-and-white textual +material. THOMA illustrated this point with examples. Although its +suitability for photoprint is the reason for electronic screening or +dithering, it cannot be used for every compound image. In the document +that was distributed by CXP, THOMA noticed that the dithered image of the +IEEE test chart evinced some deterioration in the text. He presented an +extreme example of deterioration in the text in which compounded +documents had to be set right by other techniques. The technique +illustrated by the present example was an image merge in which the page +is scanned twice and the settings go from fixed threshold to the +dithering matrix; the resulting images are merged to give the best +results with each technique. + +THOMA illustrated how dithering is also used in nonphotographic or +nonprint materials with an example of a grayish page from a medical text, +which was reproduced to show all of the gray that appeared in the +original. Dithering provided a reproduction of all the gray in the +original of another example from the same text. + +THOMA finally illustrated the problem of bordering, or page-edge, +effects. Books and bound volumes that are placed on a photocopy machine +or a scanner produce page-edge effects that are undesirable for two +reasons: 1) the aesthetics of the image; after all, if the image is to +be preserved, one does not necessarily want to keep all of its +deficiencies; 2) compression (with the bordering problem THOMA +illustrated, the compression ratio deteriorated tremendously). One way +to eliminate this more serious problem is to have the operator at the +point of scanning window the part of the image that is desirable and +automatically turn all of the pixels out of that picture to white. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * AM's experience with scanning bound materials * Dithering +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +reported AM's experience with scanning bound materials, which he likened +to the problems involved in using photocopying machines. Very few +devices in the industry offer book-edge scanning, let alone book cradles. +The problem may be unsolvable, FLEISCHHAUER said, because a large enough +market does not exist for a preservation-quality scanner. AM is using a +Kurzweil scanner, which is a book-edge scanner now sold by Xerox. + +Devoting the remainder of his brief presentation to dithering, +FLEISCHHAUER related AM's experience with a contractor who was using +unsophisticated equipment and software to reduce moire patterns from +printed halftones. AM took the same image and used the dithering +algorithm that forms part of the same Kurzweil Xerox scanner; it +disguised moire patterns much more effectively. + +FLEISCHHAUER also observed that dithering produces a binary file which is +useful for numerous purposes, for example, printing it on a laser printer +without having to "re-halftone" it. But it tends to defeat efficient +compression, because the very thing that dithers to reduce moire patterns +also tends to work against compression schemes. AM thought the +difference in image quality was worth it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Relative use as a criterion for POB's selection of books to +be converted into digital form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period, WATERS noted that one of the criteria for +selecting books among the 10,000 to be converted into digital image form +would be how much relative use they would receive--a subject still +requiring evaluation. The challenge will be to understand whether +coherent bodies of material will increase usage or whether POB should +seek material that is being used, scan that, and make it more accessible. +POB might decide to digitize materials that are already heavily used, in +order to make them more accessible and decrease wear on them. Another +approach would be to provide a large body of intellectually coherent +material that may be used more in digital form than it is currently used +in microfilm. POB would seek material that was out of copyright. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BARONAS * Origin and scope of AIIM * Types of documents produced in +AIIM's standards program * Domain of AIIM's standardization work * AIIM's +structure * TC 171 and MS23 * Electronic image management standards * +Categories of EIM standardization where AIIM standards are being +developed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Jean BARONAS, senior manager, Department of Standards and Technology, +Association for Information and Image Management (AIIM), described the +not-for-profit association and the national and international programs +for standardization in which AIIM is active. + +Accredited for twenty-five years as the nation's standards development +organization for document image management, AIIM began life in a library +community developing microfilm standards. Today the association +maintains both its library and business-image management standardization +activities--and has moved into electronic image-management +standardization (EIM). + +BARONAS defined the program's scope. AIIM deals with: 1) the +terminology of standards and of the technology it uses; 2) methods of +measurement for the systems, as well as quality; 3) methodologies for +users to evaluate and measure quality; 4) the features of apparatus used +to manage and edit images; and 5) the procedures used to manage images. + +BARONAS noted that three types of documents are produced in the AIIM +standards program: the first two, accredited by the American National +Standards Institute (ANSI), are standards and standard recommended +practices. Recommended practices differ from standards in that they +contain more tutorial information. A technical report is not an ANSI +standard. Because AIIM's policies and procedures for developing +standards are approved by ANSI, its standards are labeled ANSI/AIIM, +followed by the number and title of the standard. + +BARONAS then illustrated the domain of AIIM's standardization work. For +example, AIIM is the administrator of the U.S. Technical Advisory Group +(TAG) to the International Standards Organization's (ISO) technical +committee, TC l7l Micrographics and Optical Memories for Document and +Image Recording, Storage, and Use. AIIM officially works through ANSI in +the international standardization process. + +BARONAS described AIIM's structure, including its board of directors, its +standards board of twelve individuals active in the image-management +industry, its strategic planning and legal admissibility task forces, and +its National Standards Council, which is comprised of the members of a +number of organizations who vote on every AIIM standard before it is +published. BARONAS pointed out that AIIM's liaisons deal with numerous +other standards developers, including the optical disk community, office +and publishing systems, image-codes-and-character set committees, and the +National Information Standards Organization (NISO). + +BARONAS illustrated the procedures of TC l7l, which covers all aspects of +image management. When AIIM's national program has conceptualized a new +project, it is usually submitted to the international level, so that the +member countries of TC l7l can simultaneously work on the development of +the standard or the technical report. BARONAS also illustrated a classic +microfilm standard, MS23, which deals with numerous imaging concepts that +apply to electronic imaging. Originally developed in the l970s, revised +in the l980s, and revised again in l991, this standard is scheduled for +another revision. MS23 is an active standard whereby users may propose +new density ranges and new methods of evaluating film images in the +standard's revision. + +BARONAS detailed several electronic image-management standards, for +instance, ANSI/AIIM MS44, a quality-control guideline for scanning 8.5" +by 11" black-and-white office documents. This standard is used with the +IEEE fax image--a continuous tone photographic image with gray scales, +text, and several continuous tone pictures--and AIIM test target number +2, a representative document used in office document management. + +BARONAS next outlined the four categories of EIM standardization in which +AIIM standards are being developed: transfer and retrieval, evaluation, +optical disc and document scanning applications, and design and +conversion of documents. She detailed several of the main projects of +each: 1) in the category of image transfer and retrieval, a bi-level +image transfer format, ANSI/AIIM MS53, which is a proposed standard that +describes a file header for image transfer between unlike systems when +the images are compressed using G3 and G4 compression; 2) the category of +image evaluation, which includes the AIIM-proposed TR26 tutorial on image +resolution (this technical report will treat the differences and +similarities between classical or photographic and electronic imaging); +3) design and conversion, which includes a proposed technical report +called "Forms Design Optimization for EIM" (this report considers how +general-purpose business forms can be best designed so that scanning is +optimized; reprographic characteristics such as type, rules, background, +tint, and color will likewise be treated in the technical report); 4) +disk and document scanning applications includes a project a) on planning +platters and disk management, b) on generating an application profile for +EIM when images are stored and distributed on CD-ROM, and c) on +evaluating SCSI2, and how a common command set can be generated for SCSI2 +so that document scanners are more easily integrated. (ANSI/AIIM MS53 +will also apply to compressed images.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BATTIN * The implications of standards for preservation * A major +obstacle to successful cooperation * A hindrance to access in the digital +environment * Standards a double-edged sword for those concerned with the +preservation of the human record * Near-term prognosis for reliable +archival standards * Preservation concerns for electronic media * Need +for reconceptualizing our preservation principles * Standards in the real +world and the politics of reproduction * Need to redefine the concept of +archival and to begin to think in terms of life cycles * Cooperation and +the La Guardia Eight * Concerns generated by discussions on the problems +of preserving text and image * General principles to be adopted in a +world without standards * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Patricia BATTIN, president, the Commission on Preservation and Access +(CPA), addressed the implications of standards for preservation. She +listed several areas where the library profession and the analog world of +the printed book had made enormous contributions over the past hundred +years--for example, in bibliographic formats, binding standards, and, most +important, in determining what constitutes longevity or archival quality. + +Although standards have lightened the preservation burden through the +development of national and international collaborative programs, +nevertheless, a pervasive mistrust of other people's standards remains a +major obstacle to successful cooperation, BATTIN said. + +The zeal to achieve perfection, regardless of the cost, has hindered +rather than facilitated access in some instances, and in the digital +environment, where no real standards exist, has brought an ironically +just reward. + +BATTIN argued that standards are a double-edged sword for those concerned +with the preservation of the human record, that is, the provision of +access to recorded knowledge in a multitude of media as far into the +future as possible. Standards are essential to facilitate +interconnectivity and access, but, BATTIN said, as LYNCH pointed out +yesterday, if set too soon they can hinder creativity, expansion of +capability, and the broadening of access. The characteristics of +standards for digital imagery differ radically from those for analog +imagery. And the nature of digital technology implies continuing +volatility and change. To reiterate, precipitous standard-setting can +inhibit creativity, but delayed standard-setting results in chaos. + +Since in BATTIN'S opinion the near-term prognosis for reliable archival +standards, as defined by librarians in the analog world, is poor, two +alternatives remain: standing pat with the old technology, or +reconceptualizing. + +Preservation concerns for electronic media fall into two general domains. +One is the continuing assurance of access to knowledge originally +generated, stored, disseminated, and used in electronic form. This +domain contains several subdivisions, including 1) the closed, +proprietary systems discussed the previous day, bundled information such +as electronic journals and government agency records, and electronically +produced or captured raw data; and 2) the application of digital +technologies to the reformatting of materials originally published on a +deteriorating analog medium such as acid paper or videotape. + +The preservation of electronic media requires a reconceptualizing of our +preservation principles during a volatile, standardless transition which +may last far longer than any of us envision today. BATTIN urged the +necessity of shifting focus from assessing, measuring, and setting +standards for the permanence of the medium to the concept of managing +continuing access to information stored on a variety of media and +requiring a variety of ever-changing hardware and software for access--a +fundamental shift for the library profession. + +BATTIN offered a primer on how to move forward with reasonable confidence +in a world without standards. Her comments fell roughly into two sections: +1) standards in the real world and 2) the politics of reproduction. + +In regard to real-world standards, BATTIN argued the need to redefine the +concept of archive and to begin to think in terms of life cycles. In +the past, the naive assumption that paper would last forever produced a +cavalier attitude toward life cycles. The transient nature of the +electronic media has compelled people to recognize and accept upfront the +concept of life cycles in place of permanency. + +Digital standards have to be developed and set in a cooperative context +to ensure efficient exchange of information. Moreover, during this +transition period, greater flexibility concerning how concepts such as +backup copies and archival copies in the CXP are defined is necessary, +or the opportunity to move forward will be lost. + +In terms of cooperation, particularly in the university setting, BATTIN +also argued the need to avoid going off in a hundred different +directions. The CPA has catalyzed a small group of universities called +the La Guardia Eight--because La Guardia Airport is where meetings take +place--Harvard, Yale, Cornell, Princeton, Penn State, Tennessee, +Stanford, and USC, to develop a digital preservation consortium to look +at all these issues and develop de facto standards as we move along, +instead of waiting for something that is officially blessed. Continuing +to apply analog values and definitions of standards to the digital +environment, BATTIN said, will effectively lead to forfeiture of the +benefits of digital technology to research and scholarship. + +Under the second rubric, the politics of reproduction, BATTIN reiterated +an oft-made argument concerning the electronic library, namely, that it +is more difficult to transform than to create, and nowhere is that belief +expressed more dramatically than in the conversion of brittle books to +new media. Preserving information published in electronic media involves +making sure the information remains accessible and that digital +information is not lost through reproduction. In the analog world of +photocopies and microfilm, the issue of fidelity to the original becomes +paramount, as do issues of "Whose fidelity?" and "Whose original?" + +BATTIN elaborated these arguments with a few examples from a recent study +conducted by the CPA on the problems of preserving text and image. +Discussions with scholars, librarians, and curators in a variety of +disciplines dependent on text and image generated a variety of concerns, +for example: 1) Copy what is, not what the technology is capable of. +This is very important for the history of ideas. Scholars wish to know +what the author saw and worked from. And make available at the +workstation the opportunity to erase all the defects and enhance the +presentation. 2) The fidelity of reproduction--what is good enough, what +can we afford, and the difference it makes--issues of subjective versus +objective resolution. 3) The differences between primary and secondary +users. Restricting the definition of primary user to the one in whose +discipline the material has been published runs one headlong into the +reality that these printed books have had a host of other users from a +host of other disciplines, who not only were looking for very different +things, but who also shared values very different from those of the +primary user. 4) The relationship of the standard of reproduction to new +capabilities of scholarship--the browsing standard versus an archival +standard. How good must the archival standard be? Can a distinction be +drawn between potential users in setting standards for reproduction? +Archival storage, use copies, browsing copies--ought an attempt to set +standards even be made? 5) Finally, costs. How much are we prepared to +pay to capture absolute fidelity? What are the trade-offs between vastly +enhanced access, degrees of fidelity, and costs? + +These standards, BATTIN concluded, serve to complicate further the +reproduction process, and add to the long list of technical standards +that are necessary to ensure widespread access. Ways to articulate and +analyze the costs that are attached to the different levels of standards +must be found. + +Given the chaos concerning standards, which promises to linger for the +foreseeable future, BATTIN urged adoption of the following general +principles: + + * Strive to understand the changing information requirements of + scholarly disciplines as more and more technology is integrated into + the process of research and scholarly communication in order to meet + future scholarly needs, not to build for the past. Capture + deteriorating information at the highest affordable resolution, even + though the dissemination and display technologies will lag. + + * Develop cooperative mechanisms to foster agreement on protocols + for document structure and other interchange mechanisms necessary + for widespread dissemination and use before official standards are + set. + + * Accept that, in a transition period, de facto standards will have + to be developed. + + * Capture information in a way that keeps all options open and + provides for total convertibility: OCR, scanning of microfilm, + producing microfilm from scanned documents, etc. + + * Work closely with the generators of information and the builders + of networks and databases to ensure that continuing accessibility is + a primary concern from the beginning. + + * Piggyback on standards under development for the broad market, and + avoid library-specific standards; work with the vendors, in order to + take advantage of that which is being standardized for the rest of + the world. + + * Concentrate efforts on managing permanence in the digital world, + rather than perfecting the longevity of a particular medium. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional comments on TIFF * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief discussion period that followed BATTIN's presentation, +BARONAS explained that TIFF was not developed in collaboration with or +under the auspices of AIIM. TIFF is a company product, not a standard, +is owned by two corporations, and is always changing. BARONAS also +observed that ANSI/AIIM MS53, a bi-level image file transfer format that +allows unlike systems to exchange images, is compatible with TIFF as well +as with DEC's architecture and IBM's MODCA/IOCA. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOOTON * Several questions to be considered in discussing text conversion +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON introduced the final topic, text conversion, by noting that it is +becoming an increasingly important part of the imaging business. Many +people now realize that it enhances their system to be able to have more +and more character data as part of their imaging system. Re the issue of +OCR versus rekeying, HOOTON posed several questions: How does one get +text into computer-readable form? Does one use automated processes? +Does one attempt to eliminate the use of operators where possible? +Standards for accuracy, he said, are extremely important: it makes a +major difference in cost and time whether one sets as a standard 98.5 +percent acceptance or 99.5 percent. He mentioned outsourcing as a +possibility for converting text. Finally, what one does with the image +to prepare it for the recognition process is also important, he said, +because such preparation changes how recognition is viewed, as well as +facilitates recognition itself. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LESK * Roles of participants in CORE * Data flow * The scanning process * +The image interface * Results of experiments involving the use of +electronic resources and traditional paper copies * Testing the issue of +serendipity * Conclusions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Michael LESK, executive director, Computer Science Research, Bell +Communications Research, Inc. (Bellcore), discussed the Chemical Online +Retrieval Experiment (CORE), a cooperative project involving Cornell +University, OCLC, Bellcore, and the American Chemical Society (ACS). + +LESK spoke on 1) how the scanning was performed, including the unusual +feature of page segmentation, and 2) the use made of the text and the +image in experiments. + +Working with the chemistry journals (because ACS has been saving its +typesetting tapes since the mid-1970s and thus has a significant back-run +of the most important chemistry journals in the United States), CORE is +attempting to create an automated chemical library. Approximately a +quarter of the pages by square inch are made up of images of +quasi-pictorial material; dealing with the graphic components of the +pages is extremely important. LESK described the roles of participants +in CORE: 1) ACS provides copyright permission, journals on paper, +journals on microfilm, and some of the definitions of the files; 2) at +Bellcore, LESK chiefly performs the data preparation, while Dennis Egan +performs experiments on the users of chemical abstracts, and supplies the +indexing and numerous magnetic tapes; 3) Cornell provides the site of the +experiment; 4) OCLC develops retrieval software and other user interfaces. +Various manufacturers and publishers have furnished other help. + +Concerning data flow, Bellcore receives microfilm and paper from ACS; the +microfilm is scanned by outside vendors, while the paper is scanned +inhouse on an Improvision scanner, twenty pages per minute at 300 dpi, +which provides sufficient quality for all practical uses. LESK would +prefer to have more gray level, because one of the ACS journals prints on +some colored pages, which creates a problem. + +Bellcore performs all this scanning, creates a page-image file, and also +selects from the pages the graphics, to mix with the text file (which is +discussed later in the Workshop). The user is always searching the ASCII +file, but she or he may see a display based on the ASCII or a display +based on the images. + +LESK illustrated how the program performs page analysis, and the image +interface. (The user types several words, is presented with a list-- +usually of the titles of articles contained in an issue--that derives +from the ASCII, clicks on an icon and receives an image that mirrors an +ACS page.) LESK also illustrated an alternative interface, based on text +on the ASCII, the so-called SuperBook interface from Bellcore. + +LESK next presented the results of an experiment conducted by Dennis Egan +and involving thirty-six students at Cornell, one third of them +undergraduate chemistry majors, one third senior undergraduate chemistry +majors, and one third graduate chemistry students. A third of them +received the paper journals, the traditional paper copies and chemical +abstracts on paper. A third received image displays of the pictures of +the pages, and a third received the text display with pop-up graphics. + +The students were given several questions made up by some chemistry +professors. The questions fell into five classes, ranging from very easy +to very difficult, and included questions designed to simulate browsing +as well as a traditional information retrieval-type task. + +LESK furnished the following results. In the straightforward question +search--the question being, what is the phosphorus oxygen bond distance +and hydroxy phosphate?--the students were told that they could take +fifteen minutes and, then, if they wished, give up. The students with +paper took more than fifteen minutes on average, and yet most of them +gave up. The students with either electronic format, text or image, +received good scores in reasonable time, hardly ever had to give up, and +usually found the right answer. + +In the browsing study, the students were given a list of eight topics, +told to imagine that an issue of the Journal of the American Chemical +Society had just appeared on their desks, and were also told to flip +through it and to find topics mentioned in the issue. The average scores +were about the same. (The students were told to answer yes or no about +whether or not particular topics appeared.) The errors, however, were +quite different. The students with paper rarely said that something +appeared when it had not. But they often failed to find something +actually mentioned in the issue. The computer people found numerous +things, but they also frequently said that a topic was mentioned when it +was not. (The reason, of course, was that they were performing word +searches. They were finding that words were mentioned and they were +concluding that they had accomplished their task.) + +This question also contained a trick to test the issue of serendipity. +The students were given another list of eight topics and instructed, +without taking a second look at the journal, to recall how many of this +new list of eight topics were in this particular issue. This was an +attempt to see if they performed better at remembering what they were not +looking for. They all performed about the same, paper or electronics, +about 62 percent accurate. In short, LESK said, people were not very +good when it came to serendipity, but they were no worse at it with +computers than they were with paper. + +(LESK gave a parenthetical illustration of the learning curve of students +who used SuperBook.) + +The students using the electronic systems started off worse than the ones +using print, but by the third of the three sessions in the series had +caught up to print. As one might expect, electronics provide a much +better means of finding what one wants to read; reading speeds, once the +object of the search has been found, are about the same. + +Almost none of the students could perform the hard task--the analogous +transformation. (It would require the expertise of organic chemists to +complete.) But an interesting result was that the students using the text +search performed terribly, while those using the image system did best. +That the text search system is driven by text offers the explanation. +Everything is focused on the text; to see the pictures, one must press +on an icon. Many students found the right article containing the answer +to the question, but they did not click on the icon to bring up the right +figure and see it. They did not know that they had found the right place, +and thus got it wrong. + +The short answer demonstrated by this experiment was that in the event +one does not know what to read, one needs the electronic systems; the +electronic systems hold no advantage at the moment if one knows what to +read, but neither do they impose a penalty. + +LESK concluded by commenting that, on one hand, the image system was easy +to use. On the other hand, the text display system, which represented +twenty man-years of work in programming and polishing, was not winning, +because the text was not being read, just searched. The much easier +system is highly competitive as well as remarkably effective for the +actual chemists. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ERWAY * Most challenging aspect of working on AM * Assumptions guiding +AM's approach * Testing different types of service bureaus * AM's +requirement for 99.95 percent accuracy * Requirements for text-coding * +Additional factors influencing AM's approach to coding * Results of AM's +experience with rekeying * Other problems in dealing with service bureaus +* Quality control the most time-consuming aspect of contracting out +conversion * Long-term outlook uncertain * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To Ricky ERWAY, associate coordinator, American Memory, Library of +Congress, the constant variety of conversion projects taking place +simultaneously represented perhaps the most challenging aspect of working +on AM. Thus, the challenge was not to find a solution for text +conversion but a tool kit of solutions to apply to LC's varied +collections that need to be converted. ERWAY limited her remarks to the +process of converting text to machine-readable form, and the variety of +LC's text collections, for example, bound volumes, microfilm, and +handwritten manuscripts. + +Two assumptions have guided AM's approach, ERWAY said: 1) A desire not +to perform the conversion inhouse. Because of the variety of formats and +types of texts, to capitalize the equipment and have the talents and +skills to operate them at LC would be extremely expensive. Further, the +natural inclination to upgrade to newer and better equipment each year +made it reasonable for AM to focus on what it did best and seek external +conversion services. Using service bureaus also allowed AM to have +several types of operations take place at the same time. 2) AM was not a +technology project, but an effort to improve access to library +collections. Hence, whether text was converted using OCR or rekeying +mattered little to AM. What mattered were cost and accuracy of results. + +AM considered different types of service bureaus and selected three to +perform several small tests in order to acquire a sense of the field. +The sample collections with which they worked included handwritten +correspondence, typewritten manuscripts from the 1940s, and +eighteenth-century printed broadsides on microfilm. On none of these +samples was OCR performed; they were all rekeyed. AM had several special +requirements for the three service bureaus it had engaged. For instance, +any errors in the original text were to be retained. Working from bound +volumes or anything that could not be sheet-fed also constituted a factor +eliminating companies that would have performed OCR. + +AM requires 99.95 percent accuracy, which, though it sounds high, often +means one or two errors per page. The initial batch of test samples +contained several handwritten materials for which AM did not require +text-coding. The results, ERWAY reported, were in all cases fairly +comparable: for the most part, all three service bureaus achieved 99.95 +percent accuracy. AM was satisfied with the work but surprised at the cost. + +As AM began converting whole collections, it retained the requirement for +99.95 percent accuracy and added requirements for text-coding. AM needed +to begin performing work more than three years ago before LC requirements +for SGML applications had been established. Since AM's goal was simply +to retain any of the intellectual content represented by the formatting +of the document (which would be lost if one performed a straight ASCII +conversion), AM used "SGML-like" codes. These codes resembled SGML tags +but were used without the benefit of document-type definitions. AM found +that many service bureaus were not yet SGML-proficient. + +Additional factors influencing the approach AM took with respect to +coding included: 1) the inability of any known microcomputer-based +user-retrieval software to take advantage of SGML coding; and 2) the +multiple inconsistencies in format of the older documents, which +confirmed AM in its desire not to attempt to force the different formats +to conform to a single document-type definition (DTD) and thus create the +need for a separate DTD for each document. + +The five text collections that AM has converted or is in the process of +converting include a collection of eighteenth-century broadsides, a +collection of pamphlets, two typescript document collections, and a +collection of 150 books. + +ERWAY next reviewed the results of AM's experience with rekeying, noting +again that because the bulk of AM's materials are historical, the quality +of the text often does not lend itself to OCR. While non-English +speakers are less likely to guess or elaborate or correct typos in the +original text, they are also less able to infer what we would; they also +are nearly incapable of converting handwritten text. Another +disadvantage of working with overseas keyers is that they are much less +likely to telephone with questions, especially on the coding, with the +result that they develop their own rules as they encounter new +situations. + +Government contracting procedures and time frames posed a major challenge +to performing the conversion. Many service bureaus are not accustomed to +retaining the image, even if they perform OCR. Thus, questions of image +format and storage media were somewhat novel to many of them. ERWAY also +remarked other problems in dealing with service bureaus, for example, +their inability to perform text conversion from the kind of microfilm +that LC uses for preservation purposes. + +But quality control, in ERWAY's experience, was the most time-consuming +aspect of contracting out conversion. AM has been attempting to perform +a 10-percent quality review, looking at either every tenth document or +every tenth page to make certain that the service bureaus are maintaining +99.95 percent accuracy. But even if they are complying with the +requirement for accuracy, finding errors produces a desire to correct +them and, in turn, to clean up the whole collection, which defeats the +purpose to some extent. Even a double entry requires a +character-by-character comparison to the original to meet the accuracy +requirement. LC is not accustomed to publish imperfect texts, which +makes attempting to deal with the industry standard an emotionally +fraught issue for AM. As was mentioned in the previous day's discussion, +going from 99.95 to 99.99 percent accuracy usually doubles costs and +means a third keying or another complete run-through of the text. + +Although AM has learned much from its experiences with various collections +and various service bureaus, ERWAY concluded pessimistically that no +breakthrough has been achieved. Incremental improvements have occurred +in some of the OCR technology, some of the processes, and some of the +standards acceptances, which, though they may lead to somewhat lower costs, +do not offer much encouragement to many people who are anxiously awaiting +the day that the entire contents of LC are available on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * Several answers to why one attempts to perform full-text +conversion * Per page cost of performing OCR * Typical problems +encountered during editing * Editing poor copy OCR vs. rekeying * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), offered several answers to +the question of why one attempts to perform full-text conversion: 1) +Text in an image can be read by a human but not by a computer, so of +course it is not searchable and there is not much one can do with it. 2) +Some material simply requires word-level access. For instance, the legal +profession insists on full-text access to its material; with taxonomic or +geographic material, which entails numerous names, one virtually requires +word-level access. 3) Full text permits rapid browsing and searching, +something that cannot be achieved in an image with today's technology. +4) Text stored as ASCII and delivered in ASCII is standardized and highly +portable. 5) People just want full-text searching, even those who do not +know how to do it. NAL, for the most part, is performing OCR at an +actual cost per average-size page of approximately $7. NAL scans the +page to create the electronic image and passes it through the OCR device. + +ZIDAR next rehearsed several typical problems encountered during editing. +Praising the celerity of her student workers, ZIDAR observed that editing +requires approximately five to ten minutes per page, assuming that there +are no large tables to audit. Confusion among the three characters I, 1, +and l, constitutes perhaps the most common problem encountered. Zeroes +and O's also are frequently confused. Double M's create a particular +problem, even on clean pages. They are so wide in most fonts that they +touch, and the system simply cannot tell where one letter ends and the +other begins. Complex page formats occasionally fail to columnate +properly, which entails rescanning as though one were working with a +single column, entering the ASCII, and decolumnating for better +searching. With proportionally spaced text, OCR can have difficulty +discerning what is a space and what are merely spaces between letters, as +opposed to spaces between words, and therefore will merge text or break +up words where it should not. + +ZIDAR said that it can often take longer to edit a poor-copy OCR than to +key it from scratch. NAL has also experimented with partial editing of +text, whereby project workers go into and clean up the format, removing +stray characters but not running a spell-check. NAL corrects typos in +the title and authors' names, which provides a foothold for searching and +browsing. Even extremely poor-quality OCR (e.g., 60-percent accuracy) +can still be searched, because numerous words are correct, while the +important words are probably repeated often enough that they are likely +to be found correct somewhere. Librarians, however, cannot tolerate this +situation, though end users seem more willing to use this text for +searching, provided that NAL indicates that it is unedited. ZIDAR +concluded that rekeying of text may be the best route to take, in spite +of numerous problems with quality control and cost. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Modifying an image before performing OCR * NAL's costs per +page *AM's costs per page and experience with Federal Prison Industries * +Elements comprising NATDP's costs per page * OCR and structured markup * +Distinction between the structure of a document and its representation +when put on the screen or printed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON prefaced the lengthy discussion that followed with several +comments about modifying an image before one reaches the point of +performing OCR. For example, in regard to an application containing a +significant amount of redundant data, such as form-type data, numerous +companies today are working on various kinds of form renewal, prior to +going through a recognition process, by using dropout colors. Thus, +acquiring access to form design or using electronic means are worth +considering. HOOTON also noted that conversion usually makes or breaks +one's imaging system. It is extremely important, extremely costly in +terms of either capital investment or service, and determines the quality +of the remainder of one's system, because it determines the character of +the raw material used by the system. + +Concerning the four projects undertaken by NAL, two inside and two +performed by outside contractors, ZIDAR revealed that an in-house service +bureau executed the first at a cost between $8 and $10 per page for +everything, including building of the database. The project undertaken +by the Consultative Group on International Agricultural Research (CGIAR) +cost approximately $10 per page for the conversion, plus some expenses +for the software and building of the database. The Acid Rain Project--a +two-disk set produced by the University of Vermont, consisting of +Canadian publications on acid rain--cost $6.70 per page for everything, +including keying of the text, which was double keyed, scanning of the +images, and building of the database. The in-house project offered +considerable ease of convenience and greater control of the process. On +the other hand, the service bureaus know their job and perform it +expeditiously, because they have more people. + +As a useful comparison, ERWAY revealed AM's costs as follows: $0.75 +cents to $0.85 cents per thousand characters, with an average page +containing 2,700 characters. Requirements for coding and imaging +increase the costs. Thus, conversion of the text, including the coding, +costs approximately $3 per page. (This figure does not include the +imaging and database-building included in the NAL costs.) AM also +enjoyed a happy experience with Federal Prison Industries, which +precluded the necessity of going through the request-for-proposal process +to award a contract, because it is another government agency. The +prisoners performed AM's rekeying just as well as other service bureaus +and proved handy as well. AM shipped them the books, which they would +photocopy on a book-edge scanner. They would perform the markup on +photocopies, return the books as soon as they were done with them, +perform the keying, and return the material to AM on WORM disks. + +ZIDAR detailed the elements that constitute the previously noted cost of +approximately $7 per page. Most significant is the editing, correction +of errors, and spell-checkings, which though they may sound easy to +perform require, in fact, a great deal of time. Reformatting text also +takes a while, but a significant amount of NAL's expenses are for equipment, +which was extremely expensive when purchased because it was one of the few +systems on the market. The costs of equipment are being amortized over +five years but are still quite high, nearly $2,000 per month. + +HOCKEY raised a general question concerning OCR and the amount of editing +required (substantial in her experience) to generate the kind of +structured markup necessary for manipulating the text on the computer or +loading it into any retrieval system. She wondered if the speakers could +extend the previous question about the cost-benefit of adding or exerting +structured markup. ERWAY noted that several OCR systems retain italics, +bolding, and other spatial formatting. While the material may not be in +the format desired, these systems possess the ability to remove the +original materials quickly from the hands of the people performing the +conversion, as well as to retain that information so that users can work +with it. HOCKEY rejoined that the current thinking on markup is that one +should not say that something is italic or bold so much as why it is that +way. To be sure, one needs to know that something was italicized, but +how can one get from one to the other? One can map from the structure to +the typographic representation. + +FLEISCHHAUER suggested that, given the 100 million items the Library +holds, it may not be possible for LC to do more than report that a thing +was in italics as opposed to why it was italics, although that may be +desirable in some contexts. Promising to talk a bit during the afternoon +session about several experiments OCLC performed on automatic recognition +of document elements, and which they hoped to extend, WEIBEL said that in +fact one can recognize the major elements of a document with a fairly +high degree of reliability, at least as good as OCR. STEVENS drew a +useful distinction between standard, generalized markup (i.e., defining +for a document-type definition the structure of the document), and what +he termed a style sheet, which had to do with italics, bolding, and other +forms of emphasis. Thus, two different components are at work, one being +the structure of the document itself (its logic), and the other being its +representation when it is put on the screen or printed. + + ****** + +SESSION V. APPROACHES TO PREPARING ELECTRONIC TEXTS + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOCKEY * Text in ASCII and the representation of electronic text versus +an image * The need to look at ways of using markup to assist retrieval * +The need for an encoding format that will be reusable and multifunctional ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan HOCKEY, director, Center for Electronic Texts in the Humanities +(CETH), Rutgers and Princeton Universities, announced that one talk +(WEIBEL's) was moved into this session from the morning and that David +Packard was unable to attend. The session would attempt to focus more on +what one can do with a text in ASCII and the representation of electronic +text rather than just an image, what one can do with a computer that +cannot be done with a book or an image. It would be argued that one can +do much more than just read a text, and from that starting point one can +use markup and methods of preparing the text to take full advantage of +the capability of the computer. That would lead to a discussion of what +the European Community calls REUSABILITY, what may better be termed +DURABILITY, that is, how to prepare or make a text that will last a long +time and that can be used for as many applications as possible, which +would lead to issues of improving intellectual access. + +HOCKEY urged the need to look at ways of using markup to facilitate retrieval, +not just for referencing or to help locate an item that is retrieved, but also to put markup tags in +a text to help retrieve the thing sought either with linguistic tagging or +interpretation. HOCKEY also argued that little advancement had occurred in +the software tools currently available for retrieving and searching text. +She pressed the desideratum of going beyond Boolean searches and performing +more sophisticated searching, which the insertion of more markup in the text +would facilitate. Thinking about electronic texts as opposed to images means +considering material that will never appear in print form, or print will not +be its primary form, that is, material which only appears in electronic form. +HOCKEY alluded to the history and the need for markup and tagging and +electronic text, which was developed through the use of computers in the +humanities; as MICHELSON had observed, Father Busa had started in 1949 +to prepare the first-ever text on the computer. + +HOCKEY remarked several large projects, particularly in Europe, for the +compilation of dictionaries, language studies, and language analysis, in +which people have built up archives of text and have begun to recognize +the need for an encoding format that will be reusable and multifunctional, +that can be used not just to print the text, which may be assumed to be a +byproduct of what one wants to do, but to structure it inside the computer +so that it can be searched, built into a Hypertext system, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WEIBEL * OCLC's approach to preparing electronic text: retroconversion, +keying of texts, more automated ways of developing data * Project ADAPT +and the CORE Project * Intelligent character recognition does not exist * +Advantages of SGML * Data should be free of procedural markup; +descriptive markup strongly advocated * OCLC's interface illustrated * +Storage requirements and costs for putting a lot of information on line * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Stuart WEIBEL, senior research scientist, Online Computer Library Center, +Inc. (OCLC), described OCLC's approach to preparing electronic text. He +argued that the electronic world into which we are moving must +accommodate not only the future but the past as well, and to some degree +even the present. Thus, starting out at one end with retroconversion and +keying of texts, one would like to move toward much more automated ways +of developing data. + +For example, Project ADAPT had to do with automatically converting +document images into a structured document database with OCR text as +indexing and also a little bit of automatic formatting and tagging of +that text. The CORE project hosted by Cornell University, Bellcore, +OCLC, the American Chemical Society, and Chemical Abstracts, constitutes +WEIBEL's principal concern at the moment. This project is an example of +converting text for which one already has a machine-readable version into +a format more suitable for electronic delivery and database searching. +(Since Michael LESK had previously described CORE, WEIBEL would say +little concerning it.) Borrowing a chemical phrase, de novo synthesis, +WEIBEL cited the Online Journal of Current Clinical Trials as an example +of de novo electronic publishing, that is, a form in which the primary +form of the information is electronic. + +Project ADAPT, then, which OCLC completed a couple of years ago and in +fact is about to resume, is a model in which one takes page images either +in paper or microfilm and converts them automatically to a searchable +electronic database, either on-line or local. The operating assumption +is that accepting some blemishes in the data, especially for +retroconversion of materials, will make it possible to accomplish more. +Not enough money is available to support perfect conversion. + +WEIBEL related several steps taken to perform image preprocessing +(processing on the image before performing optical character +recognition), as well as image postprocessing. He denied the existence +of intelligent character recognition and asserted that what is wanted is +page recognition, which is a long way off. OCLC has experimented with +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000, but it +is not good enough. It will never be perfect. + +Concerning the CORE Project, WEIBEL observed that Bellcore is taking the +topography files, extracting the page images, and converting those +topography files to SGML markup. LESK hands that data off to OCLC, which +builds that data into a Newton database, the same system that underlies +the on-line system in virtually all of the reference products at OCLC. +The long-term goal is to make the systems interoperable so that not just +Bellcore's system and OCLC's system can access this data, but other +systems can as well, and the key to that is the Z39.50 common command +language and the full-text extension. Z39.50 is fine for MARC records, +but is not enough to do it for full text (that is, make full texts +interoperable). + +WEIBEL next outlined the critical role of SGML for a variety of purposes, +for example, as noted by HOCKEY, in the world of extremely large +databases, using highly structured data to perform field searches. +WEIBEL argued that by building the structure of the data in (i.e., the +structure of the data originally on a printed page), it becomes easy to +look at a journal article even if one cannot read the characters and know +where the title or author is, or what the sections of that document would be. +OCLC wants to make that structure explicit in the database, because it will +be important for retrieval purposes. + +The second big advantage of SGML is that it gives one the ability to +build structure into the database that can be used for display purposes +without contaminating the data with instructions about how to format +things. The distinction lies between procedural markup, which tells one +where to put dots on the page, and descriptive markup, which describes +the elements of a document. + +WEIBEL believes that there should be no procedural markup in the data at +all, that the data should be completely unsullied by information about +italics or boldness. That should be left up to the display device, +whether that display device is a page printer or a screen display device. +By keeping one's database free of that kind of contamination, one can +make decisions down the road, for example, reorganize the data in ways +that are not cramped by built-in notions of what should be italic and +what should be bold. WEIBEL strongly advocated descriptive markup. As +an example, he illustrated the index structure in the CORE data. With +subsequent illustrated examples of markup, WEIBEL acknowledged the common +complaint that SGML is hard to read in its native form, although markup +decreases considerably once one gets into the body. Without the markup, +however, one would not have the structure in the data. One can pass +markup through a LaTeX processor and convert it relatively easily to a +printed version of the document. + +WEIBEL next illustrated an extremely cluttered screen dump of OCLC's +system, in order to show as much as possible the inherent capability on +the screen. (He noted parenthetically that he had become a supporter of +X-Windows as a result of the progress of the CORE Project.) WEIBEL also +illustrated the two major parts of the interface: l) a control box that +allows one to generate lists of items, which resembles a small table of +contents based on key words one wishes to search, and 2) a document +viewer, which is a separate process in and of itself. He demonstrated +how to follow links through the electronic database simply by selecting +the appropriate button and bringing them up. He also noted problems that +remain to be accommodated in the interface (e.g., as pointed out by LESK, +what happens when users do not click on the icon for the figure). + +Given the constraints of time, WEIBEL omitted a large number of ancillary +items in order to say a few words concerning storage requirements and +what will be required to put a lot of things on line. Since it is +extremely expensive to reconvert all of this data, especially if it is +just in paper form (and even if it is in electronic form in typesetting +tapes), he advocated building journals electronically from the start. In +that case, if one only has text graphics and indexing (which is all that +one needs with de novo electronic publishing, because there is no need to +go back and look at bit-maps of pages), one can get 10,000 journals of +full text, or almost 6 million pages per year. These pages can be put in +approximately 135 gigabytes of storage, which is not all that much, +WEIBEL said. For twenty years, something less than three terabytes would +be required. WEIBEL calculated the costs of storing this information as +follows: If a gigabyte costs approximately $1,000, then a terabyte costs +approximately $1 million to buy in terms of hardware. One also needs a +building to put it in and a staff like OCLC to handle that information. +So, to support a terabyte, multiply by five, which gives $5 million per +year for a supported terabyte of data. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Tapes saved by ACS are the typography files originally +supporting publication of the journal * Cost of building tagged text into +the database * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed WEIBEL's +presentation, these clarifications emerged. The tapes saved by the +American Chemical Society are the typography files that originally +supported the publication of the journal. Although they are not tagged +in SGML, they are tagged in very fine detail. Every single sentence is +marked, all the registry numbers, all the publications issues, dates, and +volumes. No cost figures on tagging material on a per-megabyte basis +were available. Because ACS's typesetting system runs from tagged text, +there is no extra cost per article. It was unknown what it costs ACS to +keyboard the tagged text rather than just keyboard the text in the +cheapest process. In other words, since one intends to publish things +and will need to build tagged text into a typography system in any case, +if one does that in such a way that it can drive not only typography but +an electronic system (which is what ACS intends to do--move to SGML +publishing), the marginal cost is zero. The marginal cost represents the +cost of building tagged text into the database, which is small. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +SPERBERG-McQUEEN * Distinction between texts and computers * Implications +of recognizing that all representation is encoding * Dealing with +complicated representations of text entails the need for a grammar of +documents * Variety of forms of formal grammars * Text as a bit-mapped +image does not represent a serious attempt to represent text in +electronic form * SGML, the TEI, document-type declarations, and the +reusability and longevity of data * TEI conformance explicitly allows +extension or modification of the TEI tag set * Administrative background +of the TEI * Several design goals for the TEI tag set * An absolutely +fixed requirement of the TEI Guidelines * Challenges the TEI has +attempted to face * Good texts not beyond economic feasibility * The +issue of reproducibility or processability * The issue of mages as +simulacra for the text redux * One's model of text determines what one's +software can do with a text and has economic consequences * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Prior to speaking about SGML and markup, Michael SPERBERG-McQUEEN, editor, +Text Encoding Initiative (TEI), University of Illinois-Chicago, first drew +a distinction between texts and computers: Texts are abstract cultural +and linguistic objects while computers are complicated physical devices, +he said. Abstract objects cannot be placed inside physical devices; with +computers one can only represent text and act upon those representations. + +The recognition that all representation is encoding, SPERBERG-McQUEEN +argued, leads to the recognition of two things: 1) The topic description +for this session is slightly misleading, because there can be no discussion +of pros and cons of text-coding unless what one means is pros and cons of +working with text with computers. 2) No text can be represented in a +computer without some sort of encoding; images are one way of encoding text, +ASCII is another, SGML yet another. There is no encoding without some +information loss, that is, there is no perfect reproduction of a text that +allows one to do away with the original. Thus, the question becomes, +What is the most useful representation of text for a serious work? +This depends on what kind of serious work one is talking about. + +The projects demonstrated the previous day all involved highly complex +information and fairly complex manipulation of the textual material. +In order to use that complicated information, one has to calculate it +slowly or manually and store the result. It needs to be stored, therefore, +as part of one's representation of the text. Thus, one needs to store the +structure in the text. To deal with complicated representations of text, +one needs somehow to control the complexity of the representation of a text; +that means one needs a way of finding out whether a document and an +electronic representation of a document is legal or not; and that +means one needs a grammar of documents. + +SPERBERG-McQUEEN discussed the variety of forms of formal grammars, +implicit and explicit, as applied to text, and their capabilities. He +argued that these grammars correspond to different models of text that +different developers have. For example, one implicit model of the text +is that there is no internal structure, but just one thing after another, +a few characters and then perhaps a start-title command, and then a few +more characters and an end-title command. SPERBERG-McQUEEN also +distinguished several kinds of text that have a sort of hierarchical +structure that is not very well defined, which, typically, corresponds +to grammars that are not very well defined, as well as hierarchies that +are very well defined (e.g., the Thesaurus Linguae Graecae) and extremely +complicated things such as SGML, which handle strictly hierarchical data +very nicely. + +SPERBERG-McQUEEN conceded that one other model not illustrated on his two +displays was the model of text as a bit-mapped image, an image of a page, +and confessed to having been converted to a limited extent by the +Workshop to the view that electronic images constitute a promising, +probably superior alternative to microfilming. But he was not convinced +that electronic images represent a serious attempt to represent text in +electronic form. Many of their problems stem from the fact that they are +not direct attempts to represent the text but attempts to represent the +page, thus making them representations of representations. + +In this situation of increasingly complicated textual information and the +need to control that complexity in a useful way (which begs the question +of the need for good textual grammars), one has the introduction of SGML. +With SGML, one can develop specific document-type declarations +for specific text types or, as with the TEI, attempts to generate +general document-type declarations that can handle all sorts of text. +The TEI is an attempt to develop formats for text representation that +will ensure the kind of reusability and longevity of data discussed earlier. +It offers a way to stay alive in the state of permanent technological +revolution. + +It has been a continuing challenge in the TEI to create document grammars +that do some work in controlling the complexity of the textual object but +also allowing one to represent the real text that one will find. +Fundamental to the notion of the TEI is that TEI conformance allows one +the ability to extend or modify the TEI tag set so that it fits the text +that one is attempting to represent. + +SPERBERG-McQUEEN next outlined the administrative background of the TEI. +The TEI is an international project to develop and disseminate guidelines +for the encoding and interchange of machine-readable text. It is +sponsored by the Association for Computers in the Humanities, the +Association for Computational Linguistics, and the Association for +Literary and Linguistic Computing. Representatives of numerous other +professional societies sit on its advisory board. The TEI has a number +of affiliated projects that have provided assistance by testing drafts of +the guidelines. + +Among the design goals for the TEI tag set, the scheme first of all must +meet the needs of research, because the TEI came out of the research +community, which did not feel adequately served by existing tag sets. +The tag set must be extensive as well as compatible with existing and +emerging standards. In 1990, version 1.0 of the Guidelines was released +(SPERBERG-McQUEEN illustrated their contents). + +SPERBERG-McQUEEN noted that one problem besetting electronic text has +been the lack of adequate internal or external documentation for many +existing electronic texts. The TEI guidelines as currently formulated +contain few fixed requirements, but one of them is this: There must +always be a document header, an in-file SGML tag that provides +1) a bibliographic description of the electronic object one is talking +about (that is, who included it, when, what for, and under which title); +and 2) the copy text from which it was derived, if any. If there was +no copy text or if the copy text is unknown, then one states as much. +Version 2.0 of the Guidelines was scheduled to be completed in fall 1992 +and a revised third version is to be presented to the TEI advisory board +for its endorsement this coming winter. The TEI itself exists to provide +a markup language, not a marked-up text. + +Among the challenges the TEI has attempted to face is the need for a +markup language that will work for existing projects, that is, handle the +level of markup that people are using now to tag only chapter, section, +and paragraph divisions and not much else. At the same time, such a +language also will be able to scale up gracefully to handle the highly +detailed markup which many people foresee as the future destination of +much electronic text, and which is not the future destination but the +present home of numerous electronic texts in specialized areas. + +SPERBERG-McQUEEN dismissed the lowest-common-denominator approach as +unable to support the kind of applications that draw people who have +never been in the public library regularly before, and make them come +back. He advocated more interesting text and more intelligent text. +Asserting that it is not beyond economic feasibility to have good texts, +SPERBERG-McQUEEN noted that the TEI Guidelines listing 200-odd tags +contains tags that one is expected to enter every time the relevant +textual feature occurs. It contains all the tags that people need now, +and it is not expected that everyone will tag things in the same way. + +The question of how people will tag the text is in large part a function +of their reaction to what SPERBERG-McQUEEN termed the issue of +reproducibility. What one needs to be able to reproduce are the things +one wants to work with. Perhaps a more useful concept than that of +reproducibility or recoverability is that of processability, that is, +what can one get from an electronic text without reading it again +in the original. He illustrated this contention with a page from +Jan Comenius's bilingual Introduction to Latin. + +SPERBERG-McQUEEN returned at length to the issue of images as simulacra +for the text, in order to reiterate his belief that in the long run more +than images of pages of particular editions of the text are needed, +because just as second-generation photocopies and second-generation +microfilm degenerate, so second-generation representations tend to +degenerate, and one tends to overstress some relatively trivial aspects +of the text such as its layout on the page, which is not always +significant, despite what the text critics might say, and slight other +pieces of information such as the very important lexical ties between the +English and Latin versions of Comenius's bilingual text, for example. +Moreover, in many crucial respects it is easy to fool oneself concerning +what a scanned image of the text will accomplish. For example, in order +to study the transmission of texts, information concerning the text +carrier is necessary, which scanned images simply do not always handle. +Further, even the high-quality materials being produced at Cornell use +much of the information that one would need if studying those books as +physical objects. It is a choice that has been made. It is an arguably +justifiable choice, but one does not know what color those pen strokes in +the margin are or whether there was a stain on the page, because it has +been filtered out. One does not know whether there were rips in the page +because they do not show up, and on a couple of the marginal marks one +loses half of the mark because the pen is very light and the scanner +failed to pick it up, and so what is clearly a checkmark in the margin of +the original becomes a little scoop in the margin of the facsimile. +Standard problems for facsimile editions, not new to electronics, but +also true of light-lens photography, and are remarked here because it is +important that we not fool ourselves that even if we produce a very nice +image of this page with good contrast, we are not replacing the +manuscript any more than microfilm has replaced the manuscript. + +The TEI comes from the research community, where its first allegiance +lies, but it is not just an academic exercise. It has relevance far +beyond those who spend all of their time studying text, because one's +model of text determines what one's software can do with a text. Good +models lead to good software. Bad models lead to bad software. That has +economic consequences, and it is these economic consequences that have +led the European Community to help support the TEI, and that will lead, +SPERBERG-McQUEEN hoped, some software vendors to realize that if they +provide software with a better model of the text they can make a killing. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Implications of different DTDs and tag sets * ODA versus SGML * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed, several additional points were made. +Neither AAP (i.e., Association of American Publishers) nor CALS (i.e., +Computer-aided Acquisition and Logistics Support) has a document-type +definition for ancient Greek drama, although the TEI will be able to +handle that. Given this state of affairs and assuming that the +technical-journal producers and the commercial vendors decide to use the +other two types, then an institution like the Library of Congress, which +might receive all of their publications, would have to be able to handle +three different types of document definitions and tag sets and be able to +distinguish among them. + +Office Document Architecture (ODA) has some advantages that flow from its +tight focus on office documents and clear directions for implementation. +Much of the ODA standard is easier to read and clearer at first reading +than the SGML standard, which is extremely general. What that means is +that if one wants to use graphics in TIFF and ODA, one is stuck, because +ODA defines graphics formats while TIFF does not, whereas SGML says the +world is not waiting for this work group to create another graphics format. +What is needed is an ability to use whatever graphics format one wants. + +The TEI provides a socket that allows one to connect the SGML document to +the graphics. The notation that the graphics are in is clearly a choice +that one needs to make based on her or his environment, and that is one +advantage. SGML is less megalomaniacal in attempting to define formats +for all kinds of information, though more megalomaniacal in attempting to +cover all sorts of documents. The other advantage is that the model of +text represented by SGML is simply an order of magnitude richer and more +flexible than the model of text offered by ODA. Both offer hierarchical +structures, but SGML recognizes that the hierarchical model of the text +that one is looking at may not have been in the minds of the designers, +whereas ODA does not. + +ODA is not really aiming for the kind of document that the TEI wants to +encompass. The TEI can handle the kind of material ODA has, as well as a +significantly broader range of material. ODA seems to be very much +focused on office documents, which is what it started out being called-- +office document architecture. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * Text-encoding from a publisher's perspective * +Responsibilities of a publisher * Reproduction of Migne's Latin series +whole and complete with SGML tags based on perceived need and expected +use * Particular decisions arising from the general decision to produce +and publish PLD * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The final speaker in this session, Eric CALALUCA, vice president, +Chadwyck-Healey, Inc., spoke from the perspective of a publisher re +text-encoding, rather than as one qualified to discuss methods of +encoding data, and observed that the presenters sitting in the room, +whether they had chosen to or not, were acting as publishers: making +choices, gathering data, gathering information, and making assessments. +CALALUCA offered the hard-won conviction that in publishing very large +text files (such as PLD), one cannot avoid making personal judgments of +appropriateness and structure. + +In CALALUCA's view, encoding decisions stem from prior judgments. Two +notions have become axioms for him in the consideration of future sources +for electronic publication: 1) electronic text publishing is as personal +as any other kind of publishing, and questions of if and how to encode +the data are simply a consequence of that prior decision; 2) all +personal decisions are open to criticism, which is unavoidable. + +CALALUCA rehearsed his role as a publisher or, better, as an intermediary +between what is viewed as a sound idea and the people who would make use +of it. Finding the specialist to advise in this process is the core of +that function. The publisher must monitor and hug the fine line between +giving users what they want and suggesting what they might need. One +responsibility of a publisher is to represent the desires of scholars and +research librarians as opposed to bullheadedly forcing them into areas +they would not choose to enter. + +CALALUCA likened the questions being raised today about data structure +and standards to the decisions faced by the Abbe Migne himself during +production of the Patrologia series in the mid-nineteenth century. +Chadwyck-Healey's decision to reproduce Migne's Latin series whole and +complete with SGML tags was also based upon a perceived need and an +expected use. In the same way that Migne's work came to be far more than +a simple handbook for clerics, PLD is already far more than a database +for theologians. It is a bedrock source for the study of Western +civilization, CALALUCA asserted. + +In regard to the decision to produce and publish PLD, the editorial board +offered direct judgments on the question of appropriateness of these +texts for conversion, their encoding and their distribution, and +concluded that the best possible project was one that avoided overt +intrusions or exclusions in so important a resource. Thus, the general +decision to transmit the original collection as clearly as possible with +the widest possible avenues for use led to other decisions: 1) To encode +the data or not, SGML or not, TEI or not. Again, the expected user +community asserted the need for normative tagging structures of important +humanities texts, and the TEI seemed the most appropriate structure for +that purpose. Research librarians, who are trained to view the larger +impact of electronic text sources on 80 or 90 or 100 doctoral +disciplines, loudly approved the decision to include tagging. They see +what is coming better than the specialist who is completely focused on +one edition of Ambrose's De Anima, and they also understand that the +potential uses exceed present expectations. 2) What will be tagged and +what will not. Once again, the board realized that one must tag the +obvious. But in no way should one attempt to identify through encoding +schemes every single discrete area of a text that might someday be +searched. That was another decision. Searching by a column number, an +author, a word, a volume, permitting combination searches, and tagging +notations seemed logical choices as core elements. 3) How does one make +the data available? Tying it to a CD-ROM edition creates limitations, +but a magnetic tape file that is very large, is accompanied by the +encoding specifications, and that allows one to make local modifications +also allows one to incorporate any changes one may desire within the +bounds of private research, though exporting tag files from a CD-ROM +could serve just as well. Since no one on the board could possibly +anticipate each and every way in which a scholar might choose to mine +this data bank, it was decided to satisfy the basics and make some +provisions for what might come. 4) Not to encode the database would rob +it of the interchangeability and portability these important texts should +accommodate. For CALALUCA, the extensive options presented by full-text +searching require care in text selection and strongly support encoding of +data to facilitate the widest possible search strategies. Better +software can always be created, but summoning the resources, the people, +and the energy to reconvert the text is another matter. + +PLD is being encoded, captured, and distributed, because to +Chadwyck-Healey and the board it offers the widest possible array of +future research applications that can be seen today. CALALUCA concluded +by urging the encoding of all important text sources in whatever way +seems most appropriate and durable at the time, without blanching at the +thought that one's work may require emendation in the future. (Thus, +Chadwyck-Healey produced a very large humanities text database before the +final release of the TEI Guidelines.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating texts with markup advocated * Trends in encoding * +The TEI and the issue of interchangeability of standards * A +misconception concerning the TEI * Implications for an institution like +LC in the event that a multiplicity of DTDs develops * Producing images +as a first step towards possible conversion to full text through +character recognition * The AAP tag sets as a common starting point and +the need for caution * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOCKEY prefaced the discussion that followed with several comments in +favor of creating texts with markup and on trends in encoding. In the +future, when many more texts are available for on-line searching, real +problems in finding what is wanted will develop, if one is faced with +millions of words of data. It therefore becomes important to consider +putting markup in texts to help searchers home in on the actual things +they wish to retrieve. Various approaches to refining retrieval methods +toward this end include building on a computer version of a dictionary +and letting the computer look up words in it to obtain more information +about the semantic structure or semantic field of a word, its grammatical +structure, and syntactic structure. + +HOCKEY commented on the present keen interest in the encoding world +in creating: 1) machine-readable versions of dictionaries that can be +initially tagged in SGML, which gives a structure to the dictionary entry; +these entries can then be converted into a more rigid or otherwise +different database structure inside the computer, which can be treated as +a dynamic tool for searching mechanisms; 2) large bodies of text to study +the language. In order to incorporate more sophisticated mechanisms, +more about how words behave needs to be known, which can be learned in +part from information in dictionaries. However, the last ten years have +seen much interest in studying the structure of printed dictionaries +converted into computer-readable form. The information one derives about +many words from those is only partial, one or two definitions of the +common or the usual meaning of a word, and then numerous definitions of +unusual usages. If the computer is using a dictionary to help retrieve +words in a text, it needs much more information about the common usages, +because those are the ones that occur over and over again. Hence the +current interest in developing large bodies of text in computer-readable +form in order to study the language. Several projects are engaged in +compiling, for example, 100 million words. HOCKEY described one with +which she was associated briefly at Oxford University involving +compilation of 100 million words of British English: about 10 percent of +that will contain detailed linguistic tagging encoded in SGML; it will +have word class taggings, with words identified as nouns, verbs, +adjectives, or other parts of speech. This tagging can then be used by +programs which will begin to learn a bit more about the structure of the +language, and then, can go to tag more text. + +HOCKEY said that the more that is tagged accurately, the more one can +refine the tagging process and thus the bigger body of text one can build +up with linguistic tagging incorporated into it. Hence, the more tagging +or annotation there is in the text, the more one may begin to learn about +language and the more it will help accomplish more intelligent OCR. She +recommended the development of software tools that will help one begin to +understand more about a text, which can then be applied to scanning +images of that text in that format and to using more intelligence to help +one interpret or understand the text. + +HOCKEY posited the need to think about common methods of text-encoding +for a long time to come, because building these large bodies of text is +extremely expensive and will only be done once. + +In the more general discussion on approaches to encoding that followed, +these points were made: + +BESSER identified the underlying problem with standards that all have to +struggle with in adopting a standard, namely, the tension between a very +highly defined standard that is very interchangeable but does not work +for everyone because something is lacking, and a standard that is less +defined, more open, more adaptable, but less interchangeable. Contending +that the way in which people use SGML is not sufficiently defined, BESSER +wondered 1) if people resist the TEI because they think it is too defined +in certain things they do not fit into, and 2) how progress with +interchangeability can be made without frightening people away. + +SPERBERG-McQUEEN replied that the published drafts of the TEI had met +with surprisingly little objection on the grounds that they do not allow +one to handle X or Y or Z. Particular concerns of the affiliated +projects have led, in practice, to discussions of how extensions are to +be made; the primary concern of any project has to be how it can be +represented locally, thus making interchange secondary. The TEI has +received much criticism based on the notion that everything in it is +required or even recommended, which, as it happens, is a misconception +from the beginning, because none of it is required and very little is +actually actively recommended for all cases, except that one document +one's source. + +SPERBERG-McQUEEN agreed with BESSER about this trade-off: all the +projects in a set of twenty TEI-conformant projects will not necessarily +tag the material in the same way. One result of the TEI will be that the +easiest problems will be solved--those dealing with the external form of +the information; but the problem that is hardest in interchange is that +one is not encoding what another wants, and vice versa. Thus, after +the adoption of a common notation, the differences in the underlying +conceptions of what is interesting about texts become more visible. +The success of a standard like the TEI will lie in the ability of +the recipient of interchanged texts to use some of what it contains +and to add the information that was not encoded that one wants, in a +layered way, so that texts can be gradually enriched and one does not +have to put in everything all at once. Hence, having a well-behaved +markup scheme is important. + +STEVENS followed up on the paradoxical analogy that BESSER alluded to in +the example of the MARC records, namely, the formats that are the same +except that they are different. STEVENS drew a parallel between +document-type definitions and MARC records for books and serials and maps, +where one has a tagging structure and there is a text-interchange. +STEVENS opined that the producers of the information will set the terms +for the standard (i.e., develop document-type definitions for the users +of their products), creating a situation that will be problematical for +an institution like the Library of Congress, which will have to deal with +the DTDs in the event that a multiplicity of them develops. Thus, +numerous people are seeking a standard but cannot find the tag set that +will be acceptable to them and their clients. SPERBERG-McQUEEN agreed +with this view, and said that the situation was in a way worse: attempting +to unify arbitrary DTDs resembled attempting to unify a MARC record with a +bibliographic record done according to the Prussian instructions. +According to STEVENS, this situation occurred very early in the process. + +WATERS recalled from early discussions on Project Open Book the concern +of many people that merely by producing images, POB was not really +enhancing intellectual access to the material. Nevertheless, not wishing +to overemphasize the opposition between imaging and full text, WATERS +stated that POB views getting the images as a first step toward possibly +converting to full text through character recognition, if the technology +is appropriate. WATERS also emphasized that encoding is involved even +with a set of images. + +SPERBERG-McQUEEN agreed with WATERS that one can create an SGML document +consisting wholly of images. At first sight, organizing graphic images +with an SGML document may not seem to offer great advantages, but the +advantages of the scheme WATERS described would be precisely that +ability to move into something that is more of a multimedia document: +a combination of transcribed text and page images. WEIBEL concurred in +this judgment, offering evidence from Project ADAPT, where a page is +divided into text elements and graphic elements, and in fact the text +elements are organized by columns and lines. These lines may be used as +the basis for distributing documents in a network environment. As one +develops software intelligent enough to recognize what those elements +are, it makes sense to apply SGML to an image initially, that may, in +fact, ultimately become more and more text, either through OCR or edited +OCR or even just through keying. For WATERS, the labor of composing the +document and saying this set of documents or this set of images belongs +to this document constitutes a significant investment. + +WEIBEL also made the point that the AAP tag sets, while not excessively +prescriptive, offer a common starting point; they do not define the +structure of the documents, though. They have some recommendations about +DTDs one could use as examples, but they do just suggest tag sets. For +example, the CORE project attempts to use the AAP markup as much as +possible, but there are clearly areas where structure must be added. +That in no way contradicts the use of AAP tag sets. + +SPERBERG-McQUEEN noted that the TEI prepared a long working paper early +on about the AAP tag set and what it lacked that the TEI thought it +needed, and a fairly long critique of the naming conventions, which has +led to a very different style of naming in the TEI. He stressed the +importance of the opposition between prescriptive markup, the kind that a +publisher or anybody can do when producing documents de novo, and +descriptive markup, in which one has to take what the text carrier +provides. In these particular tag sets it is easy to overemphasize this +opposition, because the AAP tag set is extremely flexible. Even if one +just used the DTDs, they allow almost anything to appear almost anywhere. + + ****** + +SESSION VI. COPYRIGHT ISSUES + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PETERS * Several cautions concerning copyright in an electronic +environment * Review of copyright law in the United States * The notion +of the public good and the desirability of incentives to promote it * +What copyright protects * Works not protected by copyright * The rights +of copyright holders * Publishers' concerns in today's electronic +environment * Compulsory licenses * The price of copyright in a digital +medium and the need for cooperation * Additional clarifications * Rough +justice oftentimes the outcome in numerous copyright matters * Copyright +in an electronic society * Copyright law always only sets up the +boundaries; anything can be changed by contract * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Marybeth PETERS, policy planning adviser to the Register of Copyrights, +Library of Congress, made several general comments and then opened the +floor to discussion of subjects of interest to the audience. + +Having attended several sessions in an effort to gain a sense of what +people did and where copyright would affect their lives, PETERS expressed +the following cautions: + + * If one takes and converts materials and puts them in new forms, + then, from a copyright point of view, one is creating something and + will receive some rights. + + * However, if what one is converting already exists, a question + immediately arises about the status of the materials in question. + + * Putting something in the public domain in the United States offers + some freedom from anxiety, but distributing it throughout the world + on a network is another matter, even if one has put it in the public + domain in the United States. Re foreign laws, very frequently a + work can be in the public domain in the United States but protected + in other countries. Thus, one must consider all of the places a + work may reach, lest one unwittingly become liable to being faced + with a suit for copyright infringement, or at least a letter + demanding discussion of what one is doing. + +PETERS reviewed copyright law in the United States. The U.S. +Constitution effectively states that Congress has the power to enact +copyright laws for two purposes: 1) to encourage the creation and +dissemination of intellectual works for the good of society as a whole; +and, significantly, 2) to give creators and those who package and +disseminate materials the economic rewards that are due them. + +Congress strives to strike a balance, which at times can become an +emotional issue. The United States has never accepted the notion of the +natural right of an author so much as it has accepted the notion of the +public good and the desirability of incentives to promote it. This state +of affairs, however, has created strains on the international level and +is the reason for several of the differences in the laws that we have. +Today the United States protects almost every kind of work that can be +called an expression of an author. The standard for gaining copyright +protection is simply originality. This is a low standard and means that +a work is not copied from something else, as well as shows a certain +minimal amount of authorship. One can also acquire copyright protection +for making a new version of preexisting material, provided it manifests +some spark of creativity. + +However, copyright does not protect ideas, methods, systems--only the way +that one expresses those things. Nor does copyright protect anything +that is mechanical, anything that does not involve choice, or criteria +concerning whether or not one should do a thing. For example, the +results of a process called declicking, in which one mechanically removes +impure sounds from old recordings, are not copyrightable. On the other +hand, the choice to record a song digitally and to increase the sound of +violins or to bring up the tympani constitutes the results of conversion +that are copyrightable. Moreover, if a work is protected by copyright in +the United States, one generally needs the permission of the copyright +owner to convert it. Normally, who will own the new--that is, converted- +-material is a matter of contract. In the absence of a contract, the +person who creates the new material is the author and owner. But people +do not generally think about the copyright implications until after the +fact. PETERS stressed the need when dealing with copyrighted works to +think about copyright in advance. One's bargaining power is much greater +up front than it is down the road. + +PETERS next discussed works not protected by copyright, for example, any +work done by a federal employee as part of his or her official duties is +in the public domain in the United States. The issue is not wholly free +of doubt concerning whether or not the work is in the public domain +outside the United States. Other materials in the public domain include: +any works published more than seventy-five years ago, and any work +published in the United States more than twenty-eight years ago, whose +copyright was not renewed. In talking about the new technology and +putting material in a digital form to send all over the world, PETERS +cautioned, one must keep in mind that while the rights may not be an +issue in the United States, they may be in different parts of the world, +where most countries previously employed a copyright term of the life of +the author plus fifty years. + +PETERS next reviewed the economics of copyright holding. Simply, +economic rights are the rights to control the reproduction of a work in +any form. They belong to the author, or in the case of a work made for +hire, the employer. The second right, which is critical to conversion, +is the right to change a work. The right to make new versions is perhaps +one of the most significant rights of authors, particularly in an +electronic world. The third right is the right to publish the work and +the right to disseminate it, something that everyone who deals in an +electronic medium needs to know. The basic rule is if a copy is sold, +all rights of distribution are extinguished with the sale of that copy. +The key is that it must be sold. A number of companies overcome this +obstacle by leasing or renting their product. These companies argue that +if the material is rented or leased and not sold, they control the uses +of a work. The fourth right, and one very important in a digital world, +is a right of public performance, which means the right to show the work +sequentially. For example, copyright owners control the showing of a +CD-ROM product in a public place such as a public library. The reverse +side of public performance is something called the right of public +display. Moral rights also exist, which at the federal level apply only +to very limited visual works of art, but in theory may apply under +contract and other principles. Moral rights may include the right of an +author to have his or her name on a work, the right of attribution, and +the right to object to distortion or mutilation--the right of integrity. + +The way copyright law is worded gives much latitude to activities such as +preservation; to use of material for scholarly and research purposes when +the user does not make multiple copies; and to the generation of +facsimile copies of unpublished works by libraries for themselves and +other libraries. But the law does not allow anyone to become the +distributor of the product for the entire world. In today's electronic +environment, publishers are extremely concerned that the entire world is +networked and can obtain the information desired from a single copy in a +single library. Hence, if there is to be only one sale, which publishers +may choose to live with, they will obtain their money in other ways, for +example, from access and use. Hence, the development of site licenses +and other kinds of agreements to cover what publishers believe they +should be compensated for. Any solution that the United States takes +today has to consider the international arena. + +Noting that the United States is a member of the Berne Convention and +subscribes to its provisions, PETERS described the permissions process. +She also defined compulsory licenses. A compulsory license, of which the +United States has had a few, builds into the law the right to use a work +subject to certain terms and conditions. In the international arena, +however, the ability to use compulsory licenses is extremely limited. +Thus, clearinghouses and other collectives comprise one option that has +succeeded in providing for use of a work. Often overlooked when one +begins to use copyrighted material and put products together is how +expensive the permissions process and managing it is. According to +PETERS, the price of copyright in a digital medium, whatever solution is +worked out, will include managing and assembling the database. She +strongly recommended that publishers and librarians or people with +various backgrounds cooperate to work out administratively feasible +systems, in order to produce better results. + +In the lengthy question-and-answer period that followed PETERS's +presentation, the following points emerged: + + * The Copyright Office maintains that anything mechanical and + totally exhaustive probably is not protected. In the event that + what an individual did in developing potentially copyrightable + material is not understood, the Copyright Office will ask about the + creative choices the applicant chose to make or not to make. As a + practical matter, if one believes she or he has made enough of those + choices, that person has a right to assert a copyright and someone + else must assert that the work is not copyrightable. The more + mechanical, the more automatic, a thing is, the less likely it is to + be copyrightable. + + * Nearly all photographs are deemed to be copyrightable, but no one + worries about them much, because everyone is free to take the same + image. Thus, a photographic copyright represents what is called a + "thin" copyright. The photograph itself must be duplicated, in + order for copyright to be violated. + + * The Copyright Office takes the position that X-rays are not + copyrightable because they are mechanical. It can be argued + whether or not image enhancement in scanning can be protected. One + must exercise care with material created with public funds and + generally in the public domain. An article written by a federal + employee, if written as part of official duties, is not + copyrightable. However, control over a scientific article written + by a National Institutes of Health grantee (i.e., someone who + receives money from the U.S. government), depends on NIH policy. If + the government agency has no policy (and that policy can be + contained in its regulations, the contract, or the grant), the + author retains copyright. If a provision of the contract, grant, or + regulation states that there will be no copyright, then it does not + exist. When a work is created, copyright automatically comes into + existence unless something exists that says it does not. + + * An enhanced electronic copy of a print copy of an older reference + work in the public domain that does not contain copyrightable new + material is a purely mechanical rendition of the original work, and + is not copyrightable. + + * Usually, when a work enters the public domain, nothing can remove + it. For example, Congress recently passed into law the concept of + automatic renewal, which means that copyright on any work published + between l964 and l978 does not have to be renewed in order to + receive a seventy-five-year term. But any work not renewed before + 1964 is in the public domain. + + * Concerning whether or not the United States keeps track of when + authors die, nothing was ever done, nor is anything being done at + the moment by the Copyright Office. + + * Software that drives a mechanical process is itself copyrightable. + If one changes platforms, the software itself has a copyright. The + World Intellectual Property Organization will hold a symposium 28 + March through 2 April l993, at Harvard University, on digital + technology, and will study this entire issue. If one purchases a + computer software package, such as MacPaint, and creates something + new, one receives protection only for that which has been added. + +PETERS added that often in copyright matters, rough justice is the +outcome, for example, in collective licensing, ASCAP (i.e., American +Society of Composers, Authors, and Publishers), and BMI (i.e., Broadcast +Music, Inc.), where it may seem that the big guys receive more than their +due. Of course, people ought not to copy a creative product without +paying for it; there should be some compensation. But the truth of the +world, and it is not a great truth, is that the big guy gets played on +the radio more frequently than the little guy, who has to do much more +until he becomes a big guy. That is true of every author, every +composer, everyone, and, unfortunately, is part of life. + +Copyright always originates with the author, except in cases of works +made for hire. (Most software falls into this category.) When an author +sends his article to a journal, he has not relinquished copyright, though +he retains the right to relinquish it. The author receives absolutely +everything. The less prominent the author, the more leverage the +publisher will have in contract negotiations. In order to transfer the +rights, the author must sign an agreement giving them away. + +In an electronic society, it is important to be able to license a writer +and work out deals. With regard to use of a work, it usually is much +easier when a publisher holds the rights. In an electronic era, a real +problem arises when one is digitizing and making information available. +PETERS referred again to electronic licensing clearinghouses. Copyright +ought to remain with the author, but as one moves forward globally in the +electronic arena, a middleman who can handle the various rights becomes +increasingly necessary. + +The notion of copyright law is that it resides with the individual, but +in an on-line environment, where a work can be adapted and tinkered with +by many individuals, there is concern. If changes are authorized and +there is no agreement to the contrary, the person who changes a work owns +the changes. To put it another way, the person who acquires permission +to change a work technically will become the author and the owner, unless +some agreement to the contrary has been made. It is typical for the +original publisher to try to control all of the versions and all of the +uses. Copyright law always only sets up the boundaries. Anything can be +changed by contract. + + ****** + +SESSION VII. CONCLUSION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GENERAL DISCUSSION * Two questions for discussion * Different emphases in +the Workshop * Bringing the text and image partisans together * +Desiderata in planning the long-term development of something * Questions +surrounding the issue of electronic deposit * Discussion of electronic +deposit as an allusion to the issue of standards * Need for a directory +of preservation projects in digital form and for access to their +digitized files * CETH's catalogue of machine-readable texts in the +humanities * What constitutes a publication in the electronic world? * +Need for LC to deal with the concept of on-line publishing * LC's Network +Development Office exploring the limits of MARC as a standard in terms +of handling electronic information * Magnitude of the problem and the +need for distributed responsibility in order to maintain and store +electronic information * Workshop participants to be viewed as a starting +point * Development of a network version of AM urged * A step toward AM's +construction of some sort of apparatus for network access * A delicate +and agonizing policy question for LC * Re the issue of electronic +deposit, LC urged to initiate a catalytic process in terms of distributed +responsibility * Suggestions for cooperative ventures * Commercial +publishers' fears * Strategic questions for getting the image and text +people to think through long-term cooperation * Clarification of the +driving force behind both the Perseus and the Cornell Xerox projects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In his role as moderator of the concluding session, GIFFORD raised two +questions he believed would benefit from discussion: 1) Are there enough +commonalities among those of us that have been here for two days so that +we can see courses of action that should be taken in the future? And, if +so, what are they and who might take them? 2) Partly derivative from +that, but obviously very dangerous to LC as host, do you see a role for +the Library of Congress in all this? Of course, the Library of Congress +holds a rather special status in a number of these matters, because it is +not perceived as a player with an economic stake in them, but are there +roles that LC can play that can help advance us toward where we are heading? + +Describing himself as an uninformed observer of the technicalities of the +last two days, GIFFORD detected three different emphases in the Workshop: +1) people who are very deeply committed to text; 2) people who are almost +passionate about images; and 3) a few people who are very committed to +what happens to the networks. In other words, the new networking +dimension, the accessibility of the processability, the portability of +all this across the networks. How do we pull those three together? + +Adding a question that reflected HOCKEY's comment that this was the +fourth workshop she had attended in the previous thirty days, FLEISCHHAUER +wondered to what extent this meeting had reinvented the wheel, or if it +had contributed anything in the way of bringing together a different group +of people from those who normally appear on the workshop circuit. + +HOCKEY confessed to being struck at this meeting and the one the +Electronic Pierce Consortium organized the previous week that this was a +coming together of people working on texts and not images. Attempting to +bring the two together is something we ought to be thinking about for the +future: How one can think about working with image material to begin +with, but structuring it and digitizing it in such a way that at a later +stage it can be interpreted into text, and find a common way of building +text and images together so that they can be used jointly in the future, +with the network support to begin there because that is how people will +want to access it. + +In planning the long-term development of something, which is what is +being done in electronic text, HOCKEY stressed the importance not only +of discussing the technical aspects of how one does it but particularly +of thinking about what the people who use the stuff will want to do. +But conversely, there are numerous things that people start to do with +electronic text or material that nobody ever thought of in the beginning. + +LESK, in response to the question concerning the role of the Library of +Congress, remarked the often suggested desideratum of having electronic +deposit: Since everything is now computer-typeset, an entire decade of +material that was machine-readable exists, but the publishers frequently +did not save it; has LC taken any action to have its copyright deposit +operation start collecting these machine-readable versions? In the +absence of PETERS, GIFFORD replied that the question was being +actively considered but that that was only one dimension of the problem. +Another dimension is the whole question of the integrity of the original +electronic document. It becomes highly important in science to prove +authorship. How will that be done? + +ERWAY explained that, under the old policy, to make a claim for a +copyright for works that were published in electronic form, including +software, one had to submit a paper copy of the first and last twenty +pages of code--something that represented the work but did not include +the entire work itself and had little value to anyone. As a temporary +measure, LC has claimed the right to demand electronic versions of +electronic publications. This measure entails a proactive role for the +Library to say that it wants a particular electronic version. Publishers +then have perhaps a year to submit it. But the real problem for LC is +what to do with all this material in all these different formats. Will +the Library mount it? How will it give people access to it? How does LC +keep track of the appropriate computers, software, and media? The situation +is so hard to control, ERWAY said, that it makes sense for each publishing +house to maintain its own archive. But LC cannot enforce that either. + +GIFFORD acknowledged LESK's suggestion that establishing a priority +offered the solution, albeit a fairly complicated one. But who maintains +that register?, he asked. GRABER noted that LC does attempt to collect a +Macintosh version and the IBM-compatible version of software. It does +not collect other versions. But while true for software, BYRUM observed, +this reply does not speak to materials, that is, all the materials that +were published that were on somebody's microcomputer or driver tapes +at a publishing office across the country. LC does well to acquire +specific machine-readable products selectively that were intended to be +machine-readable. Materials that were in machine-readable form at one time, +BYRUM said, would be beyond LC's capability at the moment, insofar as +attempting to acquire, organize, and preserve them are concerned--and +preservation would be the most important consideration. In this +connection, GIFFORD reiterated the need to work out some sense of +distributive responsibility for a number of these issues, which +inevitably will require significant cooperation and discussion. +Nobody can do it all. + +LESK suggested that some publishers may look with favor on LC beginning +to serve as a depository of tapes in an electronic manuscript standard. +Publishers may view this as a service that they did not have to perform +and they might send in tapes. However, SPERBERG-McQUEEN countered, +although publishers have had equivalent services available to them for a +long time, the electronic text archive has never turned away or been +flooded with tapes and is forever sending feedback to the depositor. +Some publishers do send in tapes. + +ANDRE viewed this discussion as an allusion to the issue of standards. +She recommended that the AAP standard and the TEI, which has already been +somewhat harmonized internationally and which also shares several +compatibilities with the AAP, be harmonized to ensure sufficient +compatibility in the software. She drew the line at saying LC ought to +be the locus or forum for such harmonization. + +Taking the group in a slightly different direction, but one where at +least in the near term LC might play a helpful role, LYNCH remarked the +plans of a number of projects to carry out preservation by creating +digital images that will end up in on-line or near-line storage at some +institution. Presumably, LC will link this material somehow to its +on-line catalog in most cases. Thus, it is in a digital form. LYNCH had +the impression that many of these institutions would be willing to make +those files accessible to other people outside the institution, provided +that there is no copyright problem. This desideratum will require +propagating the knowledge that those digitized files exist, so that they +can end up in other on-line catalogs. Although uncertain about the +mechanism for achieving this result, LYNCH said that it warranted +scrutiny because it seemed to be connected to some of the basic issues of +cataloging and distribution of records. It would be foolish, given the +amount of work that all of us have to do and our meager resources, to +discover multiple institutions digitizing the same work. Re microforms, +LYNCH said, we are in pretty good shape. + +BATTIN called this a big problem and noted that the Cornell people (who +had already departed) were working on it. At issue from the beginning +was to learn how to catalog that information into RLIN and then into +OCLC, so that it would be accessible. That issue remains to be resolved. +LYNCH rejoined that putting it into OCLC or RLIN was helpful insofar as +somebody who is thinking of performing preservation activity on that work +could learn about it. It is not necessarily helpful for institutions to +make that available. BATTIN opined that the idea was that it not only be +for preservation purposes but for the convenience of people looking for +this material. She endorsed LYNCH's dictum that duplication of this +effort was to be avoided by every means. + +HOCKEY informed the Workshop about one major current activity of CETH, +namely a catalogue of machine-readable texts in the humanities. Held on +RLIN at present, the catalogue has been concentrated on ASCII as opposed +to digitized images of text. She is exploring ways to improve the +catalogue and make it more widely available, and welcomed suggestions +about these concerns. CETH owns the records, which are not just +restricted to RLIN, and can distribute them however it wishes. + +Taking up LESK's earlier question, BATTIN inquired whether LC, since it +is accepting electronic files and designing a mechanism for dealing with +that rather than putting books on shelves, would become responsible for +the National Copyright Depository of Electronic Materials. Of course +that could not be accomplished overnight, but it would be something LC +could plan for. GIFFORD acknowledged that much thought was being devoted +to that set of problems and returned the discussion to the issue raised +by LYNCH--whether or not putting the kind of records that both BATTIN and +HOCKEY have been talking about in RLIN is not a satisfactory solution. +It seemed to him that RLIN answered LYNCH's original point concerning +some kind of directory for these kinds of materials. In a situation +where somebody is attempting to decide whether or not to scan this or +film that or to learn whether or not someone has already done so, LYNCH +suggested, RLIN is helpful, but it is not helpful in the case of a local, +on-line catalogue. Further, one would like to have her or his system be +aware that that exists in digital form, so that one can present it to a +patron, even though one did not digitize it, if it is out of copyright. +The only way to make those linkages would be to perform a tremendous +amount of real-time look-up, which would be awkward at best, or +periodically to yank the whole file from RLIN and match it against one's +own stuff, which is a nuisance. + +But where, ERWAY inquired, does one stop including things that are +available with Internet, for instance, in one's local catalogue? +It almost seems that that is LC's means to acquire access to them. +That represents LC's new form of library loan. Perhaps LC's new on-line +catalogue is an amalgamation of all these catalogues on line. LYNCH +conceded that perhaps that was true in the very long term, but was not +applicable to scanning in the short term. In his view, the totals cited +by Yale, 10,000 books over perhaps a four-year period, and 1,000-1,500 +books from Cornell, were not big numbers, while searching all over +creation for relatively rare occurrences will prove to be less efficient. +As GIFFORD wondered if this would not be a separable file on RLIN and +could be requested from them, BATTIN interjected that it was easily +accessible to an institution. SEVERTSON pointed out that that file, cum +enhancements, was available with reference information on CD-ROM, which +makes it a little more available. + +In HOCKEY's view, the real question facing the Workshop is what to put in +this catalogue, because that raises the question of what constitutes a +publication in the electronic world. (WEIBEL interjected that Eric Joule +in OCLC's Office of Research is also wrestling with this particular +problem, while GIFFORD thought it sounded fairly generic.) HOCKEY +contended that a majority of texts in the humanities are in the hands +of either a small number of large research institutions or individuals +and are not generally available for anyone else to access at all. +She wondered if these texts ought to be catalogued. + +After argument proceeded back and forth for several minutes over why +cataloguing might be a necessary service, LEBRON suggested that this +issue involved the responsibility of a publisher. The fact that someone +has created something electronically and keeps it under his or her +control does not constitute publication. Publication implies +dissemination. While it would be important for a scholar to let other +people know that this creation exists, in many respects this is no +different from an unpublished manuscript. That is what is being accessed +in there, except that now one is not looking at it in the hard-copy but +in the electronic environment. + +LEBRON expressed puzzlement at the variety of ways electronic publishing +has been viewed. Much of what has been discussed throughout these two +days has concerned CD-ROM publishing, whereas in the on-line environment +that she confronts, the constraints and challenges are very different. +Sooner or later LC will have to deal with the concept of on-line +publishing. Taking up the comment ERWAY made earlier about storing +copies, LEBRON gave her own journal as an example. How would she deposit +OJCCT for copyright?, she asked, because the journal will exist in the +mainframe at OCLC and people will be able to access it. Here the +situation is different, ownership versus access, and is something that +arises with publication in the on-line environment, faster than is +sometimes realized. Lacking clear answers to all of these questions +herself, LEBRON did not anticipate that LC would be able to take a role +in helping to define some of them for quite a while. + +GREENFIELD observed that LC's Network Development Office is attempting, +among other things, to explore the limits of MARC as a standard in terms +of handling electronic information. GREENFIELD also noted that Rebecca +GUENTHER from that office gave a paper to the American Society for +Information Science (ASIS) summarizing several of the discussion papers +that were coming out of the Network Development Office. GREENFIELD said +he understood that that office had a list-server soliciting just the kind +of feedback received today concerning the difficulties of identifying and +cataloguing electronic information. GREENFIELD hoped that everybody +would be aware of that and somehow contribute to that conversation. + +Noting two of LC's roles, first, to act as a repository of record for +material that is copyrighted in this country, and second, to make +materials it holds available in some limited form to a clientele that +goes beyond Congress, BESSER suggested that it was incumbent on LC to +extend those responsibilities to all the things being published in +electronic form. This would mean eventually accepting electronic +formats. LC could require that at some point they be in a certain +limited set of formats, and then develop mechanisms for allowing people +to access those in the same way that other things are accessed. This +does not imply that they are on the network and available to everyone. +LC does that with most of its bibliographic records, BESSER said, which +end up migrating to the utility (e.g., OCLC) or somewhere else. But just +as most of LC's books are available in some form through interlibrary +loan or some other mechanism, so in the same way electronic formats ought +to be available to others in some format, though with some copyright +considerations. BESSER was not suggesting that these mechanisms be +established tomorrow, only that they seemed to fall within LC's purview, +and that there should be long-range plans to establish them. + +Acknowledging that those from LC in the room agreed with BESSER +concerning the need to confront difficult questions, GIFFORD underscored +the magnitude of the problem of what to keep and what to select. GIFFORD +noted that LC currently receives some 31,000 items per day, not counting +electronic materials, and argued for much more distributed responsibility +in order to maintain and store electronic information. + +BESSER responded that the assembled group could be viewed as a starting +point, whose initial operating premise could be helping to move in this +direction and defining how LC could do so, for example, in areas of +standardization or distribution of responsibility. + +FLEISCHHAUER added that AM was fully engaged, wrestling with some of the +questions that pertain to the conversion of older historical materials, +which would be one thing that the Library of Congress might do. Several +points mentioned by BESSER and several others on this question have a +much greater impact on those who are concerned with cataloguing and the +networking of bibliographic information, as well as preservation itself. + +Speaking directly to AM, which he considered was a largely uncopyrighted +database, LYNCH urged development of a network version of AM, or +consideration of making the data in it available to people interested in +doing network multimedia. On account of the current great shortage of +digital data that is both appealing and unencumbered by complex rights +problems, this course of action could have a significant effect on making +network multimedia a reality. + +In this connection, FLEISCHHAUER reported on a fragmentary prototype in +LC's Office of Information Technology Services that attempts to associate +digital images of photographs with cataloguing information in ways that +work within a local area network--a step, so to say, toward AM's +construction of some sort of apparatus for access. Further, AM has +attempted to use standard data forms in order to help make that +distinction between the access tools and the underlying data, and thus +believes that the database is networkable. + +A delicate and agonizing policy question for LC, however, which comes +back to resources and unfortunately has an impact on this, is to find +some appropriate, honorable, and legal cost-recovery possibilities. A +certain skittishness concerning cost-recovery has made people unsure +exactly what to do. AM would be highly receptive to discussing further +LYNCH's offer to test or demonstrate its database in a network +environment, FLEISCHHAUER said. + +Returning the discussion to what she viewed as the vital issue of +electronic deposit, BATTIN recommended that LC initiate a catalytic +process in terms of distributed responsibility, that is, bring together +the distributed organizations and set up a study group to look at all +these issues and see where we as a nation should move. The broader +issues of how we deal with the management of electronic information will +not disappear, but only grow worse. + +LESK took up this theme and suggested that LC attempt to persuade one +major library in each state to deal with its state equivalent publisher, +which might produce a cooperative project that would be equitably +distributed around the country, and one in which LC would be dealing with +a minimal number of publishers and minimal copyright problems. + +GRABER remarked the recent development in the scientific community of a +willingness to use SGML and either deposit or interchange on a fairly +standardized format. He wondered if a similar movement was taking place +in the humanities. Although the National Library of Medicine found only +a few publishers to cooperate in a like venture two or three years ago, a +new effort might generate a much larger number willing to cooperate. + +KIMBALL recounted his unit's (Machine-Readable Collections Reading Room) +troubles with the commercial publishers of electronic media in acquiring +materials for LC's collections, in particular the publishers' fear that +they would not be able to cover their costs and would lose control of +their products, that LC would give them away or sell them and make +profits from them. He doubted that the publishing industry was prepared +to move into this area at the moment, given its resistance to allowing LC +to use its machine-readable materials as the Library would like. + +The copyright law now addresses compact disk as a medium, and LC can +request one copy of that, or two copies if it is the only version, and +can request copies of software, but that fails to address magazines or +books or anything like that which is in machine-readable form. + +GIFFORD acknowledged the thorny nature of this issue, which he illustrated +with the example of the cumbersome process involved in putting a copy of a +scientific database on a LAN in LC's science reading room. He also +acknowledged that LC needs help and could enlist the energies and talents +of Workshop participants in thinking through a number of these problems. + +GIFFORD returned the discussion to getting the image and text people to +think through together where they want to go in the long term. MYLONAS +conceded that her experience at the Pierce Symposium the previous week at +Georgetown University and this week at LC had forced her to reevaluate +her perspective on the usefulness of text as images. MYLONAS framed the +issues in a series of questions: How do we acquire machine-readable +text? Do we take pictures of it and perform OCR on it later? Is it +important to obtain very high-quality images and text, etc.? +FLEISCHHAUER agreed with MYLONAS's framing of strategic questions, adding +that a large institution such as LC probably has to do all of those +things at different times. Thus, the trick is to exercise judgment. The +Workshop had added to his and AM's considerations in making those +judgments. Concerning future meetings or discussions, MYLONAS suggested +that screening priorities would be helpful. + +WEIBEL opined that the diversity reflected in this group was a sign both +of the health and of the immaturity of the field, and more time would +have to pass before we convince one another concerning standards. + +An exchange between MYLONAS and BATTIN clarified the point that the +driving force behind both the Perseus and the Cornell Xerox projects was +the preservation of knowledge for the future, not simply for particular +research use. In the case of Perseus, MYLONAS said, the assumption was +that the texts would not be entered again into electronically readable +form. SPERBERG-McQUEEN added that a scanned image would not serve as an +archival copy for purposes of preservation in the case of, say, the Bill +of Rights, in the sense that the scanned images are effectively the +archival copies for the Cornell mathematics books. + + + *** *** *** ****** *** *** *** + + + Appendix I: PROGRAM + + + + WORKSHOP + ON + ELECTRONIC + TEXTS + + + + 9-10 June 1992 + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + +Tuesday, 9 June 1992 + +NATIONAL DEMONSTRATION LAB, ATRIUM, LIBRARY MADISON + +8:30 AM Coffee and Danish, registration + +9:00 AM Welcome + + Prosser Gifford, Director for Scholarly Programs, and Carl + Fleischhauer, Coordinator, American Memory, Library of + Congress + +9:l5 AM Session I. Content in a New Form: Who Will Use It and What + Will They Do? + + Broad description of the range of electronic information. + Characterization of who uses it and how it is or may be used. + In addition to a look at scholarly uses, this session will + include a presentation on use by students (K-12 and college) + and the general public. + + Moderator: James Daly + Avra Michelson, Archival Research and Evaluation Staff, + National Archives and Records Administration (Overview) + Susan H. Veccia, Team Leader, American Memory, User Evaluation, + and + Joanne Freeman, Associate Coordinator, American Memory, Library + of Congress (Beyond the scholar) + +10:30- +11:00 AM Break + +11:00 AM Session II. Show and Tell. + + Each presentation to consist of a fifteen-minute + statement/show; group discussion will follow lunch. + + Moderator: Jacqueline Hess, Director, National Demonstration + Lab + + 1. A classics project, stressing texts and text retrieval + more than multimedia: Perseus Project, Harvard + University + Elli Mylonas, Managing Editor + + 2. Other humanities projects employing the emerging norms of + the Text Encoding Initiative (TEI): Chadwyck-Healey's + The English Poetry Full Text Database and/or Patrologia + Latina Database + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + + 3. American Memory + Carl Fleischhauer, Coordinator, and + Ricky Erway, Associate Coordinator, Library of Congress + + 4. Founding Fathers example from Packard Humanities + Institute: The Papers of George Washington, University + of Virginia + Dorothy Twohig, Managing Editor, and/or + David Woodley Packard + + 5. An electronic medical journal offering graphics and + full-text searchability: The Online Journal of Current + Clinical Trials, American Association for the Advancement + of Science + Maria L. Lebron, Managing Editor + + 6. A project that offers facsimile images of pages but omits + searchable text: Cornell math books + Lynne K. Personius, Assistant Director, Cornell + Information Technologies for Scholarly Information + Sources, Cornell University + +12:30 PM Lunch (Dining Room A, Library Madison 620. Exhibits + available.) + +1:30 PM Session II. Show and Tell (Cont'd.). + +3:00- +3:30 PM Break + +3:30- +5:30 PM Session III. Distribution, Networks, and Networking: Options + for Dissemination. + + Published disks: University presses and public-sector + publishers, private-sector publishers + Computer networks + + Moderator: Robert G. Zich, Special Assistant to the Associate + Librarian for Special Projects, Library of Congress + Clifford A. Lynch, Director, Library Automation, University of + California + Howard Besser, School of Library and Information Science, + University of Pittsburgh + Ronald L. Larsen, Associate Director of Libraries for + Information Technology, University of Maryland at College + Park + Edwin B. Brownrigg, Executive Director, Memex Research + Institute + +6:30 PM Reception (Montpelier Room, Library Madison 619.) + + ****** + +Wednesday, 10 June 1992 + +DINING ROOM A, LIBRARY MADISON 620 + +8:30 AM Coffee and Danish + +9:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats. + + Moderator: William L. Hooton, Vice President of Operations, + I-NET + + A) Principal Methods for Image Capture of Text: + Direct scanning + Use of microform + + Anne R. Kenney, Assistant Director, Department of Preservation + and Conservation, Cornell University + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + Donald J. Waters, Head, Systems Office, Yale University Library + + B) Special Problems: + Bound volumes + Conservation + Reproducing printed halftones + + Carl Fleischhauer, Coordinator, American Memory, Library of + Congress + George Thoma, Chief, Communications Engineering Branch, + National Library of Medicine (NLM) + +10:30- +11:00 AM Break + +11:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats (Cont'd.). + + C) Image Standards and Implications for Preservation + + Jean Baronas, Senior Manager, Department of Standards and + Technology, Association for Information and Image Management + (AIIM) + Patricia Battin, President, The Commission on Preservation and + Access (CPA) + + D) Text Conversion: + OCR vs. rekeying + Standards of accuracy and use of imperfect texts + Service bureaus + + Stuart Weibel, Senior Research Specialist, Online Computer + Library Center, Inc. (OCLC) + Michael Lesk, Executive Director, Computer Science Research, + Bellcore + Ricky Erway, Associate Coordinator, American Memory, Library of + Congress + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + +12:30- +1:30 PM Lunch + +1:30 PM Session V. Approaches to Preparing Electronic Texts. + + Discussion of approaches to structuring text for the computer; + pros and cons of text coding, description of methods in + practice, and comparison of text-coding methods. + + Moderator: Susan Hockey, Director, Center for Electronic Texts + in the Humanities (CETH), Rutgers and Princeton Universities + David Woodley Packard + C.M. Sperberg-McQueen, Editor, Text Encoding Initiative (TEI), + University of Illinois-Chicago + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + +3:30- +4:00 PM Break + +4:00 PM Session VI. Copyright Issues. + + Marybeth Peters, Policy Planning Adviser to the Register of + Copyrights, Library of Congress + +5:00 PM Session VII. Conclusion. + + General discussion. + What topics were omitted or given short shrift that anyone + would like to talk about now? + Is there a "group" here? What should the group do next, if + anything? What should the Library of Congress do next, if + anything? + Moderator: Prosser Gifford, Director for Scholarly Programs, + Library of Congress + +6:00 PM Adjourn + + + *** *** *** ****** *** *** *** + + + Appendix II: ABSTRACTS + + +SESSION I + +Avra MICHELSON Forecasting the Use of Electronic Texts by + Social Sciences and Humanities Scholars + +This presentation explores the ways in which electronic texts are likely +to be used by the non-scientific scholarly community. Many of the +remarks are drawn from a report the speaker coauthored with Jeff +Rothenberg, a computer scientist at The RAND Corporation. + +The speaker assesses 1) current scholarly use of information technology +and 2) the key trends in information technology most relevant to the +research process, in order to predict how social sciences and humanities +scholars are apt to use electronic texts. In introducing the topic, +current use of electronic texts is explored broadly within the context of +scholarly communication. From the perspective of scholarly +communication, the work of humanities and social sciences scholars +involves five processes: 1) identification of sources, 2) communication +with colleagues, 3) interpretation and analysis of data, 4) dissemination +of research findings, and 5) curriculum development and instruction. The +extent to which computation currently permeates aspects of scholarly +communication represents a viable indicator of the prospects for +electronic texts. + +The discussion of current practice is balanced by an analysis of key +trends in the scholarly use of information technology. These include the +trends toward end-user computing and connectivity, which provide a +framework for forecasting the use of electronic texts through this +millennium. The presentation concludes with a summary of the ways in +which the nonscientific scholarly community can be expected to use +electronic texts, and the implications of that use for information +providers. + +Susan VECCIA and Joanne FREEMAN Electronic Archives for the Public: + Use of American Memory in Public and + School Libraries + +This joint discussion focuses on nonscholarly applications of electronic +library materials, specifically addressing use of the Library of Congress +American Memory (AM) program in a small number of public and school +libraries throughout the United States. AM consists of selected Library +of Congress primary archival materials, stored on optical media +(CD-ROM/videodisc), and presented with little or no editing. Many +collections are accompanied by electronic introductions and user's guides +offering background information and historical context. Collections +represent a variety of formats including photographs, graphic arts, +motion pictures, recorded sound, music, broadsides and manuscripts, +books, and pamphlets. + +In 1991, the Library of Congress began a nationwide evaluation of AM in +different types of institutions. Test sites include public libraries, +elementary and secondary school libraries, college and university +libraries, state libraries, and special libraries. Susan VECCIA and +Joanne FREEMAN will discuss their observations on the use of AM by the +nonscholarly community, using evidence gleaned from this ongoing +evaluation effort. + +VECCIA will comment on the overall goals of the evaluation project, and +the types of public and school libraries included in this study. Her +comments on nonscholarly use of AM will focus on the public library as a +cultural and community institution, often bridging the gap between formal +and informal education. FREEMAN will discuss the use of AM in school +libraries. Use by students and teachers has revealed some broad +questions about the use of electronic resources, as well as definite +benefits gained by the "nonscholar." Topics will include the problem of +grasping content and context in an electronic environment, the stumbling +blocks created by "new" technologies, and the unique skills and interests +awakened through use of electronic resources. + +SESSION II + +Elli MYLONAS The Perseus Project: Interactive Sources and + Studies in Classical Greece + +The Perseus Project (5) has just released Perseus 1.0, the first publicly +available version of its hypertextual database of multimedia materials on +classical Greece. Perseus is designed to be used by a wide audience, +comprised of readers at the student and scholar levels. As such, it must +be able to locate information using different strategies, and it must +contain enough detail to serve the different needs of its users. In +addition, it must be delivered so that it is affordable to its target +audience. [These problems and the solutions we chose are described in +Mylonas, "An Interface to Classical Greek Civilization," JASIS 43:2, +March 1992.] + +In order to achieve its objective, the project staff decided to make a +conscious separation between selecting and converting textual, database, +and image data on the one hand, and putting it into a delivery system on +the other. That way, it is possible to create the electronic data +without thinking about the restrictions of the delivery system. We have +made a great effort to choose system-independent formats for our data, +and to put as much thought and work as possible into structuring it so +that the translation from paper to electronic form will enhance the value +of the data. [A discussion of these solutions as of two years ago is in +Elli Mylonas, Gregory Crane, Kenneth Morrell, and D. Neel Smith, "The +Perseus Project: Data in the Electronic Age," in Accessing Antiquity: +The Computerization of Classical Databases, J. Solomon and T. Worthen +(eds.), University of Arizona Press, in press.] + +Much of the work on Perseus is focused on collecting and converting the +data on which the project is based. At the same time, it is necessary to +provide means of access to the information, in order to make it usable, +and them to investigate how it is used. As we learn more about what +students and scholars from different backgrounds do with Perseus, we can +adjust our data collection, and also modify the system to accommodate +them. In creating a delivery system for general use, we have tried to +avoid favoring any one type of use by allowing multiple forms of access +to and navigation through the system. + +The way text is handled exemplifies some of these principles. All text +in Perseus is tagged using SGML, following the guidelines of the Text +Encoding Initiative (TEI). This markup is used to index the text, and +process it so that it can be imported into HyperCard. No SGML markup +remains in the text that reaches the user, because currently it would be +too expensive to create a system that acts on SGML in real time. +However, the regularity provided by SGML is essential for verifying the +content of the texts, and greatly speeds all the processing performed on +them. The fact that the texts exist in SGML ensures that they will be +relatively easy to port to different hardware and software, and so will +outlast the current delivery platform. Finally, the SGML markup +incorporates existing canonical reference systems (chapter, verse, line, +etc.); indexing and navigation are based on these features. This ensures +that the same canonical reference will always resolve to the same point +within a text, and that all versions of our texts, regardless of delivery +platform (even paper printouts) will function the same way. + +In order to provide tools for users, the text is processed by a +morphological analyzer, and the results are stored in a database. +Together with the index, the Greek-English Lexicon, and the index of all +the English words in the definitions of the lexicon, the morphological +analyses comprise a set of linguistic tools that allow users of all +levels to work with the textual information, and to accomplish different +tasks. For example, students who read no Greek may explore a concept as +it appears in Greek texts by using the English-Greek index, and then +looking up works in the texts and translations, or scholars may do +detailed morphological studies of word use by using the morphological +analyses of the texts. Because these tools were not designed for any one +use, the same tools and the same data can be used by both students and +scholars. + +NOTES: + (5) Perseus is based at Harvard University, with collaborators at + several other universities. The project has been funded primarily + by the Annenberg/CPB Project, as well as by Harvard University, + Apple Computer, and others. It is published by Yale University + Press. Perseus runs on Macintosh computers, under the HyperCard + program. + +Eric CALALUCA + +Chadwyck-Healey embarked last year on two distinct yet related full-text +humanities database projects. + +The English Poetry Full-Text Database and the Patrologia Latina Database +represent new approaches to linguistic research resources. The size and +complexity of the projects present problems for electronic publishers, +but surmountable ones if they remain abreast of the latest possibilities +in data capture and retrieval software techniques. + +The issues which required address prior to the commencement of the +projects were legion: + + 1. Editorial selection (or exclusion) of materials in each + database + + 2. Deciding whether or not to incorporate a normative encoding + structure into the databases? + A. If one is selected, should it be SGML? + B. If SGML, then the TEI? + + 3. Deliver as CD-ROM, magnetic tape, or both? + + 4. Can one produce retrieval software advanced enough for the + postdoctoral linguist, yet accessible enough for unattended + general use? Should one try? + + 5. Re fair and liberal networking policies, what are the risks to + an electronic publisher? + + 6. How does the emergence of national and international education + networks affect the use and viability of research projects + requiring high investment? Do the new European Community + directives concerning database protection necessitate two + distinct publishing projects, one for North America and one for + overseas? + +From new notions of "scholarly fair use" to the future of optical media, +virtually every issue related to electronic publishing was aired. The +result is two projects which have been constructed to provide the quality +research resources with the fewest encumbrances to use by teachers and +private scholars. + +Dorothy TWOHIG + +In spring 1988 the editors of the papers of George Washington, John +Adams, Thomas Jefferson, James Madison, and Benjamin Franklin were +approached by classics scholar David Packard on behalf of the Packard +Humanities Foundation with a proposal to produce a CD-ROM edition of the +complete papers of each of the Founding Fathers. This electronic edition +will supplement the published volumes, making the documents widely +available to students and researchers at reasonable cost. We estimate +that our CD-ROM edition of Washington's Papers will be substantially +completed within the next two years and ready for publication. Within +the next ten years or so, similar CD-ROM editions of the Franklin, Adams, +Jefferson, and Madison papers also will be available. At the Library of +Congress's session on technology, I would like to discuss not only the +experience of the Washington Papers in producing the CD-ROM edition, but +the impact technology has had on these major editorial projects. +Already, we are editing our volumes with an eye to the material that will +be readily available in the CD-ROM edition. The completed electronic +edition will provide immense possibilities for the searching of documents +for information in a way never possible before. The kind of technical +innovations that are currently available and on the drawing board will +soon revolutionize historical research and the production of historical +documents. Unfortunately, much of this new technology is not being used +in the planning stages of historical projects, simply because many +historians are aware only in the vaguest way of its existence. At least +two major new historical editing projects are considering microfilm +editions, simply because they are not aware of the possibilities of +electronic alternatives and the advantages of the new technology in terms +of flexibility and research potential compared to microfilm. In fact, +too many of us in history and literature are still at the stage of +struggling with our PCs. There are many historical editorial projects in +progress presently, and an equal number of literary projects. While the +two fields have somewhat different approaches to textual editing, there +are ways in which electronic technology can be of service to both. + +Since few of the editors involved in the Founding Fathers CD-ROM editions +are technical experts in any sense, I hope to point out in my discussion +of our experience how many of these electronic innovations can be used +successfully by scholars who are novices in the world of new technology. +One of the major concerns of the sponsors of the multitude of new +scholarly editions is the limited audience reached by the published +volumes. Most of these editions are being published in small quantities +and the publishers' price for them puts them out of the reach not only of +individual scholars but of most public libraries and all but the largest +educational institutions. However, little attention is being given to +ways in which technology can bypass conventional publication to make +historical and literary documents more widely available. + +What attracted us most to the CD-ROM edition of The Papers of George +Washington was the fact that David Packard's aim was to make a complete +edition of all of the 135,000 documents we have collected available in an +inexpensive format that would be placed in public libraries, small +colleges, and even high schools. This would provide an audience far +beyond our present 1,000-copy, $45 published edition. Since the CD-ROM +edition will carry none of the explanatory annotation that appears in the +published volumes, we also feel that the use of the CD-ROM will lead many +researchers to seek out the published volumes. + +In addition to ignorance of new technical advances, I have found that too +many editors--and historians and literary scholars--are resistant and +even hostile to suggestions that electronic technology may enhance their +work. I intend to discuss some of the arguments traditionalists are +advancing to resist technology, ranging from distrust of the speed with +which it changes (we are already wondering what is out there that is +better than CD-ROM) to suspicion of the technical language used to +describe electronic developments. + +Maria LEBRON + +The Online Journal of Current Clinical Trials, a joint venture of the +American Association for the Advancement of Science (AAAS) and the Online +Computer Library Center, Inc. (OCLC), is the first peer-reviewed journal +to provide full text, tabular material, and line illustrations on line. +This presentation will discuss the genesis and start-up period of the +journal. Topics of discussion will include historical overview, +day-to-day management of the editorial peer review, and manuscript +tagging and publication. A demonstration of the journal and its features +will accompany the presentation. + +Lynne PERSONIUS + +Cornell University Library, Cornell Information Technologies, and Xerox +Corporation, with the support of the Commission on Preservation and +Access, and Sun Microsystems, Inc., have been collaborating in a project +to test a prototype system for recording brittle books as digital images +and producing, on demand, high-quality archival paper replacements. The +project goes beyond that, however, to investigate some of the issues +surrounding scanning, storing, retrieving, and providing access to +digital images in a network environment. + +The Joint Study in Digital Preservation began in January 1990. Xerox +provided the College Library Access and Storage System (CLASS) software, +a prototype 600-dots-per-inch (dpi) scanner, and the hardware necessary +to support network printing on the DocuTech printer housed in Cornell's +Computing and Communications Center (CCC). + +The Cornell staff using the hardware and software became an integral part +of the development and testing process for enhancements to the CLASS +software system. The collaborative nature of this relationship is +resulting in a system that is specifically tailored to the preservation +application. + +A digital library of 1,000 volumes (or approximately 300,000 images) has +been created and is stored on an optical jukebox that resides in CCC. +The library includes a collection of select mathematics monographs that +provides mathematics faculty with an opportunity to use the electronic +library. The remaining volumes were chosen for the library to test the +various capabilities of the scanning system. + +One project objective is to provide users of the Cornell library and the +library staff with the ability to request facsimiles of digitized images +or to retrieve the actual electronic image for browsing. A prototype +viewing workstation has been created by Xerox, with input into the design +by a committee of Cornell librarians and computer professionals. This +will allow us to experiment with patron access to the images that make up +the digital library. The viewing station provides search, retrieval, and +(ultimately) printing functions with enhancements to facilitate +navigation through multiple documents. + +Cornell currently is working to extend access to the digital library to +readers using workstations from their offices. This year is devoted to +the development of a network resident image conversion and delivery +server, and client software that will support readers who use Apple +Macintosh computers, IBM windows platforms, and Sun workstations. +Equipment for this development was provided by Sun Microsystems with +support from the Commission on Preservation and Access. + +During the show-and-tell session of the Workshop on Electronic Texts, a +prototype view station will be demonstrated. In addition, a display of +original library books that have been digitized will be available for +review with associated printed copies for comparison. The fifteen-minute +overview of the project will include a slide presentation that +constitutes a "tour" of the preservation digitizing process. + +The final network-connected version of the viewing station will provide +library users with another mechanism for accessing the digital library, +and will also provide the capability of viewing images directly. This +will not require special software, although a powerful computer with good +graphics will be needed. + +The Joint Study in Digital Preservation has generated a great deal of +interest in the library community. Unfortunately, or perhaps +fortunately, this project serves to raise a vast number of other issues +surrounding the use of digital technology for the preservation and use of +deteriorating library materials, which subsequent projects will need to +examine. Much work remains. + +SESSION III + +Howard BESSER Networking Multimedia Databases + +What do we have to consider in building and distributing databases of +visual materials in a multi-user environment? This presentation examines +a variety of concerns that need to be addressed before a multimedia +database can be set up in a networked environment. + +In the past it has not been feasible to implement databases of visual +materials in shared-user environments because of technological barriers. +Each of the two basic models for multi-user multimedia databases has +posed its own problem. The analog multimedia storage model (represented +by Project Athena's parallel analog and digital networks) has required an +incredibly complex (and expensive) infrastructure. The economies of +scale that make multi-user setups cheaper per user served do not operate +in an environment that requires a computer workstation, videodisc player, +and two display devices for each user. + +The digital multimedia storage model has required vast amounts of storage +space (as much as one gigabyte per thirty still images). In the past the +cost of such a large amount of storage space made this model a +prohibitive choice as well. But plunging storage costs are finally +making this second alternative viable. + +If storage no longer poses such an impediment, what do we need to +consider in building digitally stored multi-user databases of visual +materials? This presentation will examine the networking and +telecommunication constraints that must be overcome before such databases +can become commonplace and useful to a large number of people. + +The key problem is the vast size of multimedia documents, and how this +affects not only storage but telecommunications transmission time. +Anything slower than T-1 speed is impractical for files of 1 megabyte or +larger (which is likely to be small for a multimedia document). For +instance, even on a 56 Kb line it would take three minutes to transfer a +1-megabyte file. And these figures assume ideal circumstances, and do +not take into consideration other users contending for network bandwidth, +disk access time, or the time needed for remote display. Current common +telephone transmission rates would be completely impractical; few users +would be willing to wait the hour necessary to transmit a single image at +2400 baud. + +This necessitates compression, which itself raises a number of other +issues. In order to decrease file sizes significantly, we must employ +lossy compression algorithms. But how much quality can we afford to +lose? To date there has been only one significant study done of +image-quality needs for a particular user group, and this study did not +look at loss resulting from compression. Only after identifying +image-quality needs can we begin to address storage and network bandwidth +needs. + +Experience with X-Windows-based applications (such as Imagequery, the +University of California at Berkeley image database) demonstrates the +utility of a client-server topology, but also points to the limitation of +current software for a distributed environment. For example, +applications like Imagequery can incorporate compression, but current X +implementations do not permit decompression at the end user's +workstation. Such decompression at the host computer alleviates storage +capacity problems while doing nothing to address problems of +telecommunications bandwidth. + +We need to examine the effects on network through-put of moving +multimedia documents around on a network. We need to examine various +topologies that will help us avoid bottlenecks around servers and +gateways. Experience with applications such as these raise still broader +questions. How closely is the multimedia document tied to the software +for viewing it? Can it be accessed and viewed from other applications? +Experience with the MARC format (and more recently with the Z39.50 +protocols) shows how useful it can be to store documents in a form in +which they can be accessed by a variety of application software. + +Finally, from an intellectual-access standpoint, we need to address the +issue of providing access to these multimedia documents in +interdisciplinary environments. We need to examine terminology and +indexing strategies that will allow us to provide access to this material +in a cross-disciplinary way. + +Ronald LARSEN Directions in High-Performance Networking for + Libraries + +The pace at which computing technology has advanced over the past forty +years shows no sign of abating. Roughly speaking, each five-year period +has yielded an order-of-magnitude improvement in price and performance of +computing equipment. No fundamental hurdles are likely to prevent this +pace from continuing for at least the next decade. It is only in the +past five years, though, that computing has become ubiquitous in +libraries, affecting all staff and patrons, directly or indirectly. + +During these same five years, communications rates on the Internet, the +principal academic computing network, have grown from 56 kbps to 1.5 +Mbps, and the NSFNet backbone is now running 45 Mbps. Over the next five +years, communication rates on the backbone are expected to exceed 1 Gbps. +Growth in both the population of network users and the volume of network +traffic has continued to grow geometrically, at rates approaching 15 +percent per month. This flood of capacity and use, likened by some to +"drinking from a firehose," creates immense opportunities and challenges +for libraries. Libraries must anticipate the future implications of this +technology, participate in its development, and deploy it to ensure +access to the world's information resources. + +The infrastructure for the information age is being put in place. +Libraries face strategic decisions about their role in the development, +deployment, and use of this infrastructure. The emerging infrastructure +is much more than computers and communication lines. It is more than the +ability to compute at a remote site, send electronic mail to a peer +across the country, or move a file from one library to another. The next +five years will witness substantial development of the information +infrastructure of the network. + +In order to provide appropriate leadership, library professionals must +have a fundamental understanding of and appreciation for computer +networking, from local area networks to the National Research and +Education Network (NREN). This presentation addresses these +fundamentals, and how they relate to libraries today and in the near +future. + +Edwin BROWNRIGG Electronic Library Visions and Realities + +The electronic library has been a vision desired by many--and rejected by +some--since Vannevar Bush coined the term memex to describe an automated, +intelligent, personal information system. Variations on this vision have +included Ted Nelson's Xanadau, Alan Kay's Dynabook, and Lancaster's +"paperless library," with the most recent incarnation being the +"Knowledge Navigator" described by John Scully of Apple. But the reality +of library service has been less visionary and the leap to the electronic +library has eluded universities, publishers, and information technology +files. + +The Memex Research Institute (MemRI), an independent, nonprofit research +and development organization, has created an Electronic Library Program +of shared research and development in order to make the collective vision +more concrete. The program is working toward the creation of large, +indexed publicly available electronic image collections of published +documents in academic, special, and public libraries. This strategic +plan is the result of the first stage of the program, which has been an +investigation of the information technologies available to support such +an effort, the economic parameters of electronic service compared to +traditional library operations, and the business and political factors +affecting the shift from print distribution to electronic networked +access. + +The strategic plan envisions a combination of publicly searchable access +databases, image (and text) document collections stored on network "file +servers," local and remote network access, and an intellectual property +management-control system. This combination of technology and +information content is defined in this plan as an E-library or E-library +collection. Some participating sponsors are already developing projects +based on MemRI's recommended directions. + +The E-library strategy projected in this plan is a visionary one that can +enable major changes and improvements in academic, public, and special +library service. This vision is, though, one that can be realized with +today's technology. At the same time, it will challenge the political +and social structure within which libraries operate: in academic +libraries, the traditional emphasis on local collections, extending to +accreditation issues; in public libraries, the potential of electronic +branch and central libraries fully available to the public; and for +special libraries, new opportunities for shared collections and networks. + +The environment in which this strategic plan has been developed is, at +the moment, dominated by a sense of library limits. The continued +expansion and rapid growth of local academic library collections is now +clearly at an end. Corporate libraries, and even law libraries, are +faced with operating within a difficult economic climate, as well as with +very active competition from commercial information sources. For +example, public libraries may be seen as a desirable but not critical +municipal service in a time when the budgets of safety and health +agencies are being cut back. + +Further, libraries in general have a very high labor-to-cost ratio in +their budgets, and labor costs are still increasing, notwithstanding +automation investments. It is difficult for libraries to obtain capital, +startup, or seed funding for innovative activities, and those +technology-intensive initiatives that offer the potential of decreased +labor costs can provoke the opposition of library staff. + +However, libraries have achieved some considerable successes in the past +two decades by improving both their service and their credibility within +their organizations--and these positive changes have been accomplished +mostly with judicious use of information technologies. The advances in +computing and information technology have been well-chronicled: the +continuing precipitous drop in computing costs, the growth of the +Internet and private networks, and the explosive increase in publicly +available information databases. + +For example, OCLC has become one of the largest computer network +organizations in the world by creating a cooperative cataloging network +of more than 6,000 libraries worldwide. On-line public access catalogs +now serve millions of users on more than 50,000 dedicated terminals in +the United States alone. The University of California MELVYL on-line +catalog system has now expanded into an index database reference service +and supports more than six million searches a year. And, libraries have +become the largest group of customers of CD-ROM publishing technology; +more than 30,000 optical media publications such as those offered by +InfoTrac and Silver Platter are subscribed to by U.S. libraries. + +This march of technology continues and in the next decade will result in +further innovations that are extremely difficult to predict. What is +clear is that libraries can now go beyond automation of their order files +and catalogs to automation of their collections themselves--and it is +possible to circumvent the fiscal limitations that appear to obtain +today. + +This Electronic Library Strategic Plan recommends a paradigm shift in +library service, and demonstrates the steps necessary to provide improved +library services with limited capacities and operating investments. + +SESSION IV-A + +Anne KENNEY + +The Cornell/Xerox Joint Study in Digital Preservation resulted in the +recording of 1,000 brittle books as 600-dpi digital images and the +production, on demand, of high-quality and archivally sound paper +replacements. The project, which was supported by the Commission on +Preservation and Access, also investigated some of the issues surrounding +scanning, storing, retrieving, and providing access to digital images in +a network environment. + +Anne Kenney will focus on some of the issues surrounding direct scanning +as identified in the Cornell Xerox Project. Among those to be discussed +are: image versus text capture; indexing and access; image-capture +capabilities; a comparison to photocopy and microfilm; production and +cost analysis; storage formats, protocols, and standards; and the use of +this scanning technology for preservation purposes. + +The 600-dpi digital images produced in the Cornell Xerox Project proved +highly acceptable for creating paper replacements of deteriorating +originals. The 1,000 scanned volumes provided an array of image-capture +challenges that are common to nineteenth-century printing techniques and +embrittled material, and that defy the use of text-conversion processes. +These challenges include diminished contrast between text and background, +fragile and deteriorated pages, uneven printing, elaborate type faces, +faint and bold text adjacency, handwritten text and annotations, nonRoman +languages, and a proliferation of illustrated material embedded in text. +The latter category included high-frequency and low-frequency halftones, +continuous tone photographs, intricate mathematical drawings, maps, +etchings, reverse-polarity drawings, and engravings. + +The Xerox prototype scanning system provided a number of important +features for capturing this diverse material. Technicians used multiple +threshold settings, filters, line art and halftone definitions, +autosegmentation, windowing, and software-editing programs to optimize +image capture. At the same time, this project focused on production. +The goal was to make scanning as affordable and acceptable as +photocopying and microfilming for preservation reformatting. A +time-and-cost study conducted during the last three months of this +project confirmed the economic viability of digital scanning, and these +findings will be discussed here. + +From the outset, the Cornell Xerox Project was predicated on the use of +nonproprietary standards and the use of common protocols when standards +did not exist. Digital files were created as TIFF images which were +compressed prior to storage using Group 4 CCITT compression. The Xerox +software is MS DOS based and utilizes off-the shelf programs such as +Microsoft Windows and Wang Image Wizard. The digital library is designed +to be hardware-independent and to provide interchangeability with other +institutions through network connections. Access to the digital files +themselves is two-tiered: Bibliographic records for the computer files +are created in RLIN and Cornell's local system and access into the actual +digital images comprising a book is provided through a document control +structure and a networked image file-server, both of which will be +described. + +The presentation will conclude with a discussion of some of the issues +surrounding the use of this technology as a preservation tool (storage, +refreshing, backup). + +Pamela ANDRE and Judith ZIDAR + +The National Agricultural Library (NAL) has had extensive experience with +raster scanning of printed materials. Since 1987, the Library has +participated in the National Agricultural Text Digitizing Project (NATDP) +a cooperative effort between NAL and forty-five land grant university +libraries. An overview of the project will be presented, giving its +history and NAL's strategy for the future. + +An in-depth discussion of NATDP will follow, including a description of +the scanning process, from the gathering of the printed materials to the +archiving of the electronic pages. The type of equipment required for a +stand-alone scanning workstation and the importance of file management +software will be discussed. Issues concerning the images themselves will +be addressed briefly, such as image format; black and white versus color; +gray scale versus dithering; and resolution. + +Also described will be a study currently in progress by NAL to evaluate +the usefulness of converting microfilm to electronic images in order to +improve access. With the cooperation of Tuskegee University, NAL has +selected three reels of microfilm from a collection of sixty-seven reels +containing the papers, letters, and drawings of George Washington Carver. +The three reels were converted into 3,500 electronic images using a +specialized microfilm scanner. The selection, filming, and indexing of +this material will be discussed. + +Donald WATERS + +Project Open Book, the Yale University Library's effort to convert 10, +000 books from microfilm to digital imagery, is currently in an advanced +state of planning and organization. The Yale Library has selected a +major vendor to serve as a partner in the project and as systems +integrator. In its proposal, the successful vendor helped isolate areas +of risk and uncertainty as well as key issues to be addressed during the +life of the project. The Yale Library is now poised to decide what +material it will convert to digital image form and to seek funding, +initially for the first phase and then for the entire project. + +The proposal that Yale accepted for the implementation of Project Open +Book will provide at the end of three phases a conversion subsystem, +browsing stations distributed on the campus network within the Yale +Library, a subsystem for storing 10,000 books at 200 and 600 dots per +inch, and network access to the image printers. Pricing for the system +implementation assumes the existence of Yale's campus ethernet network +and its high-speed image printers, and includes other requisite hardware +and software, as well as system integration services. Proposed operating +costs include hardware and software maintenance, but do not include +estimates for the facilities management of the storage devices and image +servers. + +Yale selected its vendor partner in a formal process, partly funded by +the Commission for Preservation and Access. Following a request for +proposal, the Yale Library selected two vendors as finalists to work with +Yale staff to generate a detailed analysis of requirements for Project +Open Book. Each vendor used the results of the requirements analysis to +generate and submit a formal proposal for the entire project. This +competitive process not only enabled the Yale Library to select its +primary vendor partner but also revealed much about the state of the +imaging industry, about the varying, corporate commitments to the markets +for imaging technology, and about the varying organizational dynamics +through which major companies are responding to and seeking to develop +these markets. + +Project Open Book is focused specifically on the conversion of images +from microfilm to digital form. The technology for scanning microfilm is +readily available but is changing rapidly. In its project requirements, +the Yale Library emphasized features of the technology that affect the +technical quality of digital image production and the costs of creating +and storing the image library: What levels of digital resolution can be +achieved by scanning microfilm? How does variation in the quality of +microfilm, particularly in film produced to preservation standards, +affect the quality of the digital images? What technologies can an +operator effectively and economically apply when scanning film to +separate two-up images and to control for and correct image +imperfections? How can quality control best be integrated into +digitizing work flow that includes document indexing and storage? + +The actual and expected uses of digital images--storage, browsing, +printing, and OCR--help determine the standards for measuring their +quality. Browsing is especially important, but the facilities available +for readers to browse image documents is perhaps the weakest aspect of +imaging technology and most in need of development. As it defined its +requirements, the Yale Library concentrated on some fundamental aspects +of usability for image documents: Does the system have sufficient +flexibility to handle the full range of document types, including +monographs, multi-part and multivolume sets, and serials, as well as +manuscript collections? What conventions are necessary to identify a +document uniquely for storage and retrieval? Where is the database of +record for storing bibliographic information about the image document? +How are basic internal structures of documents, such as pagination, made +accessible to the reader? How are the image documents physically +presented on the screen to the reader? + +The Yale Library designed Project Open Book on the assumption that +microfilm is more than adequate as a medium for preserving the content of +deteriorated library materials. As planning in the project has advanced, +it is increasingly clear that the challenge of digital image technology +and the key to the success of efforts like Project Open Book is to +provide a means of both preserving and improving access to those +deteriorated materials. + +SESSION IV-B + +George THOMA + +In the use of electronic imaging for document preservation, there are +several issues to consider, such as: ensuring adequate image quality, +maintaining substantial conversion rates (through-put), providing unique +identification for automated access and retrieval, and accommodating +bound volumes and fragile material. + +To maintain high image quality, image processing functions are required +to correct the deficiencies in the scanned image. Some commercially +available systems include these functions, while some do not. The +scanned raw image must be processed to correct contrast deficiencies-- +both poor overall contrast resulting from light print and/or dark +background, and variable contrast resulting from stains and +bleed-through. Furthermore, the scan density must be adequate to allow +legibility of print and sufficient fidelity in the pseudo-halftoned gray +material. Borders or page-edge effects must be removed for both +compactibility and aesthetics. Page skew must be corrected for aesthetic +reasons and to enable accurate character recognition if desired. +Compound images consisting of both two-toned text and gray-scale +illustrations must be processed appropriately to retain the quality of +each. + +SESSION IV-C + +Jean BARONAS + +Standards publications being developed by scientists, engineers, and +business managers in Association for Information and Image Management +(AIIM) standards committees can be applied to electronic image management +(EIM) processes including: document (image) transfer, retrieval and +evaluation; optical disk and document scanning; and document design and +conversion. When combined with EIM system planning and operations, +standards can assist in generating image databases that are +interchangeable among a variety of systems. The applications of +different approaches for image-tagging, indexing, compression, and +transfer often cause uncertainty concerning EIM system compatibility, +calibration, performance, and upward compatibility, until standard +implementation parameters are established. The AIIM standards that are +being developed for these applications can be used to decrease the +uncertainty, successfully integrate imaging processes, and promote "open +systems." AIIM is an accredited American National Standards Institute +(ANSI) standards developer with more than twenty committees comprised of +300 volunteers representing users, vendors, and manufacturers. The +standards publications that are developed in these committees have +national acceptance and provide the basis for international harmonization +in the development of new International Organization for Standardization +(ISO) standards. + +This presentation describes the development of AIIM's EIM standards and a +new effort at AIIM, a database on standards projects in a wide framework +of imaging industries including capture, recording, processing, +duplication, distribution, display, evaluation, and preservation. The +AIIM Imagery Database will cover imaging standards being developed by +many organizations in many different countries. It will contain +standards publications' dates, origins, related national and +international projects, status, key words, and abstracts. The ANSI Image +Technology Standards Board requested that such a database be established, +as did the ISO/International Electrotechnical Commission Joint Task Force +on Imagery. AIIM will take on the leadership role for the database and +coordinate its development with several standards developers. + +Patricia BATTIN + + Characteristics of standards for digital imagery: + + * Nature of digital technology implies continuing volatility. + + * Precipitous standard-setting not possible and probably not + desirable. + + * Standards are a complex issue involving the medium, the + hardware, the software, and the technical capacity for + reproductive fidelity and clarity. + + * The prognosis for reliable archival standards (as defined by + librarians) in the foreseeable future is poor. + + Significant potential and attractiveness of digital technology as a + preservation medium and access mechanism. + + Productive use of digital imagery for preservation requires a + reconceptualizing of preservation principles in a volatile, + standardless world. + + Concept of managing continuing access in the digital environment + rather than focusing on the permanence of the medium and long-term + archival standards developed for the analog world. + + Transition period: How long and what to do? + + * Redefine "archival." + + * Remove the burden of "archival copy" from paper artifacts. + + * Use digital technology for storage, develop management + strategies for refreshing medium, hardware and software. + + * Create acid-free paper copies for transition period backup + until we develop reliable procedures for ensuring continuing + access to digital files. + +SESSION IV-D + +Stuart WEIBEL The Role of SGML Markup in the CORE Project (6) + +The emergence of high-speed telecommunications networks as a basic +feature of the scholarly workplace is driving the demand for electronic +document delivery. Three distinct categories of electronic +publishing/republishing are necessary to support access demands in this +emerging environment: + + 1.) Conversion of paper or microfilm archives to electronic format + 2.) Conversion of electronic files to formats tailored to + electronic retrieval and display + 3.) Primary electronic publishing (materials for which the + electronic version is the primary format) + +OCLC has experimental or product development activities in each of these +areas. Among the challenges that lie ahead is the integration of these +three types of information stores in coherent distributed systems. + +The CORE (Chemistry Online Retrieval Experiment) Project is a model for +the conversion of large text and graphics collections for which +electronic typesetting files are available (category 2). The American +Chemical Society has made available computer typography files dating from +1980 for its twenty journals. This collection of some 250 journal-years +is being converted to an electronic format that will be accessible +through several end-user applications. + +The use of Standard Generalized Markup Language (SGML) offers the means +to capture the structural richness of the original articles in a way that +will support a variety of retrieval, navigation, and display options +necessary to navigate effectively in very large text databases. + +An SGML document consists of text that is marked up with descriptive tags +that specify the function of a given element within the document. As a +formal language construct, an SGML document can be parsed against a +document-type definition (DTD) that unambiguously defines what elements +are allowed and where in the document they can (or must) occur. This +formalized map of article structure allows the user interface design to +be uncoupled from the underlying database system, an important step +toward interoperability. Demonstration of this separability is a part of +the CORE project, wherein user interface designs born of very different +philosophies will access the same database. + +NOTES: + (6) The CORE project is a collaboration among Cornell University's + Mann Library, Bell Communications Research (Bellcore), the American + Chemical Society (ACS), the Chemical Abstracts Service (CAS), and + OCLC. + +Michael LESK The CORE Electronic Chemistry Library + +A major on-line file of chemical journal literature complete with +graphics is being developed to test the usability of fully electronic +access to documents, as a joint project of Cornell University, the +American Chemical Society, the Chemical Abstracts Service, OCLC, and +Bellcore (with additional support from Sun Microsystems, Springer-Verlag, +DigitaI Equipment Corporation, Sony Corporation of America, and Apple +Computers). Our file contains the American Chemical Society's on-line +journals, supplemented with the graphics from the paper publication. The +indexing of the articles from Chemical Abstracts Documents is available +in both image and text format, and several different interfaces can be +used. Our goals are (1) to assess the effectiveness and acceptability of +electronic access to primary journals as compared with paper, and (2) to +identify the most desirable functions of the user interface to an +electronic system of journals, including in particular a comparison of +page-image display with ASCII display interfaces. Early experiments with +chemistry students on a variety of tasks suggest that searching tasks are +completed much faster with any electronic system than with paper, but +that for reading all versions of the articles are roughly equivalent. + +Pamela ANDRE and Judith ZIDAR + +Text conversion is far more expensive and time-consuming than image +capture alone. NAL's experience with optical character recognition (OCR) +will be related and compared with the experience of having text rekeyed. +What factors affect OCR accuracy? How accurate does full text have to be +in order to be useful? How do different users react to imperfect text? +These are questions that will be explored. For many, a service bureau +may be a better solution than performing the work inhouse; this will also +be discussed. + +SESSION VI + +Marybeth PETERS + +Copyright law protects creative works. Protection granted by the law to +authors and disseminators of works includes the right to do or authorize +the following: reproduce the work, prepare derivative works, distribute +the work to the public, and publicly perform or display the work. In +addition, copyright owners of sound recordings and computer programs have +the right to control rental of their works. These rights are not +unlimited; there are a number of exceptions and limitations. + +An electronic environment places strains on the copyright system. +Copyright owners want to control uses of their work and be paid for any +use; the public wants quick and easy access at little or no cost. The +marketplace is working in this area. Contracts, guidelines on electronic +use, and collective licensing are in use and being refined. + +Issues concerning the ability to change works without detection are more +difficult to deal with. Questions concerning the integrity of the work +and the status of the changed version under the copyright law are to be +addressed. These are public policy issues which require informed +dialogue. + + + *** *** *** ****** *** *** *** + + + Appendix III: DIRECTORY OF PARTICIPANTS + + +PRESENTERS: + + Pamela Q.J. Andre + Associate Director, Automation + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 + Fax: (301) 504-7473 + E-mail: INTERNET: PANDRE@ASRR.ARSUSDA.GOV + + Jean Baronas, Senior Manager + Department of Standards and Technology + Association for Information and Image Management (AIIM) + 1100 Wayne Avenue, Suite 1100 + Silver Spring, MD 20910 + Phone: (301) 587-8202 + Fax: (301) 587-2711 + + Patricia Battin, President + The Commission on Preservation and Access + 1400 16th Street, N.W. + Suite 740 + Washington, DC 20036-2217 + Phone: (202) 939-3400 + Fax: (202) 939-3407 + E-mail: CPA@GWUVM.BITNET + + Howard Besser + Centre Canadien d'Architecture + (Canadian Center for Architecture) + 1920, rue Baile + Montreal, Quebec H3H 2S6 + CANADA + Phone: (514) 939-7001 + Fax: (514) 939-7020 + E-mail: howard@lis.pitt.edu + + Edwin B. Brownrigg, Executive Director + Memex Research Institute + 422 Bonita Avenue + Roseville, CA 95678 + Phone: (916) 784-2298 + Fax: (916) 786-7559 + E-mail: BITNET: MEMEX@CALSTATE.2 + + Eric M. Calaluca, Vice President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + James Daly + 4015 Deepwood Road + Baltimore, MD 21218-1404 + Phone: (410) 235-0763 + + Ricky Erway, Associate Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Carl Fleischhauer, Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Joanne Freeman + 2000 Jefferson Park Avenue, No. 7 + Charlottesville, VA 22903 + + Prosser Gifford + Director for Scholarly Programs + Library of Congress + Phone: (202) 707-1517 + Fax: (202) 707-9898 + E-mail: pgif@seq1.loc.gov + + Jacqueline Hess, Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Susan Hockey, Director + Center for Electronic Texts in the Humanities (CETH) + Alexander Library + Rutgers University + 169 College Avenue + New Brunswick, NJ 08903 + Phone: (908) 932-1384 + Fax: (908) 932-1386 + E-mail: hockey@zodiac.rutgers.edu + + William L. Hooton, Vice President + Business & Technical Development + Imaging & Information Systems Group + I-NET + 6430 Rockledge Drive, Suite 400 + Bethesda, MD 208l7 + Phone: (301) 564-6750 + Fax: (513) 564-6867 + + Anne R. Kenney, Associate Director + Department of Preservation and Conservation + 701 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-6875 + Fax: (607) 255-9346 + E-mail: LYDY@CORNELLA.BITNET + + Ronald L. Larsen + Associate Director for Information Technology + University of Maryland at College Park + Room B0224, McKeldin Library + College Park, MD 20742-7011 + Phone: (301) 405-9194 + Fax: (301) 314-9865 + E-mail: rlarsen@libr.umd.edu + + Maria L. Lebron, Managing Editor + The Online Journal of Current Clinical Trials + l333 H Street, N.W. + Washington, DC 20005 + Phone: (202) 326-6735 + Fax: (202) 842-2868 + E-mail: PUBSAAAS@GWUVM.BITNET + + Michael Lesk, Executive Director + Computer Science Research + Bell Communications Research, Inc. + Rm 2A-385 + 445 South Street + Morristown, NJ 07960-l9l0 + Phone: (201) 829-4070 + Fax: (201) 829-5981 + E-mail: lesk@bellcore.com (Internet) or bellcore!lesk (uucp) + + Clifford A. Lynch + Director, Library Automation + University of California, + Office of the President + 300 Lakeside Drive, 8th Floor + Oakland, CA 94612-3350 + Phone: (510) 987-0522 + Fax: (510) 839-3573 + E-mail: calur@uccmvsa + + Avra Michelson + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, D.C. 20408 + Phone: (202) 501-5544 + Fax: (202) 501-5533 + E-mail: tmi@cu.nih.gov + + Elli Mylonas, Managing Editor + Perseus Project + Department of the Classics + Harvard University + 319 Boylston Hall + Cambridge, MA 02138 + Phone: (617) 495-9025, (617) 495-0456 (direct) + Fax: (617) 496-8886 + E-mail: Elli@IKAROS.Harvard.EDU or elli@wjh12.harvard.edu + + David Woodley Packard + Packard Humanities Institute + 300 Second Street, Suite 201 + Los Altos, CA 94002 + Phone: (415) 948-0150 (PHI) + Fax: (415) 948-5793 + + Lynne K. Personius, Assistant Director + Cornell Information Technologies for + Scholarly Information Sources + 502 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-3393 + Fax: (607) 255-9346 + E-mail: JRN@CORNELLC.BITNET + + Marybeth Peters + Policy Planning Adviser to the + Register of Copyrights + Library of Congress + Office LM 403 + Phone: (202) 707-8350 + Fax: (202) 707-8366 + + C. Michael Sperberg-McQueen + Editor, Text Encoding Initiative + Computer Center (M/C 135) + University of Illinois at Chicago + Box 6998 + Chicago, IL 60680 + Phone: (312) 413-0317 + Fax: (312) 996-6834 + E-mail: u35395@uicvm..cc.uic.edu or u35395@uicvm.bitnet + + George R. Thoma, Chief + Communications Engineering Branch + National Library of Medicine + 8600 Rockville Pike + Bethesda, MD 20894 + Phone: (301) 496-4496 + Fax: (301) 402-0341 + E-mail: thoma@lhc.nlm.nih.gov + + Dorothy Twohig, Editor + The Papers of George Washington + 504 Alderman Library + University of Virginia + Charlottesville, VA 22903-2498 + Phone: (804) 924-0523 + Fax: (804) 924-4337 + + Susan H. Veccia, Team leader + American Memory, User Evaluation + Library of Congress + American Memory Evaluation Project + Phone: (202) 707-9104 + Fax: (202) 707-3764 + E-mail: svec@seq1.loc.gov + + Donald J. Waters, Head + Systems Office + Yale University Library + New Haven, CT 06520 + Phone: (203) 432-4889 + Fax: (203) 432-7231 + E-mail: DWATERS@YALEVM.BITNET or DWATERS@YALEVM.YCC.YALE.EDU + + Stuart Weibel, Senior Research Scientist + OCLC + 6565 Frantz Road + Dublin, OH 43017 + Phone: (614) 764-608l + Fax: (614) 764-2344 + E-mail: INTERNET: Stu@rsch.oclc.org + + Robert G. Zich + Special Assistant to the Associate Librarian + for Special Projects + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + E-mail: rzic@seq1.loc.gov + + Judith A. Zidar, Coordinator + National Agricultural Text Digitizing Program + Information Systems Division + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 or 504-5853 + Fax: (301) 504-7473 + E-mail: INTERNET: JZIDAR@ASRR.ARSUSDA.GOV + + +OBSERVERS: + + Helen Aguera, Program Officer + Division of Research + Room 318 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, D.C. 20506 + Phone: (202) 786-0358 + Fax: (202) 786-0243 + + M. Ellyn Blanton, Deputy Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Charles M. Dollar + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5532 + Fax: (202) 501-5512 + + Jeffrey Field, Deputy to the Director + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0570 + Fax: (202) 786-0243 + + Lorrin Garson + American Chemical Society + Research and Development Department + 1155 16th Street, N.W. + Washington, D.C. 20036 + Phone: (202) 872-4541 + Fax: E-mail: INTERNET: LRG96@ACS.ORG + + William M. Holmes, Jr. + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5540 + Fax: (202) 501-5512 + E-mail: WHOLMES@AMERICAN.EDU + + Sperling Martin + Information Resource Management + 20030 Doolittle Street + Gaithersburg, MD 20879 + Phone: (301) 924-1803 + + Michael Neuman, Director + The Center for Text and Technology + Academic Computing Center + 238 Reiss Science Building + Georgetown University + Washington, DC 20057 + Phone: (202) 687-6096 + Fax: (202) 687-6003 + E-mail: neuman@guvax.bitnet, neuman@guvax.georgetown.edu + + Barbara Paulson, Program Officer + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0577 + Fax: (202) 786-0243 + + Allen H. Renear + Senior Academic Planning Analyst + Brown University Computing and Information Services + 115 Waterman Street + Campus Box 1885 + Providence, R.I. 02912 + Phone: (401) 863-7312 + Fax: (401) 863-7329 + E-mail: BITNET: Allen@BROWNVM or + INTERNET: Allen@brownvm.brown.edu + + Susan M. Severtson, President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + Frank Withrow + U.S. Department of Education + 555 New Jersey Avenue, N.W. + Washington, DC 20208-5644 + Phone: (202) 219-2200 + Fax: (202) 219-2106 + + +(LC STAFF) + + Linda L. Arret + Machine-Readable Collections Reading Room LJ 132 + (202) 707-1490 + + John D. Byrum, Jr. + Descriptive Cataloging Division LM 540 + (202) 707-5194 + + Mary Jane Cavallo + Science and Technology Division LA 5210 + (202) 707-1219 + + Susan Thea David + Congressional Research Service LM 226 + (202) 707-7169 + + Robert Dierker + Senior Adviser for Multimedia Activities LM 608 + (202) 707-6151 + + William W. Ellis + Associate Librarian for Science and Technology LM 611 + (202) 707-6928 + + Ronald Gephart + Manuscript Division LM 102 + (202) 707-5097 + + James Graber + Information Technology Services LM G51 + (202) 707-9628 + + Rich Greenfield + American Memory LM 603 + (202) 707-6233 + + Rebecca Guenther + Network Development LM 639 + (202) 707-5092 + + Kenneth E. Harris + Preservation LM G21 + (202) 707-5213 + + Staley Hitchcock + Manuscript Division LM 102 + (202) 707-5383 + + Bohdan Kantor + Office of Special Projects LM 612 + (202) 707-0180 + + John W. Kimball, Jr + Machine-Readable Collections Reading Room LJ 132 + (202) 707-6560 + + Basil Manns + Information Technology Services LM G51 + (202) 707-8345 + + Sally Hart McCallum + Network Development LM 639 + (202) 707-6237 + + Dana J. Pratt + Publishing Office LM 602 + (202) 707-6027 + + Jane Riefenhauser + American Memory LM 603 + (202) 707-6233 + + William Z. Schenck + Collections Development LM 650 + (202) 707-7706 + + Chandru J. Shahani + Preservation Research and Testing Office (R&T) LM G38 + (202) 707-5607 + + William J. Sittig + Collections Development LM 650 + (202) 707-7050 + + Paul Smith + Manuscript Division LM 102 + (202) 707-5097 + + James L. Stevens + Information Technology Services LM G51 + (202) 707-9688 + + Karen Stuart + Manuscript Division LM 130 + (202) 707-5389 + + Tamara Swora + Preservation Microfilming Office LM G05 + (202) 707-6293 + + Sarah Thomas + Collections Cataloging LM 642 + (202) 707-5333 + + + END + ************************************************************* + +Note: This file has been edited for use on computer networks. This +editing required the removal of diacritics, underlining, and fonts such +as italics and bold. + +kde 11/92 + +[A few of the italics (when used for emphasis) were replaced by CAPS mh] + +*End of The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC ETEXTS + diff --git a/internal-complibs/zlib-ng-2.1.2/test/data/paper-100k.pdf b/internal-complibs/zlib-ng-2.1.2/test/data/paper-100k.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b3325e4a2bb578419d6c7fa412aaa78d493ff274 GIT binary patch literal 102400 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 f+ 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 +#include +#include + +#include "test_shared_ng.h" + +#define TESTFILE "foo.gz" + +static const char dictionary[] = "hello"; +static unsigned long dictId = 0; /* Adler32 value of the dictionary */ + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + + +void test_compress (unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen); +void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen); +void test_deflate (unsigned char *compr, size_t comprLen); +void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params); +void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_flush (unsigned char *compr, z_uintmax_t *comprLen); +void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_dict_deflate (unsigned char *compr, size_t comprLen); +void test_dict_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +int main (int argc, char *argv[]); + + +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *format, ...) { + va_list va; + + va_start(va, format); + vfprintf(stderr, format, va); + va_end(va); + + exit(1); +} + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) \ + error("%s error: %d\n", msg, err); \ +} + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen) { + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + err = PREFIX(compress)(compr, &comprLen, (const unsigned char*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) + error("bad uncompress\n"); + else + printf("uncompress(): %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + size_t read; + size_t len = strlen(hello)+1; + gzFile file; + z_off64_t pos; + z_off64_t comprLen; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(fname, "wb"); + if (file == NULL) + error("gzopen error\n"); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + if (PREFIX(gzputs)(file, "ello") != 4) + error("gzputs err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8) + error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err)); + /* Write string null-teriminator using gzseek */ + if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0) + error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file)); + /* Write hello, hello! using gzfwrite using best compression level */ + if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) + error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzfwrite)(hello, len, 1, file) == 0) + error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err)); + /* Flush compressed bytes to file */ + if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK) + error("gzflush err: %s\n", PREFIX(gzerror)(file, &err)); + comprLen = PREFIX(gzoffset)(file); + if (comprLen <= 0) + error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(fname, "rb"); + if (file == NULL) + error("gzopen error\n"); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len)) + error("gzread err: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello)) + error("bad gzread: %s\n", (char*)uncompr); + else + printf("gzread(): %s\n", (char*)uncompr); + /* Check position at the end of the gz file */ + if (PREFIX(gzeof)(file) != 1) + error("gzeof err: not reporting end of stream\n"); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + if (pos != 6 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + if (PREFIX(gzgetc)(file) != ' ') + error("gzgetc error\n"); + if (PREFIX(gzungetc)(' ', file) != ' ') + error("gzungetc error\n"); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) /* " hello!" */ + error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello + 6)) + error("bad gzgets after gzseek\n"); + else + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + if (pos != 14 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + /* Check position not at end of file */ + if (PREFIX(gzeof)(file) != 0) + error("gzeof err: reporting end of stream\n"); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file); + if (strcmp((const char *)uncompr, hello) != 0) + error("bad gzgets\n"); + else + printf("gzgets(): %s\n", (char*)uncompr); + pos = PREFIX(gzoffset)(file); + if (pos < 0 || pos != (comprLen + 10)) + error("gzoffset err: wrong offset at end\n"); + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + if (err == 0) + error("gzerror err: no error returned\n"); + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + if (err != 0) + error("gzclearerr err: not zero %d\n", err); + + PREFIX(gzclose)(file); + + if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR) + error("gzclose unexpected return when handle null\n"); + Z_UNUSED(read); +#endif +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) + error("bad inflate\n"); + else + printf("inflate(): %s\n", (char *)uncompr); +} + +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) + error("deflate not greedy\n"); + + /* Feed in already compressed data and switch to no compression: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_BEST_SPEED) + error("Expected compression level Z_BEST_SPEED, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + } + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_NO_COMPRESSION) + error("Expected compression level Z_NO_COMPRESSION, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + } + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + diff) + error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + else + printf("large_inflate(): OK\n"); +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_uintmax_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +#ifdef ZLIBNG_ENABLE_TESTS +/* =========================================================================== + * Test inflateSync() + * We expect a certain compressed block layout, so skip this with the original zlib. + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen-2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("inflate should report Z_STREAM_END\n"); + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} +#endif + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.adler = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + uint8_t check_dictionary[MAX_DICTIONARY_SIZE]; + uint32_t check_dictionary_len = 0; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + d_stream.adler = 0; + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) + error("unexpected dictionary"); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (check_dictionary_len < sizeof(dictionary)) + error("bad dictionary length\n"); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0) + error("bad dictionary\n"); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strncmp((char*)uncompr, hello, sizeof(hello))) + error("bad inflate with dict\n"); + else + printf("inflate with dictionary: %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflateBound() with small buffers + */ +void test_deflate_bound(void) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + int estimateLen = 0; + unsigned char *outBuf = NULL; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + c_stream.avail_in = len; + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_out = 0; + c_stream.next_out = outBuf; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + /* calculate actual output length and update structure */ + estimateLen = PREFIX(deflateBound)(&c_stream, len); + outBuf = malloc(estimateLen); + + if (outBuf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimateLen; + c_stream.next_out = outBuf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) { + printf("deflateBound(): OK\n"); + } else { + CHECK_ERR(err, "deflate"); + } + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(outBuf); +} + +/* =========================================================================== + * Test deflateCopy() with small buffers + */ +void test_deflate_copy(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + CHECK_ERR(err, "deflate_copy"); + + if (c_stream.state->status == c_stream_copy.state->status) { + printf("deflate_copy(): OK\n"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd original"); + + err = PREFIX(deflateEnd)(&c_stream_copy); + CHECK_ERR(err, "deflateEnd copy"); +} + +/* =========================================================================== + * Test deflateGetDictionary() with small buffers + */ +void test_deflate_get_dict(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned char *dictNew = NULL; + unsigned int *dictLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + + dictNew = calloc(256, 1); + dictLen = (unsigned int *)calloc(4, 1); + err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen); + + CHECK_ERR(err, "deflateGetDictionary"); + if (err == Z_OK) { + printf("deflateGetDictionary(): %s\n", dictNew); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(dictNew); + free(dictLen); +} + +/* =========================================================================== + * Test deflatePending() with small buffers + */ +void test_deflate_pending(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int *bits = calloc(256, 1); + unsigned *ped = calloc(256, 1); + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + CHECK_ERR(err, "deflatePending"); + + if (*bits >= 0 && *bits <= 7) { + printf("deflatePending(): OK\n"); + } else { + printf("deflatePending(): error\n"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(bits); + free(ped); +} + +/* =========================================================================== + * Test deflatePrime() wrapping gzip around deflate stream + */ +void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + PREFIX3(stream) d_stream; /* decompression stream */ + int err; + size_t len = strlen(hello)+1; + uint32_t crc = 0; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + CHECK_ERR(err, "deflatePrime"); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + CHECK_ERR(err, "deflatePrime"); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + CHECK_ERR(err, "deflatePrime"); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + CHECK_ERR(err, "deflatePrime"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)comprLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + CHECK_ERR(err, "deflate"); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len); + err = deflate_prime_32(&c_stream, crc); + CHECK_ERR(err, "deflatePrime"); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)len); + CHECK_ERR(err, "deflatePrime"); + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncomprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + CHECK_ERR(err, "inflateInit"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_BUF_ERROR) { + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((const char *)uncompr, hello) != 0) + error("bad deflatePrime\n"); + if (err == Z_OK) + printf("deflatePrime(): OK\n"); +} + +/* =========================================================================== + * Test deflateSetHeader() with small buffers + */ +void test_deflate_set_header(unsigned char *compr, size_t comprLen) { + PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header))); + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + + if (head == NULL) + error("out of memory\n"); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + CHECK_ERR(err, "deflateSetHeader"); + if (err == Z_OK) { + printf("deflateSetHeader(): OK\n"); + } + PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(head); +} + +/* =========================================================================== + * Test deflateTune() with small buffers + */ +void test_deflate_tune(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain); + CHECK_ERR(err, "deflateTune"); + if (err == Z_OK) { + printf("deflateTune(): OK\n"); + } + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ +int main(int argc, char *argv[]) { + unsigned char *compr, *uncompr; + z_uintmax_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + z_uintmax_t uncomprLen = comprLen; + static const char* myVersion = PREFIX2(VERSION); + + if (zVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zVersion(), PREFIX2(VERSION)) != 0) { + fprintf(stderr, "warning: different zlib version linked: %s\n", zVersion()); + } + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); + + compr = (unsigned char*)calloc((unsigned int)comprLen, 1); + uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == NULL || uncompr == NULL) + error("out of memory\n"); + + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + +#ifndef ZLIB_COMPAT + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); +#endif + + test_flush(compr, &comprLen); +#ifdef ZLIBNG_ENABLE_TESTS + test_sync(compr, comprLen, uncompr, uncomprLen); +#endif + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + test_deflate_bound(); + test_deflate_copy(compr, comprLen); + test_deflate_get_dict(compr, comprLen); + test_deflate_set_header(compr, comprLen); + test_deflate_tune(compr, comprLen); + test_deflate_pending(compr, comprLen); + test_deflate_prime(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/test/fuzz/CMakeLists.txt new file mode 100644 index 000000000..27a04c0e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.5.1) + +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + enable_language(CXX) + + if(DEFINED ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE_FOUND ON) + else() + find_library(FUZZING_ENGINE "FuzzingEngine") + endif() +endif() + +set(FUZZERS + fuzzer_checksum + fuzzer_compress + fuzzer_example_small + fuzzer_example_large + fuzzer_example_flush + fuzzer_example_dict + ) + +if(WITH_GZFILEOP) + list(APPEND FUZZERS fuzzer_minigzip) +endif() + +foreach(FUZZER ${FUZZERS}) + add_executable(${FUZZER} ${FUZZER}.c) + + if(NOT FUZZING_ENGINE_FOUND) + target_sources(${FUZZER} PRIVATE standalone_fuzz_target_runner.c) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(${FUZZER} zlibstatic) + else() + target_link_libraries(${FUZZER} zlib) + endif() + + if(FUZZING_ENGINE_FOUND) + target_link_libraries(${FUZZER} ${FUZZING_ENGINE}) + endif() + + if(ZLIB_ENABLE_TESTS) + file(GLOB FUZZER_TEST_FILES ${PROJECT_SOURCE_DIR}/*) + set(FUZZER_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${FUZZER_TEST_FILES}) + add_test(NAME ${FUZZER} COMMAND ${FUZZER_COMMAND}) + endif() +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_checksum.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_checksum.c new file mode 100644 index 000000000..cedd284db --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_checksum.c @@ -0,0 +1,81 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + uint32_t crc0 = PREFIX(crc32)(0L, NULL, 0); + uint32_t crc1 = crc0; + uint32_t crc2 = crc0; + uint32_t adler0 = PREFIX(adler32)(0L, NULL, 0); + uint32_t adler1 = adler0; + uint32_t adler2 = adler0; + uint32_t combine1, combine2; + /* Checksum with a buffer of size equal to the first byte in the input. */ + uint32_t buffSize = data[0]; + uint32_t offset = 0; + uint32_t op; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + /* Make sure the buffer has at least a byte. */ + if (buffSize == 0) + ++buffSize; + + /* CRC32 */ + op = PREFIX(crc32_combine_gen)(buffSize); + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) { + uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize); + uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op); + crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize); + assert(crc1 == crc4); + Z_UNUSED(crc1); + Z_UNUSED(crc4); + } + crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize); + + crc2 = PREFIX(crc32_z)(crc2, data, dataLen); + + assert(crc1 == crc2); + Z_UNUSED(crc1); + Z_UNUSED(crc2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine)(crc1, crc1, (z_off_t)dataLen); + assert(combine1 == combine2); + + /* Fast CRC32 combine. */ + op = PREFIX(crc32_combine_gen)((z_off_t)dataLen); + combine1 = PREFIX(crc32_combine_op)(crc1, crc2, op); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + + /* Adler32 */ + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) + adler1 = PREFIX(adler32_z)(adler1, data + offset, buffSize); + adler1 = PREFIX(adler32_z)(adler1, data + offset, dataLen % buffSize); + + adler2 = PREFIX(adler32_z)(adler2, data, dataLen); + + assert(adler1 == adler2); + Z_UNUSED(adler1); + Z_UNUSED(adler2); + combine1 = PREFIX(adler32_combine)(adler1, adler2, (z_off_t)dataLen); + combine2 = PREFIX(adler32_combine)(adler1, adler1, (z_off_t)dataLen); + assert(combine1 == combine2); + Z_UNUSED(combine1); + Z_UNUSED(combine2); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_compress.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_compress.c new file mode 100644 index 000000000..71cdf99ec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_compress.c @@ -0,0 +1,82 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +static const uint8_t *data; +static size_t dataLen; + +static void check_compress_level(uint8_t *compr, z_size_t comprLen, + uint8_t *uncompr, z_size_t uncomprLen, + int level) { + PREFIX(compress2)(compr, &comprLen, data, dataLen, level); + PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + + /* Make sure compress + uncompress gives back the input data. */ + assert(dataLen == uncomprLen); + assert(0 == memcmp(data, uncompr, dataLen)); +} + +#define put_byte(s, i, c) {s[i] = (unsigned char)(c);} + +static void write_zlib_header(uint8_t *s) { + unsigned level_flags = 0; /* compression level (0..3) */ + unsigned w_bits = 8; /* window size log2(w_size) (8..16) */ + unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8; + header |= (level_flags << 6); + + header += 31 - (header % 31); + + /* s is guaranteed to be longer than 2 bytes. */ + put_byte(s, 0, (header >> 8)); + put_byte(s, 1, (header & 0xff)); +} + +static void check_decompress(uint8_t *compr, size_t comprLen) { + /* We need to write a valid zlib header of size two bytes. Copy the input data + in a larger buffer. Do not modify the input data to avoid libFuzzer error: + fuzz target overwrites its const input. */ + size_t copyLen = dataLen + 2; + uint8_t *copy = (uint8_t *)malloc(copyLen); + memcpy(copy + 2, data, dataLen); + write_zlib_header(copy); + + PREFIX(uncompress)(compr, &comprLen, copy, copyLen); + free(copy); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + /* compressBound does not provide enough space for low compression levels. */ + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + check_compress_level(compr, comprLen, uncompr, uncomprLen, 1); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 3); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 6); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 7); + + check_decompress(compr, comprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_dict.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_dict.c new file mode 100644 index 000000000..053a3e101 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_dict.c @@ -0,0 +1,164 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int dictionaryLen = 0; +static unsigned long dictId; /* Adler32 value of the dictionary */ + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char **compr, size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int level = data[0] % 11 - 1; /* [-1..9] + compression levels + #define Z_NO_COMPRESSION 0 + #define Z_BEST_SPEED 1 + #define Z_BEST_COMPRESSION 9 + #define Z_DEFAULT_COMPRESSION (-1) */ + + int method = Z_DEFLATED; /* The deflate compression method (the only one + supported in this version) */ + int windowBits = 8 + data[(dataLen > 1) ? 1:0] % 8; /* The windowBits parameter is the base + two logarithm of the window size (the size of the history buffer). It + should be in the range 8..15 for this version of the library. */ + int memLevel = 1 + data[(dataLen > 2) ? 2:0] % 9; /* memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. */ + int strategy = data[(dataLen > 3) ? 3:0] % 5; /* [0..4] + #define Z_FILTERED 1 + #define Z_HUFFMAN_ONLY 2 + #define Z_RLE 3 + #define Z_FIXED 4 + #define Z_DEFAULT_STRATEGY 0 */ + + /* deflate would fail for no-compression or for speed levels. */ + if (level == 0 || level == 1) + level = -1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit2)(&c_stream, level, method, windowBits, memLevel, + strategy); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)( + &c_stream, (const unsigned char *)data, dictionaryLen); + CHECK_ERR(err, "deflateSetDictionary"); + + /* deflateBound does not provide enough space for low compression levels. */ + *comprLen = 100 + 2 * PREFIX(deflateBound)(&c_stream, (unsigned long)dataLen); + *compr = (uint8_t *)calloc(1, *comprLen); + + dictId = c_stream.adler; + c_stream.next_out = *compr; + c_stream.avail_out = (unsigned int)(*comprLen); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.avail_in = (uint32_t)dataLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate dict should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + unsigned char *uncompr; + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + uncompr = (uint8_t *)calloc(1, dataLen); + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)dataLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = PREFIX(inflateSetDictionary)( + &d_stream, (const unsigned char *)data, dictionaryLen); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } + + free(uncompr); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 0; + uint8_t *compr; + + /* Discard inputs larger than 100Kb. */ + static size_t kMaxSize = 100 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + + /* Set up the contents of the dictionary. The size of the dictionary is + intentionally selected to be of unusual size. To help cover more corner + cases, the size of the dictionary is read from the input data. */ + dictionaryLen = data[0]; + if (dictionaryLen > dataLen) + dictionaryLen = (unsigned int)dataLen; + + test_dict_deflate(&compr, &comprLen); + test_dict_inflate(compr, comprLen); + + free(compr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_flush.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_flush.c new file mode 100644 index 000000000..baa6988e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_flush.c @@ -0,0 +1,119 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate flush 1"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate flush 2"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen - 2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "inflate should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + // This test requires at least 3 bytes of input data. + if (size <= 3 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_large.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_large.c new file mode 100644 index 000000000..411459721 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_large.c @@ -0,0 +1,137 @@ +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 1"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 2"); + + /* Switch back to compressing mode: */ + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 3"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate large should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2 * uncomprLen + diff) { + fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 100 + 3 * size; + size_t uncomprLen = comprLen; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 512Kb. */ + static size_t kMaxSize = 512 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_small.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_small.c new file mode 100644 index 000000000..e59c72083 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_example_small.c @@ -0,0 +1,118 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned long len = (unsigned long)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate small 1"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "deflate small 2"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = PREFIX(compressBound)(size); + size_t uncomprLen = size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_minigzip.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_minigzip.c new file mode 100644 index 000000000..819148d2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/fuzzer_minigzip.c @@ -0,0 +1,325 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 /* read buffer size */ +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static const char *prog = "minigzip_fuzzer"; + +void error (const char *msg); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode); +void file_uncompress (char *file); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + /* Clear out the contents of buf before reading from the file to avoid + MemorySanitizer: use-of-uninitialized-value warnings. */ + memset(buf, 0, sizeof(buf)); + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) error(PREFIX(gzerror)(out, &err)); + } + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int err; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(PREFIX(gzerror)(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char buf[BUFLENW]; + int len; + int err; + + for (;;) { + len = PREFIX(gzread)(in, buf, sizeof(buf)); + if (len < 0) error (PREFIX(gzerror)(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + char *inFileName = "minigzip_fuzzer.out"; + char *outFileName = "minigzip_fuzzer.out.gz"; + char outmode[20]; + FILE *in; + char buf[BUFLEN]; + uint32_t offset = 0; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + in = fopen(inFileName, "wb"); + if (fwrite(data, 1, (unsigned)dataLen, in) != dataLen) + error("failed fwrite"); + if (fclose(in)) + error("failed fclose"); + + memset(outmode, 0, sizeof(outmode)); + snprintf(outmode, sizeof(outmode), "%s", "wb"); + + /* Compression level: [0..9]. */ + outmode[2] = '0' + (data[0] % 10); + + switch (data[dataLen-1] % 6) { + default: + case 0: + outmode[3] = 0; + break; + case 1: + /* compress with Z_FILTERED */ + outmode[3] = 'f'; + break; + case 2: + /* compress with Z_HUFFMAN_ONLY */ + outmode[3] = 'h'; + break; + case 3: + /* compress with Z_RLE */ + outmode[3] = 'R'; + break; + case 4: + /* compress with Z_FIXED */ + outmode[3] = 'F'; + break; + case 5: + /* direct */ + outmode[3] = 'T'; + break; + } + + file_compress(inFileName, outmode); + + /* gzopen does not support reading in direct mode */ + if (outmode[3] == 'T') + inFileName = outFileName; + else + file_uncompress(outFileName); + + /* Check that the uncompressed file matches the input data. */ + in = fopen(inFileName, "rb"); + if (in == NULL) { + perror(inFileName); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + for (;;) { + int len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) + break; + assert(0 == memcmp(data + offset, buf, len)); + offset += len; + } + + if (fclose(in)) + error("failed fclose"); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/fuzz/standalone_fuzz_target_runner.c b/internal-complibs/zlib-ng-2.1.2/test/fuzz/standalone_fuzz_target_runner.c new file mode 100644 index 000000000..810a56072 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/fuzz/standalone_fuzz_target_runner.c @@ -0,0 +1,37 @@ +#include +#include + +#include "zbuild.h" + +extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); + +int main(int argc, char **argv) { + int i; + fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1); + + for (i = 1; i < argc; i++) { + size_t len, n_read, err; + unsigned char *buf; + FILE *f = fopen(argv[i], "rb+"); + if (!f) { + /* Failed to open this file: it may be a directory. */ + fprintf(stderr, "Skipping: %s\n", argv[i]); + continue; + } + fprintf(stderr, "Running: %s %s\n", argv[0], argv[i]); + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + buf = (unsigned char *)malloc(len); + n_read = fread(buf, 1, len, f); + assert(n_read == len); + LLVMFuzzerTestOneInput(buf, len); + free(buf); + err = fclose(f); + assert(err == 0); + Z_UNUSED(err); + fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/gh1235.c b/internal-complibs/zlib-ng-2.1.2/test/gh1235.c new file mode 100644 index 000000000..7bf8738f3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/gh1235.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "zutil.h" + +int main(void) { + unsigned char plain[32]; + unsigned char compressed[130]; + PREFIX3(stream) strm; + z_size_t bound; + z_size_t bytes; + + for (int i = 0; i <= 32; i++) { + memset(plain, 6, i); + memset(&strm, 0, sizeof(strm)); + PREFIX(deflateInit2)(&strm, 0, 8, 31, 1, Z_DEFAULT_STRATEGY); + bound = PREFIX(deflateBound)(&strm, i); + strm.next_in = plain; + strm.next_out = compressed; + strm.avail_in = i; + strm.avail_out = sizeof(compressed); + if (PREFIX(deflate)(&strm, Z_FINISH) != Z_STREAM_END) return -1; + if (strm.avail_in != 0) return -1; + printf("bytes = %2i, deflateBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)strm.total_out); + if (bound < strm.total_out) return -1; + if (PREFIX(deflateEnd)(&strm) != Z_OK) return -1; + } + for (int i = 0; i <= 32; i++) { + bytes = sizeof(compressed); + for (int j = 0; j < i; j++) { + plain[j] = j; + } + bound = PREFIX(compressBound)(i); + if (PREFIX(compress2)(compressed, &bytes, plain, i, 1) != Z_OK) return -1; + printf("bytes = %2i, compressBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)bytes); + if (bytes > bound) return -1; + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/infcover.c b/internal-complibs/zlib-ng-2.1.2/test/infcover.c new file mode 100644 index 000000000..6606d222a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/infcover.c @@ -0,0 +1,686 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#undef NDEBUG +#include +#include + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + PREFIX3(stream) strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +static void *mem_alloc(void *mem, unsigned count, unsigned size) { + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +static void mem_free(void *mem, void *ptr) { + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +static void mem_setup(PREFIX3(stream) *strm) { + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +static void mem_limit(PREFIX3(stream) *strm, size_t limit) { + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +static void mem_used(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " allocated\n", prefix, (uint64_t)zone->total); +} + +/* show the high water allocation in bytes */ +static void mem_high(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " high water mark\n", prefix, (uint64_t)zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +static void mem_done(PREFIX3(stream) *strm, char *prefix) { + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %" PRIu64 " bytes in %d blocks not freed\n", + prefix, (uint64_t)zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = NULL; + strm->zalloc = NULL; + strm->zfree = NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can be delimited by any non-hex character, + where the delimiters are ignored except when a single hex digit is followed + by a delimiter, where that single digit writes a byte. The returned data is + allocated and must eventually be freed. NULL is returned if out of memory. + If the length is not needed, then len can be NULL. */ +static unsigned char *h2b(const char *hex, unsigned *len) { + unsigned char *in, *re; + unsigned next, val; + size_t inlen; + + inlen = (strlen(hex) + 1) >> 1; + assert(inlen != 0); /* tell static analyzer we won't call malloc(0) */ + in = malloc(inlen); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + assert(next != 0); /* tell static analyzer we won't call realloc(in, 0) */ + re = realloc(in, next); + return re == NULL ? in : re; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err) { + int ret; + unsigned have; + unsigned char *in, *out; + PREFIX3(stream) strm, copy; + PREFIX(gz_header) head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = PREFIX(inflateGetHeader)(&strm, &head); + assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = PREFIX(inflateSetDictionary)(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_OK); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(ret == Z_BUF_ERROR); + } + ret = PREFIX(inflateCopy)(©, &strm); + assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = PREFIX(inflateReset2)(&strm, -8); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, what); + Z_UNUSED(err); +} + +/* cover all of the lines in inflate.c up to inflate() */ +static void cover_support(void) { + int ret; + PREFIX3(stream) strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = PREFIX(inflatePrime)(&strm, 5, 31); assert(ret == Z_OK); + ret = PREFIX(inflatePrime)(&strm, -1, 0); assert(ret == Z_OK); + ret = PREFIX(inflateSetDictionary)(&strm, NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + +#ifdef ZLIB_COMPAT + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit_)(&strm, &PREFIX2(VERSION)[1], (int)sizeof(PREFIX3(stream))); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); +#endif + + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +static void cover_wrap(void) { + int ret; + PREFIX3(stream) strm, copy; + unsigned char dict[257]; + + ret = PREFIX(inflate)(NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(NULL); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateCopy)(NULL, NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = PREFIX(inflateSetDictionary)(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = PREFIX(inflatePrime)(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_DATA_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_OK); + (void)PREFIX(inflateSyncPoint)(&strm); + ret = PREFIX(inflateCopy)(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = PREFIX(inflateUndermine)(&strm, 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + assert(ret == Z_OK); +#else + assert(ret == Z_DATA_ERROR); +#endif + (void)PREFIX(inflateMark)(&strm); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +static unsigned pull(void *desc, z_const unsigned char **buf) { + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((PREFIX3(stream) *)desc)->state; + if (state != NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +static int push(void *desc, unsigned char *buf, unsigned len) { + buf += len; + Z_UNUSED(buf); + return desc != NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +static void cover_back(void) { + int ret; + PREFIX3(stream) strm; + unsigned char win[32768]; + +#ifdef ZLIB_COMPAT + ret = PREFIX(inflateBackInit_)(NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); +#endif + + ret = PREFIX(inflateBackInit)(NULL, 0, win); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBack)(NULL, NULL, NULL, NULL, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = PREFIX(inflateBack)(&strm, pull, &strm, push, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +static int try(char *hex, char *id, int err) { + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + PREFIX3(stream) strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateEnd)(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret != Z_STREAM_ERROR); + if (err && ret != Z_BUF_ERROR) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateBackEnd)(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +static void cover_inflate(void) { + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 0); +#else + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); +#endif + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +static void cover_trees(void) { + int ret; + unsigned bits; + uint16_t lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (uint16_t)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); + Z_UNUSED(ret); +} + +/* cover remaining inffast.c decoding and window copying */ +static void cover_fast(void) { + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +static void cover_cve_2022_37434(void) { + inf("1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51", "wtf", 13, 47, 12, Z_OK); +} + +int main(void) { + fprintf(stderr, "%s\n", zVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + cover_cve_2022_37434(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/minideflate.c b/internal-complibs/zlib-ng-2.1.2/test/minideflate.c new file mode 100644 index 000000000..987e6121b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/minideflate.c @@ -0,0 +1,359 @@ +/* minideflate.c -- test deflate/inflate under specific conditions + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#include +#include + +#include "zutil.h" + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +# ifdef _MSC_VER +# define strcasecmp _stricmp +# endif +#else +# include +# define SET_BINARY_MODE(file) +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +/* Default read/write i/o buffer size based on GZBUFSIZE */ +#define BUFSIZE 131072 + +/* =========================================================================== + * deflate() using specialized parameters + */ +void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t level, + int32_t window_bits, int32_t mem_level, int32_t strategy, int32_t flush) { + PREFIX3(stream) c_stream; /* compression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + c_stream.zalloc = NULL; + c_stream.zfree = NULL; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + + err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy); + CHECK_ERR(err, "deflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + c_stream.next_in = (z_const uint8_t *)read_buf; + c_stream.avail_in = read; + + do { + err = PREFIX(deflate)(&c_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + } while (c_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + c_stream.avail_in = 0; + do { + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (c_stream.next_out != write_buf) { + fwrite(write_buf, 1, c_stream.next_out - write_buf, fout); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(read_buf); + free(write_buf); +} + +/* =========================================================================== + * inflate() using specialized parameters + */ +void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t window_bits, + int32_t flush) { + PREFIX3(stream) d_stream; /* decompression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + d_stream.zalloc = NULL; + d_stream.zfree = NULL; + d_stream.opaque = (void *)0; + d_stream.total_in = 0; + d_stream.total_out = 0; + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + + err = PREFIX(inflateInit2)(&d_stream, window_bits); + CHECK_ERR(err, "inflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + d_stream.next_in = (z_const uint8_t *)read_buf; + d_stream.avail_in = read; + + do { + err = PREFIX(inflate)(&d_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + } while (d_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + d_stream.avail_in = 0; + do { + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (d_stream.next_out != write_buf) { + fwrite(write_buf, 1, d_stream.next_out - write_buf, fout); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + free(read_buf); + free(write_buf); +} + +void show_help(void) { + printf("Usage: minideflate [-c][-d][-k] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input file\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -m : memory level (1 to 8)\n" \ + " -w : window bits..\n" \ + " : -1 to -15 for raw deflate\n" + " : 0 to 15 for deflate (adler32)\n" + " : 16 to 31 for gzip (crc32)\n" + " -s : flush type (0 to 5)\n" \ + " -r : read buffer size\n" \ + " -t : write buffer size\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char **argv) { + int32_t i; + int32_t mem_level = DEF_MEM_LEVEL; + int32_t window_bits = INT32_MAX; + int32_t strategy = Z_DEFAULT_STRATEGY; + int32_t level = Z_DEFAULT_COMPRESSION; + int32_t read_buf_size = BUFSIZE; + int32_t write_buf_size = BUFSIZE; + int32_t flush = Z_NO_FLUSH; + uint8_t copyout = 0; + uint8_t uncompr = 0; + uint8_t keep = 0; + FILE *fin = stdin; + FILE *fout = stdout; + + + if (argc == 1) { + show_help(); + return 64; /* EX_USAGE */ + } + + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc)) + mem_level = atoi(argv[++i]); + else if ((strcmp(argv[i], "-w") == 0) && (i + 1 < argc)) + window_bits = atoi(argv[++i]); + else if ((strcmp(argv[i], "-r") == 0) && (i + 1 < argc)) + read_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-t") == 0) && (i + 1 < argc)) + write_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-s") == 0) && (i + 1 < argc)) + flush = atoi(argv[++i]); + else if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-f") == 0) + strategy = Z_FILTERED; + else if (strcmp(argv[i], "-F") == 0) + strategy = Z_FIXED; + else if (strcmp(argv[i], "-h") == 0) + strategy = Z_HUFFMAN_ONLY; + else if (strcmp(argv[i], "-R") == 0) + strategy = Z_RLE; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i][1] - '0'; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else + break; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + if (i != argc) { + fin = fopen(argv[i], "rb+"); + if (fin == NULL) { + fprintf(stderr, "Failed to open file: %s\n", argv[i]); + exit(1); + } + if (!copyout) { + char *out_file = (char *)calloc(1, strlen(argv[i]) + 6); + if (out_file == NULL) { + fprintf(stderr, "Not enough memory\n"); + exit(1); + } + strcat(out_file, argv[i]); + if (!uncompr) { + if (window_bits < 0) { + strcat(out_file, ".zraw"); + } else if (window_bits > MAX_WBITS) { + strcat(out_file, ".gz"); + } else { + strcat(out_file, ".z"); + } + } else { + char *out_ext = strrchr(out_file, '.'); + if (out_ext != NULL) { + if (strcasecmp(out_ext, ".zraw") == 0 && window_bits == INT32_MAX) { + fprintf(stderr, "Must specify window bits for raw deflate stream\n"); + exit(1); + } + *out_ext = 0; + } + } + fout = fopen(out_file, "wb"); + if (fout == NULL) { + fprintf(stderr, "Failed to open file: %s\n", out_file); + exit(1); + } + free(out_file); + } + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (uncompr) { + inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush); + } else { + deflate_params(fin, fout, read_buf_size, write_buf_size, level, window_bits, mem_level, strategy, flush); + } + + if (fin != stdin) { + fclose(fin); + if (!copyout && !keep) { + unlink(argv[i]); + } + } + if (fout != stdout) { + fclose(fout); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/minigzip.c b/internal-complibs/zlib-ng-2.1.2/test/minigzip.c new file mode 100644 index 000000000..d55f5086b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/minigzip.c @@ -0,0 +1,378 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include + +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#ifndef BUFLEN +# define BUFLEN 16384 /* read buffer size */ +#endif +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static char *prog; + +void error (const char *msg); +void gz_fatal (gzFile file); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode, int keep); +void file_uncompress (char *file, int keep); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Display last error message of gzFile, close it and exit + */ + +void gz_fatal(gzFile file) { + int err; + fprintf(stderr, "%s: %s\n", prog, PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char *buf; + int len; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + buf = (char *)calloc(BUFLEN, 1); + if (buf == NULL) { + perror("out of memory"); + exit(1); + } + + for (;;) { + len = (int)fread(buf, 1, BUFLEN, in); + if (ferror(in)) { + free(buf); + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) gz_fatal(out); + } + free(buf); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, buf, (unsigned)buf_len); + + if (len != (int)buf_len) gz_fatal(out); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char *buf = (char *)malloc(BUFLENW); + int len; + + if (buf == NULL) error("out of memory"); + + for (;;) { + len = PREFIX(gzread)(in, buf, BUFLENW); + if (len < 0) { + free(buf); + gz_fatal(in); + } + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + free(buf); + error("failed fwrite"); + } + } + free(buf); + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode, int keep) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + if (!keep) + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file, int keep) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + if (!keep) + unlink(infile); +} + +void show_help(void) { + printf("Usage: minigzip [-c] [-d] [-k] [-f|-h|-R|-F|-T] [-A] [-0 to -9] [files...]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input files\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -T : stored raw\n" \ + " -A : auto detect type\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char *argv[]) { + int copyout = 0; + int uncompr = 0; + int keep = 0; + int i = 0; + gzFile file; + char *bname, outmode[20]; + char *strategy = ""; + char *level = "6"; + char *type = "b"; + + prog = argv[i]; + bname = strrchr(argv[i], '/'); + if (bname) + bname++; + else + bname = argv[i]; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-A") == 0) + type = ""; + else if (argv[i][0] == '-' && (argv[i][1] == 'f' || argv[i][1] == 'h' || + argv[i][1] == 'R' || argv[i][1] == 'F' || argv[i][1] == 'T') && argv[i][2] == 0) + strategy = argv[i] + 1; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i] + 1; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else { + break; + } + } + + snprintf(outmode, sizeof(outmode), "w%s%s%s", type, strategy, level); + + if (i == argc) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = PREFIX(gzdopen)(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = PREFIX(gzopen)(argv[i], "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, argv[i]); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(argv[i], keep); + } + } else { + if (copyout) { + FILE * in = fopen(argv[i], "rb"); + + if (in == NULL) { + perror(argv[i]); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(argv[i], outmode, keep); + } + } + } while (++i < argc); + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/pigz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/test/pigz/CMakeLists.txt new file mode 100644 index 000000000..bc6830ae2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/pigz/CMakeLists.txt @@ -0,0 +1,211 @@ +# CMakeLists.txt -- Build madler/pigz against zlib variant + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# By default pigz will be linked against the system zlib and +# pthread libraries if installed. + +# For compilation on Windows download and use shim: +# https://github.com/zlib-ng/pigzbench/tree/master/pigz/win + +# Optional Variables +# WITH_CODE_COVERAGE - Enable code coverage reporting +# WITH_THREADS - Enable threading support +# PIGZ_ENABLE_TESTS - Enable adding unit tests +# PIGZ_VERSION - Set the version of pigz to build +# ZLIB_ROOT - Path to the zlib source directory +# PTHREADS4W_ROOT - Path to pthreads4w source directory on Windows. +# If not specified then threading will be disabled. + +cmake_minimum_required(VERSION 3.11) + +include(CheckCCompilerFlag) +include(FeatureSummary) +include(FetchContent) + +include(../../cmake/detect-coverage.cmake) + +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_THREADS "Enable threading support" ON) +option(PIGZ_ENABLE_TESTS "Build unit tests" ON) +option(PIGZ_VERSION "Set the version of pigz to build" "") + +project(pigz LANGUAGES C) + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Compiler definitions +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_definitions(-fno-caret-diagnostics) +elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5.0) + add_definitions(-Wno-unused-result) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8.0) + add_definitions(-fno-diagnostics-show-caret) + endif() +elseif(WIN32) + add_definitions(-D_TIMESPEC_DEFINED) + if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + endif() +endif() + +# Fetch pigz source code from official repository +if(PIGZ_VERSION STREQUAL "") + set(PIGZ_TAG master) +else() + set(PIGZ_TAG ${PIGZ_VERSION}) +endif() +FetchContent_Declare(pigz + GIT_REPOSITORY https://github.com/madler/pigz.git + GIT_TAG ${PIGZ_TAG}) + +FetchContent_GetProperties(pigz) +if(NOT pigz_POPULATED) + FetchContent_Populate(pigz) +endif() + +set(PIGZ_SRCS + ${pigz_SOURCE_DIR}/pigz.c + ${pigz_SOURCE_DIR}/try.c) + +set(PIGZ_HDRS + ${pigz_SOURCE_DIR}/try.h) + +add_executable(${PROJECT_NAME} ${PIGZ_SRCS} ${PIGZ_HDRS}) +add_definitions(-DNOZOPFLI) +if(WIN32) + target_include_directories(${PROJECT_NAME} PRIVATE win) +endif() + +# Find and link against pthreads or pthreads4w +if(WITH_THREADS) + if(WIN32) + if(DEFINED PTHREADS4W_ROOT) + set(CLEANUP_STYLE VC) + set(PTHREADS4W_VERSION 3) + + add_subdirectory(${PTHREADS4W_ROOT} ${PTHREADS4W_ROOT} EXCLUDE_FROM_ALL) + target_link_libraries(${PROJECT_NAME} pthreadVC3) + target_include_directories(${PROJECT_NAME} PRIVATE ${PTHREADS4W_ROOT}) + else() + message(WARNING "Missing pthreads4w root directory") + set(WITH_THREADS OFF) + endif() + else() + find_package(Threads REQUIRED) + target_link_libraries(${PROJECT_NAME} Threads::Threads) + if(NOT APPLE) + target_link_libraries(${PROJECT_NAME} m) + endif() + endif() +endif() + +# Disable threading support +if(NOT WITH_THREADS) + add_definitions(-DNOTHREAD) +else() + set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY SOURCES + ${pigz_SOURCE_DIR}/yarn.c + ${pigz_SOURCE_DIR}/yarn.h) +endif() + +# Find and link against zlib +if(NOT DEFINED ZLIB_ROOT) + find_package(Zlib REQUIRED) +endif() + +set(ZLIB_COMPAT ON) +set(ZLIB_ENABLE_TESTS OFF) + +add_subdirectory(${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib EXCLUDE_FROM_ALL) + +if(NOT DEFINED BUILD_SHARED_LIBS OR NOT BUILD_SHARED_LIBS) + set(ZLIB_TARGET zlibstatic) +else() + set(ZLIB_TARGET zlib) +endif() + +target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib) +target_link_libraries(${PROJECT_NAME} ${ZLIB_TARGET}) + +if(NOT SKIP_INSTALL_BINARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${PROJECT_NAME} DESTINATION "bin") +endif() + +# Add unit tests +if(PIGZ_ENABLE_TESTS) + enable_testing() + + set(PIGZ_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + + macro(test_pigz name path) + # Construct compression arguments for pigz + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id pigz-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${PIGZ_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/compress-and-verify.cmake) + endif() + endmacro() + + set(TEST_CONFIGS + -U # RLE compression + #-H # Z_HUFFMAN_ONLY (broken in 2.6) + -0 # No compression + -1 # Deflate quick + -4 # Deflate medium (lazy matches) + -6 # Deflate medium + -9 # Deflate slow + ) + + file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) + + foreach(TEST_FILE_PATH ${TEST_FILE_PATHS}) + if("${TEST_FILE_PATH}" MATCHES ".gz$" OR "${TEST_FILE_PATH}" MATCHES ".out$" OR + "${TEST_FILE_PATH}" MATCHES "/.git/" OR "${TEST_FILE_PATH}" MATCHES ".md$") + continue() + endif() + foreach(TEST_CONFIG ${TEST_CONFIGS}) + get_filename_component(TEST_NAME ${TEST_FILE_PATH} NAME) + if (TEST_NAME STREQUAL "") + continue() + endif() + test_pigz(${TEST_NAME} ${TEST_FILE_PATH} ${TEST_CONFIG}) + endforeach() + endforeach() + + set(GH979_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + -d -k -f ${CMAKE_CURRENT_SOURCE_DIR}/../GH-979/pigz-2.6.tar.gz) + add_test(NAME GH-979 COMMAND ${GH979_COMMAND}) +endif() + +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_THREADS WITH_THREADS "Enable threading support") +add_feature_info(PIGZ_ENABLE_TESTS PIGZ_ENABLE_TESTS "Build unit tests") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.2/test/pkgcheck.sh b/internal-complibs/zlib-ng-2.1.2/test/pkgcheck.sh new file mode 100644 index 000000000..87a4e61ef --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/pkgcheck.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +usage() { + cat <<"_EOF_" +Usage: sh test/pkgcheck.sh [--zlib-compat] + +Verifies that the various build systems produce identical results on a Unixlike system. +If --zlib-compat, tests with zlib compatible builds. + +To build the 32 bit version for the current 64 bit arch: + +$ sudo apt install ninja-build diffoscope gcc-multilib +$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-m32" CFLAGS=-m32 LDFLAGS=-m32 +$ sh test/pkgcheck.sh + +To cross-build, install the appropriate qemu and gcc packages, +and set the environment variables used by configure or cmake. +On Ubuntu, for example (values taken from .github/workflows/pkgconf.yml): + +arm HF: +$ sudo apt install ninja-build diffoscope qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross +$ export CHOST=arm-linux-gnueabihf +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +aarch64: +$ sudo apt install ninja-build diffoscope qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross +$ export CHOST=aarch64-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +ppc (32 bit big endian): +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross +$ export CHOST=powerpc-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake" + +ppc64le: +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross +$ export CHOST=powerpc64le-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake" + +then: +$ export CC=${CHOST}-gcc +$ sh test/pkgcheck.sh [--zlib-compat] + +Note: on Mac, you may also need to do 'sudo xcode-select -r' to get cmake to match configure/make's behavior (i.e. omit -isysroot). +_EOF_ +} + +set -ex + +# Caller can also set CMAKE_ARGS or CONFIGURE_ARGS if desired +CMAKE_ARGS="-DCMAKE_INSTALL_LIBDIR=lib ${CMAKE_ARGS}" +CONFIGURE_ARGS=${CONFIGURE_ARGS} + +case "$1" in +--zlib-compat) + suffix="" + CMAKE_ARGS="$CMAKE_ARGS -DZLIB_COMPAT=ON" + CONFIGURE_ARGS="$CONFIGURE_ARGS --zlib-compat" + ;; +"") + suffix="-ng" + ;; +*) + echo "Unknown arg '$1'" + usage + exit 1 + ;; +esac + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps +# Probably only needed on older systems (ubuntu 14.04, BSD?) +export SOURCE_DATE_EPOCH=0 +case $(uname) in +Darwin) + # Tell Apple's ar etc. to use zero timestamps + export ZERO_AR_DATE=1 + # What CPU are we running on, exactly? + sysctl -n machdep.cpu.brand_string + sysctl -n machdep.cpu.features + sysctl -n machdep.cpu.leaf7_features + sysctl -n machdep.cpu.extfeatures + ;; +esac + +# Use same compiler for make and cmake builds +if test "$CC"x = ""x +then + if clang --version + then + export CC=clang + elif gcc --version + then + export CC=gcc + fi +fi + +# New build system +# Happens to delete top-level zconf.h +# (which itself is a bug, https://github.com/madler/zlib/issues/162 ) +# which triggers another bug later in configure, +# https://github.com/madler/zlib/issues/499 +rm -rf btmp2 pkgtmp2 +mkdir btmp2 pkgtmp2 +export DESTDIR=$(pwd)/pkgtmp2 +cd btmp2 + cmake -G Ninja ${CMAKE_ARGS} .. + ninja -v + ninja install +cd .. + +# Original build system +rm -rf btmp1 pkgtmp1 +mkdir btmp1 pkgtmp1 +export DESTDIR=$(pwd)/pkgtmp1 +cd btmp1 + case $(uname) in + Darwin) + export LDFLAGS="-Wl,-headerpad_max_install_names" + ;; + esac + ../configure $CONFIGURE_ARGS + make -j2 + make install +cd .. + +repack_ar() { + if ! cmp --silent pkgtmp1/usr/local/lib/libz$suffix.a pkgtmp2/usr/local/lib/libz$suffix.a + then + echo "libz$suffix.a does not match. Probably filenames differ (.o vs .c.o). Unpacking and renaming..." + # Note: %% is posix shell syntax meaning "Remove Largest Suffix Pattern", see + # https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 + cd pkgtmp1; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; cd .. + cd pkgtmp2; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; for a in *.c.o; do mv $a ${a%%.c.o}.o; done; cd .. + # Also, remove __.SYMDEF SORTED if present, as it has those funky .c.o names embedded in it. + rm -f pkgtmp[12]/__.SYMDEF\ SORTED + fi +} + +case $(uname) in +Darwin) + # Remove the build uuid. + dylib1=$(find pkgtmp1 -type f -name '*.dylib*') + dylib2=$(find pkgtmp2 -type f -name '*.dylib*') + strip -x -no_uuid "$dylib1" + strip -x -no_uuid "$dylib2" + ;; +esac + +# The ar on newer systems defaults to -D (i.e. deterministic), +# but FreeBSD 12.1, Debian 8, and Ubuntu 14.04 seem to not do that. +# I had trouble passing -D safely to the ar inside CMakeLists.txt, +# so punt and unpack the archive if needed before comparing. +# Also, cmake uses different .o suffix anyway... +repack_ar + +if diff -Nur pkgtmp1 pkgtmp2 +then + echo pkgcheck-cmake-bits-identical PASS +else + echo pkgcheck-cmake-bits-identical FAIL + dylib1=$(find pkgtmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + dylib2=$(find pkgtmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + diffoscope $dylib1 $dylib2 | cat + exit 1 +fi + +rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +# any failure would have caused an early exit already +echo "pkgcheck: PASS" diff --git a/internal-complibs/zlib-ng-2.1.2/test/switchlevels.c b/internal-complibs/zlib-ng-2.1.2/test/switchlevels.c new file mode 100644 index 000000000..a065dbcff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/switchlevels.c @@ -0,0 +1,167 @@ +/* Compresses a user-specified number of chunks from stdin into stdout as a single gzip stream. + * Each chunk is compressed with a user-specified level. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +static int read_all(unsigned char *buf, size_t size) { + size_t total_read = 0; + while (total_read < size) { + size_t n_read = fread(buf + total_read, 1, size - total_read, stdin); + if (ferror(stdin)) { + perror("fread\n"); + return 1; + } + if (n_read == 0) { + fprintf(stderr, "Premature EOF\n"); + return 1; + } + total_read += n_read; + } + return 0; +} + +static int write_all(unsigned char *buf, size_t size) { + size_t total_written = 0; + while (total_written < size) { + size_t n_written = fwrite(buf + total_written, 1, size - total_written, stdout); + if (ferror(stdout)) { + perror("fwrite\n"); + return 1; + } + total_written += n_written; + } + return 0; +} + +static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last) { + int ret = 1; + int err = 0; + unsigned long compsize; + unsigned char *buf; + + if (size <= 0) { + fprintf(stderr, "compress_chunk() invalid size %d\n", size); + goto done; + } + if (level < 0 || level > 9) { + fprintf(stderr, "compress_chunk() invalid level %d\n", level); + goto done; + } + + compsize = PREFIX(deflateBound)(strm, size); + buf = malloc(size + compsize); + if (buf == NULL) { + fprintf(stderr, "Out of memory\n"); + goto done; + } + if (read_all(buf, size) != 0) { + goto free_buf; + } + + /* Provide only output buffer to deflateParams(). It might need some space to flush the leftovers from the last + * deflate(), but we don't want it to compress anything new. */ + strm->next_in = NULL; + strm->avail_in = 0; + strm->next_out = buf + size; + strm->avail_out = compsize; + err = PREFIX(deflateParams)(strm, level, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateParams() failed with code %d\n", err); + goto free_buf; + } + + /* Provide input buffer to deflate(). */ + strm->next_in = buf; + strm->avail_in = size; + err = PREFIX(deflate)(strm, last ? Z_FINISH : Z_SYNC_FLUSH); + if ((!last && err != Z_OK) || (last && err != Z_STREAM_END)) { + fprintf(stderr, "deflate() failed with code %d\n", err); + goto free_buf; + } + if (strm->avail_in != 0) { + fprintf(stderr, "deflate() did not consume %d bytes of input\n", strm->avail_in); + goto free_buf; + } + if (write_all(buf + size, compsize - strm->avail_out) != 0) { + goto free_buf; + } + ret = 0; + +free_buf: + free(buf); +done: + return ret; +} + +void show_help(void) +{ + printf("Usage: switchlevels [-w bits] level1 size1 [level2 size2 ...]\n\n" \ + " -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n\n"); +} + +int main(int argc, char **argv) { + int ret = EXIT_FAILURE; + int err = 0; + int size = 0; + int level = Z_DEFAULT_COMPRESSION; + int level_arg = 1; + int window_bits = MAX_WBITS + 16; + PREFIX3(stream) strm; + + + if ((argc == 1) || (argc == 2 && strcmp(argv[1], "--help") == 0)) { + show_help(); + return 0; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + memset(&strm, 0, sizeof(strm)); + + for (int i = 1; i < argc - 1; i++) { + if (strcmp(argv[i], "-w") == 0 && i+1 < argc) { + window_bits = atoi(argv[++i]); + } else { + level_arg = i; + level = atoi(argv[i]); + break; + } + } + + err = PREFIX(deflateInit2)(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateInit() failed with code %d\n", err); + goto done; + } + + for (int i = level_arg; i < argc - 1; i += 2) { + level = atoi(argv[i]); + size = atoi(argv[i + 1]); + if (compress_chunk(&strm, level, size, i + 2 >= argc - 1) != 0) { + goto deflate_end; + } + } + ret = EXIT_SUCCESS; + +deflate_end: + PREFIX(deflateEnd)(&strm); +done: + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_adler32.cc b/internal-complibs/zlib-ng-2.1.2/test/test_adler32.cc new file mode 100644 index 000000000..4dfe63f20 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_adler32.cc @@ -0,0 +1,386 @@ +/* test_adler32.c -- unit test for adler32 in the zlib compression library + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + uint32_t adler; + const uint8_t *buf; + uint32_t len; + uint32_t expect; +} adler32_test; + +static const uint8_t long_string[5552] = { + 'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q', + 'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k', + 'A','x','N','Q','R','k','d','V','5','y','n','U','N','W','Q','Y','i','W','5','9','R','p','D','C','x','p','u','h','C','a','m','r', + 'z','n','z','A','d','J','6','u','N','e','r','x','7','Q','3','v','V','h','H','S','H','S','f','K','f','e','E','T','9','J','f','K', + 'w','t','x','J','2','y','7','B','x','X','X','p','G','b','T','g','3','k','U','6','E','Z','M','t','J','q','v','n','S','T','6','x', + '5','x','4','P','z','p','M','F','V','b','d','m','f','G','n','J','m','w','z','K','8','a','q','E','D','e','b','3','h','B','V','g', + 'y','3','P','L','5','8','r','z','X','b','Q','g','H','7','L','c','Z','B','3','C','4','y','t','u','k','z','h','v','C','Y','p','p', + '8','H','v','5','X','w','4','L','R','V','V','4','U','C','8','4','T','E','a','N','Z','S','7','U','u','z','f','H','p','P','J','u', + 'Y','Z','h','T','6','e','v','z','V','F','h','u','y','H','b','k','J','M','f','3','6','g','y','L','E','W','t','B','B','d','d','9', + 'u','M','Z','k','F','G','f','h','q','k','5','k','f','r','M','7','c','M','7','y','n','u','8','b','d','7','Q','f','E','m','F','K', + 'x','W','f','B','2','F','8','5','q','z','y','3','R','i','U','m','X','k','h','N','J','y','B','C','h','u','x','4','f','k','J','5', + '6','X','T','W','h','8','J','4','m','K','p','N','3','g','C','g','A','E','e','Z','x','A','P','2','E','4','t','Q','5','X','Y','j', + '6','m','b','h','G','a','v','6','t','v','6','C','M','G','P','u','B','C','A','V','b','2','9','d','2','c','5','a','b','X','w','V', + 'G','6','a','7','c','8','G','6','K','U','Q','m','w','P','V','5','N','x','b','v','x','E','N','C','A','N','t','v','N','B','z','X', + 'B','R','q','U','n','i','A','Q','d','m','a','D','7','Y','f','3','J','8','Y','m','w','Z','b','w','r','H','q','E','j','c','u','E', + 'i','i','S','b','n','G','P','a','F','j','c','R','D','D','G','F','v','i','a','i','M','7','B','e','w','m','L','E','F','2','Y','4', + '4','7','Y','C','t','y','q','7','2','V','G','m','m','E','e','V','u','m','L','p','R','X','W','z','V','K','E','k','p','V','r','J', + 'd','N','3','t','i','u','S','V','w','2','w','U','Q','3','F','q','4','h','q','k','B','7','R','X','B','F','Q','Z','b','b','4','E', + 'K','v','T','B','w','k','V','C','x','d','K','g','N','S','u','k','p','9','z','w','c','y','U','M','V','E','2','Y','P','F','h','9', + 'T','y','h','w','b','9','P','w','G','c','W','W','k','j','J','Q','N','B','U','G','6','9','U','b','v','a','N','9','N','C','G','n', + 'x','R','6','9','Q','C','h','e','j','P','U','h','U','R','i','4','T','B','W','5','w','m','J','p','e','7','r','9','t','c','9','Z', + 'j','p','r','F','C','e','U','P','x','T','A','N','7','6','a','i','y','e','w','F','C','X','H','Y','G','C','q','q','m','A','t','7', + 'z','u','D','S','L','U','C','f','7','e','t','G','V','F','u','c','x','5','M','7','N','i','M','6','h','2','n','H','S','h','K','M', + 'd','T','z','X','d','x','x','4','q','z','d','D','a','2','X','r','p','r','R','m','U','U','y','S','H','c','a','F','e','Z','a','U', + 'P','9','V','J','e','q','j','Y','M','x','e','v','K','7','M','P','N','2','b','6','f','P','h','H','4','U','X','k','n','f','Q','M', + '9','9','a','J','N','e','w','y','f','F','P','p','a','F','Y','a','M','L','W','i','T','M','B','3','U','v','X','v','G','p','7','a', + 'f','u','4','S','y','X','9','g','g','b','B','G','c','i','M','U','n','m','a','7','q','f','9','n','Q','2','V','L','6','e','T','R', + '2','4','9','d','6','Q','B','Y','q','2','4','9','G','Q','E','b','Y','5','u','2','T','Q','G','L','5','n','4','Y','2','y','G','F', + 'j','c','8','M','G','L','e','3','a','N','v','A','A','W','t','R','S','2','i','D','R','8','j','d','Q','3','6','C','V','M','e','w', + 'j','U','Z','w','M','4','b','m','8','J','P','Q','L','P','R','c','r','b','V','C','3','N','8','K','4','d','W','D','N','U','A','A', + '2','J','p','b','D','d','p','j','N','C','k','A','j','B','a','c','u','v','L','X','U','B','4','U','X','W','e','C','b','C','u','d', + 'A','v','U','z','P','t','D','e','5','y','Y','c','x','K','4','7','j','e','e','D','M','5','K','B','Q','6','d','p','T','T','R','j', + 'M','E','E','M','r','N','6','8','7','q','x','F','S','x','E','U','4','d','B','6','5','W','C','e','m','J','e','5','j','w','V','J', + 'w','v','d','7','v','f','K','u','m','8','h','W','T','e','Q','j','M','8','R','Y','d','B','R','2','r','F','j','7','d','E','q','V', + 'k','e','j','P','9','3','X','R','p','R','b','A','v','7','4','A','M','2','k','r','E','7','X','3','7','k','5','c','B','7','W','5', + 'u','J','B','Q','R','2','V','7','h','Q','h','9','g','G','y','c','c','x','M','z','7','G','2','J','w','v','j','5','9','E','b','k', + 'z','W','T','C','b','4','K','R','X','T','k','V','S','G','2','j','d','6','y','E','4','P','H','K','w','a','m','F','Z','x','9','j', + 'i','2','d','X','u','a','4','a','M','z','8','p','p','z','g','t','H','5','Y','L','Q','c','R','F','m','E','n','G','X','d','f','7', + 'x','8','j','g','J','z','D','S','a','S','h','y','5','h','Y','N','p','w','Y','W','h','E','N','v','8','Q','D','W','Z','k','f','e', + 'r','Z','D','7','R','D','T','2','H','X','z','G','X','f','v','E','z','P','v','U','H','e','4','R','W','U','x','t','t','4','w','p', + 'r','z','K','9','f','g','h','P','r','f','v','k','h','c','e','5','8','a','L','F','J','M','G','R','a','N','q','S','g','W','e','7', + 'R','K','R','A','B','z','6','v','S','p','w','n','e','x','k','E','r','j','f','Y','x','8','9','z','e','T','6','E','G','v','9','f', + 'D','A','N','v','y','U','7','D','M','2','E','5','W','G','6','b','9','q','g','Y','F','f','k','q','Q','E','x','Y','C','R','G','6', + 'R','h','4','J','d','U','D','b','9','b','8','r','f','V','d','g','b','2','z','Z','d','m','X','v','j','Y','d','w','K','8','G','r', + 'v','j','N','y','c','h','u','5','z','g','J','H','a','Z','b','z','G','C','r','P','f','y','P','6','F','P','h','7','9','w','7','y', + 'R','3','n','E','h','G','D','4','m','Y','E','q','k','a','f','a','R','B','q','t','W','E','T','p','H','7','k','X','2','d','X','6', + 'W','n','H','m','w','M','i','Y','M','E','F','5','R','p','p','y','c','b','q','R','9','Y','t','T','7','w','u','K','M','Q','z','n', + 'P','7','g','x','6','R','4','x','N','v','w','M','6','j','K','v','7','a','Y','4','a','M','6','n','z','3','E','2','V','N','4','i', + 'E','f','u','W','J','W','e','8','3','Q','e','a','F','P','c','3','P','k','i','z','d','q','m','q','M','a','d','8','D','3','F','M', + 'e','d','E','j','z','V','e','d','z','H','D','J','8','X','g','E','i','u','c','7','A','w','S','J','2','A','e','8','r','q','C','m', + '9','9','a','g','2','y','y','P','M','e','8','3','T','r','m','8','j','v','r','p','M','Z','Y','g','a','9','2','d','H','B','m','9', + '4','6','a','Z','V','u','S','H','g','3','X','h','i','N','3','B','S','E','k','9','k','2','9','R','A','i','3','L','X','M','B','S', + '4','S','F','F','F','w','u','d','M','T','9','K','B','7','R','U','R','8','D','8','T','5','U','t','E','R','x','n','x','h','v','k', + 'B','N','k','E','U','T','t','p','r','u','Z','h','t','E','4','i','P','z','f','z','q','M','p','f','A','K','2','D','t','j','f','c', + 'Y','E','N','M','x','k','g','7','T','U','2','c','d','V','g','2','z','L','i','j','Y','q','b','T','A','y','v','a','t','N','5','t', + 'Z','5','n','D','a','y','G','n','P','x','V','k','M','8','t','J','Z','G','g','5','9','R','h','P','P','J','N','X','p','G','J','p', + '2','y','A','v','d','G','U','z','3','V','M','y','q','U','N','M','Y','p','B','Z','U','h','j','q','z','q','x','w','7','d','J','Q', + 'u','F','q','3','m','9','c','Q','W','d','6','7','b','V','M','7','P','j','r','k','9','h','R','z','m','b','i','B','u','E','L','9', + 'k','v','h','h','W','2','K','e','M','U','Q','p','A','Q','Y','J','G','E','T','U','L','f','q','G','4','z','K','K','y','a','U','W', + 'K','D','P','c','N','D','V','S','Y','6','T','p','R','y','y','J','a','T','J','W','Q','9','p','F','P','X','y','k','9','z','z','4', + 'G','d','a','z','X','n','h','4','J','P','W','V','D','r','U','m','a','8','a','b','X','F','J','X','L','4','S','X','5','W','p','W', + 'h','y','x','B','f','d','C','X','w','7','r','g','V','T','H','a','i','4','N','v','c','w','n','2','3','A','i','A','J','9','N','c', + 'z','7','n','n','3','n','h','n','i','R','i','b','E','h','k','U','c','c','U','6','f','x','q','N','y','H','M','e','J','B','U','B', + 'r','g','a','8','V','a','G','V','y','u','c','c','v','C','H','W','y','g','z','Q','2','4','k','S','m','f','e','G','H','v','Q','3', + 'P','e','f','S','V','P','c','U','e','3','P','x','d','c','7','c','f','g','D','w','2','t','q','y','g','2','Q','V','4','K','a','Q', + 'g','B','b','L','x','9','m','a','K','4','i','x','g','Q','M','9','W','N','2','w','p','v','2','k','B','y','9','k','A','c','f','Z', + 'D','R','A','S','d','v','w','f','f','q','t','K','3','j','x','D','G','P','n','u','r','v','U','k','A','2','d','R','N','T','G','4', + 'B','g','k','t','h','7','J','k','F','A','C','g','W','g','J','F','z','S','Q','c','v','M','b','D','e','H','Q','S','j','v','G','E', + 'R','k','f','i','P','E','F','N','6','y','p','b','t','M','c','Q','B','7','g','w','J','7','3','d','V','E','m','z','6','6','P','P', + 'd','i','r','J','H','D','H','J','r','b','n','v','z','W','e','u','g','B','u','Z','2','m','D','5','h','F','X','B','2','r','6','w', + 'u','Y','4','N','X','K','a','v','V','3','j','B','r','r','C','c','w','R','g','S','8','V','b','F','2','N','M','c','K','8','Y','E', + 'E','N','K','X','K','V','B','x','n','Q','p','a','q','f','k','t','z','Y','E','P','Z','y','n','a','c','B','V','a','x','b','d','X', + 'r','d','8','P','H','F','v','r','V','5','g','J','w','6','i','h','d','d','p','J','c','c','Y','S','q','W','m','U','5','G','b','H', + 'N','z','E','Z','K','E','y','M','c','G','i','d','w','Z','D','N','N','w','S','t','g','y','a','Y','b','H','e','M','N','f','Y','Y', + '7','a','9','b','M','U','k','a','V','k','C','n','a','k','U','H','A','M','i','v','k','t','a','d','i','3','F','d','5','2','A','p', + 'U','c','J','U','R','h','G','d','A','Y','v','q','X','c','w','r','x','4','j','3','4','b','F','d','a','L','N','J','3','Z','g','6', + 'W','Q','R','u','P','t','M','A','3','F','6','y','K','Y','G','2','t','v','u','p','w','b','G','S','K','5','p','4','d','E','w','6', + 'g','t','V','4','b','2','n','b','Z','3','3','f','m','d','2','c','a','m','j','X','U','E','D','6','6','F','w','H','9','7','Z','Y', + 'd','X','C','K','i','g','p','F','Y','n','2','b','F','4','R','u','V','k','f','d','J','i','a','b','X','H','7','v','K','a','Q','i', + 'W','M','j','M','i','a','i','n','F','h','r','q','4','w','x','m','4','q','y','F','8','w','i','4','D','B','A','L','B','U','u','K', + 'v','K','n','a','Q','i','e','k','v','Q','U','5','w','Q','c','r','A','6','M','w','y','g','n','e','v','K','7','W','u','2','y','f', + 'Q','u','e','r','y','a','w','V','p','f','Q','z','C','u','i','i','9','S','P','q','L','r','C','H','S','3','E','p','8','S','m','Q', + 'S','K','r','V','b','J','R','m','w','c','n','Q','N','Q','4','M','u','f','X','S','f','U','Z','x','U','4','j','K','4','G','z','X', + '7','Q','j','R','h','i','G','m','q','c','V','T','x','U','a','E','b','Q','q','E','i','F','K','7','K','i','R','J','5','Y','F','V', + 'B','7','R','8','M','i','f','j','Z','w','j','b','B','u','p','N','Y','r','S','r','f','h','E','J','T','B','P','R','D','V','K','A', + 'Z','A','R','j','z','f','B','i','Y','L','F','G','V','Y','w','R','C','P','G','m','9','7','C','5','e','y','w','N','K','N','a','Q', + 'j','a','W','3','2','f','G','w','n','M','6','F','u','K','8','g','8','M','G','r','e','9','Z','z','y','2','G','U','k','G','6','m', + 'A','D','4','n','b','8','a','q','S','m','S','6','5','R','5','D','5','S','B','g','X','T','8','Q','V','d','A','n','g','y','8','a', + 'h','7','K','9','H','D','J','F','w','G','4','w','T','J','F','f','i','8','X','e','B','J','K','H','7','V','y','X','7','E','8','S', + 'A','d','b','w','S','8','Y','a','J','d','j','E','V','J','T','E','U','R','5','7','V','M','E','v','D','3','z','5','r','k','z','v', + 'e','m','A','7','P','8','j','X','E','f','Q','q','8','D','g','y','8','j','A','e','B','c','c','M','z','k','2','c','q','v','v','y', + 'Q','y','h','g','p','v','M','m','m','C','G','D','k','8','u','T','n','Q','H','G','H','f','b','J','j','5','X','c','i','7','7','q', + 'b','R','8','b','b','z','f','f','h','Y','Q','7','u','B','X','e','i','j','M','q','C','T','M','v','t','J','J','w','b','F','v','J', + 'm','e','2','u','e','8','L','V','G','q','A','j','m','7','m','g','m','5','i','r','p','p','U','y','F','6','f','b','u','6','q','L', + 'M','E','t','V','W','C','t','e','p','w','a','n','w','y','X','h','8','e','G','C','H','q','r','X','G','9','c','h','7','k','8','M', + 'G','b','a','m','Y','Q','w','8','J','z','a','F','r','4','W','M','j','P','q','a','z','U','y','u','3','b','Z','f','Y','5','7','g', + 'N','M','h','M','a','3','C','K','6','6','f','a','p','i','f','q','k','T','i','z','w','f','Z','c','H','L','X','g','6','m','g','r', + 'w','Y','u','K','8','L','p','8','P','R','A','R','A','b','Z','V','a','x','V','c','G','A','H','t','Y','6','P','T','L','W','N','z', + 'g','z','k','d','E','v','C','t','Z','M','Z','K','4','w','9','5','D','W','f','U','8','5','u','6','b','5','B','8','g','y','C','E', + 'Q','z','e','9','p','N','S','P','D','D','f','x','k','Z','4','R','v','X','V','k','p','b','n','t','c','F','R','e','x','9','C','D', + 'J','2','6','f','Z','D','w','J','R','j','j','9','b','w','N','N','p','R','f','Z','z','j','F','r','Q','e','F','x','f','t','V','V', + 'A','y','J','G','W','Z','H','r','D','5','M','u','H','V','L','N','U','V','X','z','j','9','r','v','e','d','R','c','u','V','x','r', + 'c','6','k','L','h','q','w','U','W','Q','g','G','F','C','t','E','a','D','h','x','9','5','P','R','Z','E','M','5','f','4','2','t', + 'A','6','f','r','X','G','X','Y','B','8','G','E','n','B','v','x','f','M','R','f','B','z','Y','3','2','q','z','G','t','P','C','6', + '6','r','z','J','r','c','n','d','6','h','e','w','D','D','h','V','L','u','i','b','5','K','d','S','y','9','N','p','E','r','D','k', + 'B','z','u','v','d','Q','p','K','5','m','J','r','b','Y','Z','7','p','M','J','F','E','q','x','f','E','K','U','U','4','f','a','6', + 'g','5','a','q','D','U','8','F','y','R','a','P','5','5','x','z','6','V','T','P','D','m','y','7','U','5','C','A','7','Q','h','w', + 'r','6','x','g','Q','i','b','K','F','p','B','X','Q','h','i','E','r','C','z','v','x','W','Q','6','p','6','b','M','K','V','x','u', + 'k','d','R','S','k','Q','p','n','h','d','Q','Y','x','n','x','5','K','t','5','w','A','5','p','k','F','z','W','p','j','U','y','V', + 'x','G','m','y','L','A','X','H','G','A','a','J','5','E','P','q','E','U','7','p','6','A','9','n','d','G','D','g','i','h','t','W', + 'b','c','E','2','P','d','y','J','M','u','4','g','P','S','X','J','v','w','3','v','D','q','U','i','U','T','q','E','Y','5','2','t', + 'b','j','P','2','j','D','9','y','i','B','5','Y','3','X','L','w','m','V','X','z','X','r','Z','d','H','L','A','H','k','R','X','5', + 'i','L','m','q','3','p','a','G','P','j','g','h','R','P','Y','U','z','M','5','R','M','A','E','Q','V','c','w','r','4','M','S','k', + 'N','D','i','R','R','x','t','q','T','i','u','N','K','R','x','Z','K','a','g','G','y','9','c','j','J','S','9','3','H','T','f','F', + 'q','6','D','W','F','K','h','e','p','p','b','q','N','k','A','C','m','y','u','B','J','v','q','D','e','j','e','b','2','w','R','t', + 'J','N','j','F','T','A','8','L','m','X','i','T','g','j','c','V','4','V','h','2','h','R','p','2','9','k','c','c','G','D','h','z', + 't','i','h','t','W','R','n','Y','i','8','u','6','G','9','T','P','9','9','J','P','Y','R','h','X','K','z','h','L','W','r','C','U', + '2','L','T','k','2','m','6','W','L','P','T','Z','z','t','i','H','5','G','w','t','E','v','z','k','b','H','b','b','W','W','u','b', + 'i','h','C','Q','n','H','N','u','5','u','K','X','r','M','W','U','3','Y','k','P','2','k','x','f','x','C','w','z','z','b','G','8', + 'y','W','e','j','v','2','v','r','t','q','z','p','Y','d','w','6','Z','D','J','L','9','F','z','G','U','4','a','8','H','6','U','a', + 'q','7','y','Q','J','v','m','D','P','S','j','q','v','t','n','t','g','j','3','t','8','f','K','K','7','b','W','d','F','i','N','K', + 'a','R','V','V','V','v','m','A','Q','2','y','j','c','t','f','k','j','7','X','y','j','b','U','F','w','W','3','9','6','A','S','J', + 'p','q','2','Z','7','L','p','b','7','b','5','i','p','r','r','h','P','M','h','j','c','y','e','u','h','B','d','9','9','u','f','d', + 'g','u','p','w','u','9','S','c','L','U','g','A','y','V','F','V','6','D','D','X','i','V','m','u','Y','P','J','v','L','T','A','F', + 'M','Q','H','Z','6','v','8','p','A','L','P','z','C','V','a','C','h','X','j','W','8','G','z','j','d','M','4','u','x','w','H','g', + 'V','q','K','z','b','g','2','3','D','N','y','G','X','F','T','v','T','L','y','v','L','9','g','c','C','R','8','L','A','7','Y','N', + 't','n','R','6','b','n','m','9','i','h','t','T','F','a','V','N','J','J','3','J','q','p','W','7','b','T','G','r','M','k','a','7', + 'D','H','v','y','T','A','C','U','P','u','q','L','R','Y','4','q','h','y','f','F','J','x','K','7','N','B','v','3','a','Z','M','t', + 'U','x','8','9','V','E','t','j','K','r','u','Y','Y','A','u','w','Y','2','y','Q','z','S','n','J','B','2','t','X','x','K','z','g', + '6','d','n','i','7','Z','N','F','Q','6','w','N','r','b','k','d','W','X','S','t','c','U','m','6','4','2','e','w','6','x','Z','a', + 'Q','A','7','4','h','H','z','r','e','J','q','j','w','4','q','c','i','R','4','x','n','r','j','r','P','g','E','7','t','k','b','Z', + 'r','A','b','d','g','i','G','V','D','E','U','L','b','J','U','q','2','S','K','m','A','U','L','k','Q','4','N','p','k','G','C','6', + 'R','Z','B','y','B','B','j','y','x','L','d','h','L','G','6','x','H','z','T','5','d','Y','4','2','m','q','Q','y','H','6','c','N', + 'u','m','U','v','i','Y','Z','7','4','L','K','F','b','v','2','Y','h','x','8','a','R','w','q','x','E','a','T','y','m','C','2','Q', + 'U','T','D','Q','v','u','M','9','D','8','r','8','b','m','p','E','7','C','T','9','B','A','G','k','b','G','z','Z','G','L','N','k', + 'h','3','k','J','e','f','d','x','F','8','W','K','7','T','6','h','H','V','C','h','P','u','H','e','v','w','z','P','K','r','D','G', + 'X','Z','B','X','f','H','Q','4','e','D','y','W','Z','6','4','K','A','e','a','F','S','N','h','x','S','W','J','c','E','P','g','j', + 'a','w','T','m','Z','X','E','P','Y','R','M','2','R','2','X','N','F','X','Y','W','x','z','p','J','g','n','D','4','i','p','6','N', + 'r','9','G','k','E','h','T','h','U','h','x','B','Q','9','H','7','w','U','P','Q','d','G','6','q','p','j','j','v','C','a','X','J', + 'N','G','Y','w','f','H','C','x','F','k','z','3','9','r','h','8','7','5','V','i','V','C','R','q','x','N','2','2','i','W','F','U', + '7','T','H','f','z','E','a','n','u','Q','t','U','Y','G','t','3','A','m','r','6','d','f','e','n','e','z','F','u','U','N','8','m', + 'h','p','R','N','S','H','6','6','V','M','S','t','q','P','E','i','u','y','g','8','L','Q','Y','Y','G','e','W','W','C','G','y','b', + 'y','t','u','P','R','P','5','m','N','K','B','Z','w','f','t','k','x','3','L','b','q','d','w','S','G','E','h','R','F','4','q','e', + '5','6','F','2','n','q','T','R','y','f','n','Y','h','2','F','u','x','M','i','i','h','w','G','C','Z','v','i','C','a','X','U','C', + 'Y','8','d','h','R','x','V','n','v','G','i','D','a','U','p','U','a','e','b','F','w','P','d','X','n','K','h','9','H','r','b','g', + '2','f','m','X','k','m','q','6','n','5','b','G','H','d','R','9','D','U','c','r','Z','Y','W','S','Z','x','p','t','x','y','4','k', + 'j','F','U','t','C','i','e','i','b','p','e','4','C','z','h','3','3','5','Q','P','n','G','i','A','8','c','Q','z','B','a','V','4', + '2','B','2','z','u','u','3','i','L','w','y','g','K','H','k','y','2','B','b','e','5','e','4','e','U','4','z','n','P','z','a','c', + 'E','f','u','M','G','C','g','z','j','4','E','7','R','t','D','K','c','t','p','g','W','H','C','H','J','Q','J','c','F','5','4','W', + 'K','7','j','h','A','T','K','z','t','S','f','f','j','C','c','8','n','7','c','T','U','R','Q','E','7','A','W','Z','z','K','5','j', + '2','H','k','a','j','g','g','W','w','4','T','A','9','J','U','e','S','N','P','K','d','k','L','Q','G','Z','e','W','i','H','u','j', + 'C','z','4','E','2','v','5','L','u','9','Z','a','9','A','b','C','M','G','X','B','C','2','Y','Z','e','U','n','E','5','Y','n','y', + 'F','h','H','p','9','j','Y','F','V','w','Y','r','8','Q','f','C','J','4','T','t','z','Q','N','M','e','7','4','3','y','E','M','m', + 'b','S','c','h','w','a','X','E','d','E','z','t','h','9','k','p','A','k','K','H','x','q','K','Z','B','u','a','9','3','U','U','u', + '8','E','D','v','y','k','W','Y','X','k','r','R','D','X','n','Q','V','d','e','D','g','x','E','V','Y','w','k','m','K','r','H','D', + 't','2','6','N','U','g','3','t','B','9','t','u','M','D','z','Y','K','z','K','r','V','5','i','e','p','M','d','t','w','6','a','f', + 'f','W','k','L','i','g','M','V','M','Y','b','x','e','4','h','h','Y','g','w','Z','m','e','e','6','R','W','M','x','G','y','V','n', + '6','e','g','A','g','K','a','N','7','p','a','u','E','4','6','M','t','X','h','g','b','j','p','5','x','x','B','P','3','J','M','7', + 'j','Z','P','y','e','Q','Z','e','t','j','3','t','F','V','x','m','b','b','B','y','J','L','L','9','3','R','a','5','j','S','V','t', + 'e','2','6','m','H','w','r','w','r','6','Q','3','x','z','m','A','d','x','t','E','H','c','Z','x','c','P','j','r','u','U','W','k', + '6','g','X','g','n','f','n','7','H','M','B','t','v','6','v','x','g','M','f','e','2','w','m','y','d','H','S','q','c','K','U','H', + '2','X','h','d','p','Q','7','J','X','i','X','f','a','z','V','A','F','2','8','z','v','h','C','h','e','4','g','z','w','z','h','q', + 'p','6','B','n','m','8','h','W','U','7','z','h','T','6','J','f','4','Z','n','Q','W','z','2','N','4','t','g','7','u','4','X','2', + 'C','F','L','n','J','n','m','j','3','P','3','Y','e','J','R','A','H','e','R','D','z','7','u','X','Y','y','D','w','J','m','G','U', + 'P','H','5','S','d','a','F','F','Y','c','M','f','3','3','L','v','V','B','U','C','A','d','N','H','Q','h','7','8','4','r','p','G', + 'v','M','D','H','7','e','E','r','i','K','Q','i','B','D','M','Z','p','c','R','G','u','c','H','a','N','k','E','f','9','R','7','x', + '6','3','5','u','x','3','h','v','p','6','q','r','j','u','f','W','T','q','P','n','Y','L','B','6','U','w','P','2','T','W','R','g', + '2','3','3','e','N','V','a','j','b','e','4','T','u','J','u','u','F','B','D','G','H','x','x','k','5','G','e','3','4','B','m','L', + 'S','b','i','t','T','p','M','D','Z','A','A','i','r','J','p','4','H','U','A','G','y','d','Q','5','U','R','F','8','q','a','S','H', + 'n','5','z','9','g','3','u','R','H','m','G','m','b','p','c','L','Z','Y','u','m','i','K','A','Q','R','T','X','G','t','b','8','7', + '7','6','w','M','N','f','R','G','r','L','m','q','n','7','5','k','X','8','g','u','K','7','Y','w','K','q','U','e','W','A','r','i', + 'Z','a','p','q','L','5','P','u','n','t','y','G','x','C','N','X','q','P','r','U','v','A','r','r','q','e','f','c','z','M','7','N', + '6','a','z','Z','a','t','f','p','4','v','J','Y','j','h','M','D','t','k','A','B','p','Q','A','y','x','X','7','p','S','8','m','M', + 'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'}; + +static const adler32_test tests[] = { + {0x1, (const uint8_t *)0x0, 0, 0x1}, + {0x1, (const uint8_t *)"", 1, 0x10001}, + {0x1, (const uint8_t *)"a", 1, 0x620062}, + {0x1, (const uint8_t *)"abacus", 6, 0x8400270}, + {0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4}, + {0x1, (const uint8_t *)"campfire", 8, 0xea10348}, + {0x1, (const uint8_t *)"delta", 5, 0x61a020b}, + {0x1, (const uint8_t *)"executable", 10, 0x16fa0423}, + {0x1, (const uint8_t *)"file", 4, 0x41401a1}, + {0x1, (const uint8_t *)"greatest", 8, 0xefa0360}, + {0x1, (const uint8_t *)"inverter", 8, 0xf6f0370}, + {0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286}, + {0x1, (const uint8_t *)"karate", 6, 0x8a50279}, + {0x1, (const uint8_t *)"landscape", 9, 0x126a03ac}, + {0x1, (const uint8_t *)"machine", 7, 0xb5302d6}, + {0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca}, + {0x1, (const uint8_t *)"oblivion", 8, 0xf220363}, + {0x1, (const uint8_t *)"panama", 6, 0x8a1026f}, + {0x1, (const uint8_t *)"quest", 5, 0x6970233}, + {0x1, (const uint8_t *)"resource", 8, 0xf8d0369}, + {0x1, (const uint8_t *)"secret", 6, 0x8d10287}, + {0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366}, + {0x1, (const uint8_t *)"vector", 6, 0x8fb0294}, + {0x1, (const uint8_t *)"walrus", 6, 0x918029f}, + {0x1, (const uint8_t *)"xeno", 4, 0x45e01bb}, + {0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5}, + {0x1, (const uint8_t *)"zero", 4, 0x46e01c1}, + {0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d}, + {0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f}, + {0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e}, + {0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650}, + {0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690}, + {0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609}, + {0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703}, + {0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7}, + {0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698}, + {0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6}, + {0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c}, + {0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9}, + {0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769}, + {0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5}, + {0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750}, + {0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414}, + {0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405}, + {0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423}, + {0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421}, + {0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b}, + {0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d}, + {0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a}, + {0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d}, + {0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417}, + {0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412}, + {0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420}, + {0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419}, + {0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f}, + {0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f}, + {0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417}, + {0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841}, + {0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751}, + {0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a}, + {0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815}, + {0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661}, + {0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3}, + {0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb}, + {0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680}, + {0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f}, + {0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee}, + {0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92}, + {0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96}, + {0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8}, + {0x1, (const uint8_t *)long_string, 5552, 0x8b81718f}, + {0x7a30360d, (const uint8_t *)0x0, 0, 0x1}, + {0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee}, + {0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea}, + {0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da}, + {0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5}, + {0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44}, + {0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521}, + {0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2}, + {0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a}, + {0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01}, + {0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9}, + {0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4}, + {0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d}, + {0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024}, + {0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b}, + {0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb}, + {0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb}, + {0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f}, + {0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92}, + {0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5}, + {0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390}, + {0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39}, + {0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c}, + {0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516}, + {0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b}, + {0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4}, + {0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00}, + {0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b}, + {0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8}, + {0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c}, + {0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f}, + {0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f}, + {0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd}, + {0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446}, + {0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148}, + {0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc}, + {0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284}, + {0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706}, + {0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a}, + {0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db}, + {0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8}, + {0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd}, + {0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4}, + {0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218}, + {0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38}, + {0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8}, + {0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af}, + {0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c}, + {0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda}, + {0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006}, + {0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c}, + {0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4}, + {0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b}, + {0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3}, + {0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3}, + {0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a}, + {0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0}, + {0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8}, + {0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8}, + {0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54}, + {0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e}, + {0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c}, + {0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c}, + {0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9}, + {0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652}, + {0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e}, + {0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664}, + {0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911}, + {0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73}, + {0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8}, + {0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2}, +}; + +class adler32_variant : public ::testing::TestWithParam { +public: + void hash(adler32_test param, adler32_func adler32) { + uint32_t adler = adler32((uint32_t)param.adler, param.buf, param.len); + EXPECT_EQ(adler, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests)); + +#define TEST_ADLER32(name, func, support_flag) \ + TEST_P(adler32_variant, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_ADLER32(c, adler32_c, 1) + +#ifdef ARM_NEON +TEST_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon) +#elif defined(POWER8_VSX) +TEST_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(PPC_VMX) +TEST_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec) +#endif + +#ifdef X86_SSSE3 +TEST_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3) +#endif +#ifdef X86_AVX2 +TEST_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2) +#endif +#ifdef X86_AVX512 +TEST_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512) +#endif +#ifdef X86_AVX512VNNI +TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni) +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_aligned_alloc.cc b/internal-complibs/zlib-ng-2.1.2/test/test_aligned_alloc.cc new file mode 100644 index 000000000..07f99a9da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_aligned_alloc.cc @@ -0,0 +1,48 @@ +/* test_aligned_alloc.cc - Test zng_alloc_aligned and zng_free_aligned */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil.h" +} + +#include + +#include "test_shared.h" + +void *zng_calloc_unaligned(void *opaque, unsigned items, unsigned size) { + uint8_t *pointer = (uint8_t *)calloc(1, (items * size) + 2); + Z_UNUSED(opaque); + if (pointer == NULL) + return pointer; + /* Store whether or not our allocation is aligned */ + *pointer = ((uint64_t)(intptr_t)pointer + 1) % 2 == 0; + pointer++; + if (*pointer) { + /* Return pointer that is off by one */ + pointer++; + } + return (void *)pointer; +} + +void zng_cfree_unaligned(void *opaque, void *ptr) { + uint8_t *pointer = (uint8_t *)ptr; + Z_UNUSED(opaque); + pointer--; + /* Get whether or not our original memory pointer was aligned */ + if (*pointer) { + /* Return original aligned pointer to free() */ + pointer--; + } + free(pointer); +} + +TEST(zalloc, aligned_64) { + void *return_ptr = PREFIX3(alloc_aligned)(zng_calloc_unaligned, 0, 1, 100, 64); + ASSERT_TRUE(return_ptr != NULL); + EXPECT_EQ((intptr_t)return_ptr % 64, 0); + PREFIX3(free_aligned)(zng_cfree_unaligned, 0, return_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_compare256.cc b/internal-complibs/zlib-ng-2.1.2/test/test_compare256.cc new file mode 100644 index 000000000..0e656da37 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_compare256.cc @@ -0,0 +1,83 @@ +/* test_compare256.cc -- compare256 unit tests + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +#include "test_shared.h" + +#define MAX_COMPARE_SIZE (256) + + +/* Ensure that compare256 returns the correct match length */ +static inline void compare256_match_check(compare256_func compare256) { + int32_t match_len, i; + uint8_t *str1; + uint8_t *str2; + + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + + for (i = 0; i <= MAX_COMPARE_SIZE; i++) { + if (i < MAX_COMPARE_SIZE) + str2[i] = 0; + + match_len = compare256(str1, str2); + EXPECT_EQ(match_len, i); + + if (i < MAX_COMPARE_SIZE) + str2[i] = 'a'; + } + + zng_free(str1); + zng_free(str2); +} + +#define TEST_COMPARE256(name, func, support_flag) \ + TEST(compare256, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + compare256_match_check(func); \ + } + +TEST_COMPARE256(c, compare256_c, 1) + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +TEST_COMPARE256(unaligned_16, compare256_unaligned_16, 1) +#ifdef HAVE_BUILTIN_CTZ +TEST_COMPARE256(unaligned_32, compare256_unaligned_32, 1) +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(unaligned_64, compare256_unaligned_64, 1) +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2) +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2) +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon) +#endif +#ifdef POWER9 +TEST_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00) +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_compare256_rle.cc b/internal-complibs/zlib-ng-2.1.2/test/test_compare256_rle.cc new file mode 100644 index 000000000..da60d6f97 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_compare256_rle.cc @@ -0,0 +1,63 @@ +/* test_compare256_rle.cc -- compare256_rle unit tests + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "compare256_rle.h" +} + +#include + +#define MAX_COMPARE_SIZE (256) + +/* Ensure that compare256_rle returns the correct match length */ +static inline void compare256_rle_match_check(compare256_rle_func compare256_rle) { + int32_t match_len, i; + uint8_t str1[] = {'a', 'a', 0}; + uint8_t *str2; + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + + for (i = 0; i <= MAX_COMPARE_SIZE; i++) { + if (i < MAX_COMPARE_SIZE) + str2[i] = 0; + + match_len = compare256_rle(str1, str2); + EXPECT_EQ(match_len, i); + + if (i < MAX_COMPARE_SIZE) + str2[i] = 'a'; + } + + zng_free(str2); +} + +#define TEST_COMPARE256_RLE(name, func, support_flag) \ + TEST(compare256_rle, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + compare256_rle_match_check(func); \ + } + +TEST_COMPARE256_RLE(c, compare256_rle_c, 1) + +#ifdef UNALIGNED_OK +TEST_COMPARE256_RLE(unaligned_16, compare256_rle_unaligned_16, 1) +#ifdef HAVE_BUILTIN_CTZ +TEST_COMPARE256_RLE(unaligned_32, compare256_rle_unaligned_32, 1) +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256_RLE(unaligned_64, compare256_rle_unaligned_64, 1) +#endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_compress.cc b/internal-complibs/zlib-ng-2.1.2/test/test_compress.cc new file mode 100644 index 000000000..e069b69d3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_compress.cc @@ -0,0 +1,33 @@ +/* test_compress.cc - Test compress() and uncompress() using hello world string */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic) { + uint8_t compr[128], uncompr[128]; + z_uintmax_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = PREFIX(compress)(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_compress_bound.cc b/internal-complibs/zlib-ng-2.1.2/test/test_compress_bound.cc new file mode 100644 index 000000000..b83b59f4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_compress_bound.cc @@ -0,0 +1,59 @@ +/* test_compress_bound.cc - Test compressBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +class compress_bound_variant : public testing::TestWithParam { +public: + void estimate(int32_t level) { + z_size_t estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t dest[128]; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + + /* buffer with values for worst case compression */ + for (int32_t j = 0; j < MAX_LENGTH; j++) { + uncompressed[j] = (uint8_t)j; + } + + for (z_size_t i = 0; i < MAX_LENGTH; i++) { + z_uintmax_t dest_len = sizeof(dest); + + /* calculate actual output length */ + estimate_len = PREFIX(compressBound)(i); + + err = PREFIX(compress2)(dest, &dest_len, uncompressed, i, level); + EXPECT_EQ(err, Z_OK); + EXPECT_GE(estimate_len, dest_len) << + "level: " << level << "\n" << + "length: " << i; + } + + free(uncompressed); + } +}; + +TEST_P(compress_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(compress_bound, compress_bound_variant, + testing::Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_compress_dual.cc b/internal-complibs/zlib-ng-2.1.2/test/test_compress_dual.cc new file mode 100644 index 000000000..a92ab4be3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_compress_dual.cc @@ -0,0 +1,28 @@ +/* test_compress_dual.cc - Test linking against both zlib and zlib-ng */ + +#include "zlib.h" + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic_zlib) { + Byte compr[128], uncompr[128]; + uLong compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = compress(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_cpu_features.h b/internal-complibs/zlib-ng-2.1.2/test/test_cpu_features.h new file mode 100644 index 000000000..1bb4b13a0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_cpu_features.h @@ -0,0 +1,8 @@ +#ifndef TEST_CPU_FEATURES_H +#define TEST_CPU_FEATURES_H + +#include "cpu_features.h" + +extern struct cpu_features test_cpu_features; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_crc32.cc b/internal-complibs/zlib-ng-2.1.2/test/test_crc32.cc new file mode 100644 index 000000000..f194b4ccf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_crc32.cc @@ -0,0 +1,222 @@ +/* test_crc32.cc -- crc32 unit test + * Copyright (C) 2019-2021 IBM Corporation + * Authors: Rogerio Alves + * Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + unsigned long crc; + const uint8_t *buf; + size_t len; + unsigned long expect; +} crc32_test; + +static const crc32_test tests[] = { + {0x0, (const uint8_t *)0x0, 0, 0x0}, + {0xffffffff, (const uint8_t *)0x0, 0, 0x0}, + {0x0, (const uint8_t *)0x0, 255, 0x0}, /* BZ 174799. */ + {0x0, (const uint8_t *)0x0, 256, 0x0}, + {0x0, (const uint8_t *)0x0, 257, 0x0}, + {0x0, (const uint8_t *)0x0, 32767, 0x0}, + {0x0, (const uint8_t *)0x0, 32768, 0x0}, + {0x0, (const uint8_t *)0x0, 32769, 0x0}, + {0x0, (const uint8_t *)"", 0, 0x0}, + {0xffffffff, (const uint8_t *)"", 0, 0xffffffff}, + {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b}, + {0x0, (const uint8_t *)"backlog", 7, 0x269205}, + {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8}, + {0x0, (const uint8_t *)"delta", 5, 0x9643fed9}, + {0x0, (const uint8_t *)"executable", 10, 0xd68eda01}, + {0x0, (const uint8_t *)"file", 4, 0x8c9f3610}, + {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd}, + {0x0, (const uint8_t *)"hello", 5, 0x3610a686}, + {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9}, + {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69}, + {0x0, (const uint8_t *)"karate", 6, 0x890be0e2}, + {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b}, + {0x0, (const uint8_t *)"machine", 7, 0x1505df84}, + {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39}, + {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77}, + {0x0, (const uint8_t *)"panama", 6, 0x66b8979c}, + {0x0, (const uint8_t *)"quest", 5, 0x4317f817}, + {0x0, (const uint8_t *)"resource", 8, 0xbc91f416}, + {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5}, + {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c}, + {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b}, + {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b}, + {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97}, + {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444}, + {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5}, + {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a}, + {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1}, + {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e}, + {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76}, + {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a}, + {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d}, + {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5}, + {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11}, + {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac}, + {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb}, + {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9}, + {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37}, + {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0}, + {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29}, + {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8}, + {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192}, + {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0}, + {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7}, + {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546}, + {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c}, + {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca}, + {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7}, + {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5}, + {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba}, + {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8}, + {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662}, + {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2}, + {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b}, + {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937}, + {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f}, + {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4}, + {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4}, + {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631}, + {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99}, + {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac}, + {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9}, + {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf}, + {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac}, + {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388}, + {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d}, + {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5}, + {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9}, + {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777}, + {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048}, + {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84}, + {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1}, + {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca}, + {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1}, + {0xdc712e2, (const uint8_t *)"executable", 10, 0x761b4254}, + {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b}, + {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b}, + {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5}, + {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109}, + {0xab058a2, (const uint8_t *)"karate", 6, 0xc5591f41}, + {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644}, + {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636}, + {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb}, + {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b}, + {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4}, + {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36}, + {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925}, + {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db}, + {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8}, + {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d}, + {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef}, + {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5}, + {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38}, + {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127}, + {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0}, + {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274}, + {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870}, + {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd}, + {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc}, + {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178}, + {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070}, + {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0}, + {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72}, + {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620}, + {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d}, + {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24}, + {0x3275b9f, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df}, + {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30}, + {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9}, + {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7}, + {0xe75b214, (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d}, + {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7}, + {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7}, + {0x54b8e14, (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2}, + {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461}, + {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a}, + {0xbe92385, (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12}, + {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c}, + {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1}, + {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2}, + {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1}, + {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83}, + {0x75770fc, (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81}, + {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404}, + {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010}, + {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3}, + {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f}, + {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de}, + {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59}, + {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f}, + {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac}, + {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66}, + {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7}, + {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a}, + {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060}, + {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312}, + {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912}, + {0xc45aef77, (const uint8_t *) + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B} +}; + +class crc32_variant : public ::testing::TestWithParam { +public: + void hash(crc32_test param, crc32_func crc32) { + uint32_t crc = 0; + if (param.buf != NULL) { + if (param.len) { + crc = crc32(param.crc, param.buf, param.len); + } else { + crc = param.crc; + } + } + EXPECT_EQ(crc, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests)); + +#define TEST_CRC32(name, func, support_flag) \ + TEST_P(crc32_variant, name) { \ + if (!(support_flag)) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_CRC32(braid, PREFIX(crc32_braid), 1) + +#ifdef ARM_ACLE +TEST_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32) +#elif defined(POWER8_VSX_CRC32) +TEST_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(S390_CRC32_VX) +TEST_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx) +#elif defined(X86_PCLMULQDQ_CRC) +TEST_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq) +# ifdef X86_VPCLMULQDQ_CRC +TEST_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512 && test_cpu_features.x86.has_vpclmulqdq)) +# endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_cve-2003-0107.cc b/internal-complibs/zlib-ng-2.1.2/test/test_cve-2003-0107.cc new file mode 100644 index 000000000..9d9e5b00d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_cve-2003-0107.cc @@ -0,0 +1,28 @@ +// https://www.securityfocus.com/archive/1/312869 --- originally by Richard Kettlewell +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if !defined(_WIN32) && defined(ZLIB_COMPAT) +TEST(gzip, cve_2003_0107) { + gzFile f; + int ret; + + f = gzopen("/dev/null", "w"); + EXPECT_TRUE(f != NULL); + + ret = gzprintf(f, "%10240s", ""); + printf("gzprintf -> %d\n", ret); + ret = gzclose(f); + printf("gzclose -> %d [%d]\n", ret, errno); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_bound.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_bound.cc new file mode 100644 index 000000000..c86d4e00b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_bound.cc @@ -0,0 +1,99 @@ +/* test_deflate_bound.cc - Test deflateBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +typedef struct { + int32_t level; + int32_t window_size; + int32_t mem_level; + bool after_init; +} deflate_bound_test; + +static const deflate_bound_test tests[] = { + {0, MAX_WBITS + 16, 1, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, false}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, false}, +}; + +class deflate_bound_variant : public testing::TestWithParam { +public: + void estimate(deflate_bound_test param) { + PREFIX3(stream) c_stream; + int estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t *out_buf = NULL; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + memset(uncompressed, 'a', MAX_LENGTH); + + for (int32_t i = 0; i < MAX_LENGTH; i++) { + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.avail_in = i; + c_stream.next_in = (z_const unsigned char *)uncompressed; + c_stream.avail_out = 0; + c_stream.next_out = out_buf; + + if (!param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + + err = PREFIX(deflateInit2)(&c_stream, param.level, Z_DEFLATED, + param.window_size, param.mem_level, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* calculate actual output length and update structure */ + if (param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + out_buf = (uint8_t *)malloc(estimate_len); + + if (out_buf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimate_len; + c_stream.next_out = out_buf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END) << + "level: " << param.level << "\n" << + "window_size: " << param.window_size << "\n" << + "mem_level: " << param.mem_level << "\n" << + "after_init: " << param.after_init << "\n" << + "length: " << i; + + free(out_buf); + out_buf = NULL; + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + } + + free(uncompressed); + } +}; + +TEST_P(deflate_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(deflate_bound, deflate_bound_variant, testing::ValuesIn(tests)); diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_concurrency.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_concurrency.cc new file mode 100644 index 000000000..1297aee64 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_concurrency.cc @@ -0,0 +1,170 @@ +/* Test deflate() on concurrently modified next_in. + * + * Plain zlib does not document that this is supported, but in practice it tolerates this, and QEMU live migration is + * known to rely on this. Make sure zlib-ng tolerates this as well. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +#include "zlib.h" +#else +#include "zlib-ng.h" +#endif + +#include + +#include +#include +#include +#include + +static uint8_t buf[8 * 1024]; +static uint8_t zbuf[4 * 1024]; +static uint8_t tmp[8 * 1024]; + +/* Thread that increments all bytes in buf by 1. */ +class Mutator { + enum class State { + PAUSED, + RUNNING, + STOPPED, + }; + +public: + Mutator() + : m_state(State::PAUSED), m_target_state(State::PAUSED), + m_thread(&Mutator::run, this) {} + ~Mutator() { + transition(State::STOPPED); + m_thread.join(); + } + + void pause() { + transition(State::PAUSED); + } + + void resume() { + transition(State::RUNNING); + } + +private: + void run() { + while (true) { + m_state.store(m_target_state); + if (m_state == State::PAUSED) + continue; + if (m_state == State::STOPPED) + break; + for (uint8_t & i: buf) + i++; + } + } + + void transition(State target_state) { + m_target_state = target_state; + while (m_state != target_state) { + } + } + + std::atomic m_state, m_target_state; + std::thread m_thread; +}; + +TEST(deflate, concurrency) { +#ifdef S390_DFLTCC_DEFLATE + GTEST_SKIP() << "Known to be broken with S390_DFLTCC_DEFLATE"; +#endif + + /* Create reusable mutator and streams. */ + Mutator mutator; + + PREFIX3(stream) dstrm; + memset(&dstrm, 0, sizeof(dstrm)); + int err = PREFIX(deflateInit2)(&dstrm, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + PREFIX3(stream) istrm; + memset(&istrm, 0, sizeof(istrm)); + err = PREFIX(inflateInit2)(&istrm, -15); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Iterate for a certain amount of time. */ + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < deadline) { + /* Start each iteration with a fresh stream state. */ + err = PREFIX(deflateReset)(&dstrm); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + err = PREFIX(inflateReset)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Mutate and compress the first half of buf concurrently. + * Decompress and throw away the results, which are unpredictable. + */ + mutator.resume(); + dstrm.next_in = buf; + dstrm.avail_in = sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << istrm.msg; + } + } + + /* Stop mutation and compress the second half of buf. + * Decompress and check that the result matches. + */ + mutator.pause(); + dstrm.next_in = buf + sizeof(buf) / 2; + dstrm.avail_in = sizeof(buf) - sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_FINISH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, dstrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + size_t orig_total_out = istrm.total_out; + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, istrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << istrm.msg; + size_t concurrent_size = sizeof(buf) - sizeof(buf) / 2; + if (istrm.total_out > concurrent_size) { + size_t tmp_offset, buf_offset, size; + if (orig_total_out >= concurrent_size) { + tmp_offset = 0; + buf_offset = orig_total_out - concurrent_size; + size = istrm.total_out - orig_total_out; + } else { + tmp_offset = concurrent_size - orig_total_out; + buf_offset = 0; + size = istrm.total_out - concurrent_size; + } + ASSERT_EQ(0, memcmp(tmp + tmp_offset, buf + sizeof(buf) / 2 + buf_offset, size)); + } + } + } + } + + err = PREFIX(inflateEnd)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + err = PREFIX(deflateEnd)(&dstrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_copy.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_copy.cc new file mode 100644 index 000000000..4adc9be96 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_copy.cc @@ -0,0 +1,60 @@ +/* test_deflate_copy.cc - Test deflateCopy() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "deflate.h" + +#include "test_shared.h" + +#include + +TEST(deflate, copy) { + PREFIX3(stream) c_stream, c_stream_copy; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&c_stream_copy, 0, sizeof(c_stream_copy)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(c_stream.state->status, c_stream_copy.state->status); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream_copy); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_dict.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_dict.cc new file mode 100644 index 000000000..781c70db2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_dict.cc @@ -0,0 +1,54 @@ +/* test_deflate_dict.cc - Test deflateGetDictionary() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, dictionary) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + uint32_t compr_len = sizeof(compr); + uint8_t *dict_new = NULL; + uint32_t *dict_len; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + dict_new = (uint8_t *)calloc(256, 1); + ASSERT_TRUE(dict_new != NULL); + dict_len = (uint32_t *)calloc(4, 1); + ASSERT_TRUE(dict_len != NULL); + + err = PREFIX(deflateGetDictionary)(&c_stream, dict_new, dict_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(dict_new); + free(dict_len); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_hash_head_0.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_hash_head_0.cc new file mode 100644 index 000000000..cbf601038 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_hash_head_0.cc @@ -0,0 +1,83 @@ +/* Generated by fuzzing - test hash_head == 0 handling. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, hash_head_0) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY); + EXPECT_EQ(err, Z_OK); + + unsigned char next_in[9698]; + memset(next_in, 0x30, sizeof(next_in)); + next_in[8193] = 0x00; + next_in[8194] = 0x00; + next_in[8195] = 0x00; + next_in[8199] = 0x8a; + strm.next_in = next_in; + unsigned char next_out[21572]; + strm.next_out = next_out; + + strm.avail_in = 0; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 3, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 6728; + strm.avail_out = 2696; + err = PREFIX(deflate(&strm, Z_SYNC_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 15; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 9, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 1453; + strm.avail_out = 1348; + err = PREFIX(deflate(&strm, Z_FULL_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in); + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_header.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_header.cc new file mode 100644 index 000000000..0d1b7d044 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_header.cc @@ -0,0 +1,71 @@ +/* test_deflate_header.cc - Test deflateSetHeader() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, header) { + PREFIX3(stream) c_stream; + PREFIX(gz_header) *head; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + head = (PREFIX(gz_header) *)calloc(1, sizeof(PREFIX(gz_header))); + ASSERT_TRUE(head != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + EXPECT_EQ(err, Z_OK); + + PREFIX(deflateBound)(&c_stream, (unsigned long)compr_len); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + /* Check CRC32. */ + EXPECT_EQ(c_stream.adler, 0xb56c3f9dU); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(head); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_params.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_params.cc new file mode 100644 index 000000000..9fadea85f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_params.cc @@ -0,0 +1,143 @@ +/* test_deflate_params.cc - Test deflate() with dynamic change of compression level */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "deflate.h" + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (64 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, params) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + uint32_t diff; + int32_t i; + time_t now; + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + /* Feed in already compressed data and switch to no compression: */ +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_BEST_SPEED); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); +#endif + + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* Switch back to compressing mode: */ +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_NO_COMPRESSION); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); +#endif + + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncompr_len; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + do { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } while (err == Z_OK); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, (2 * uncompr_len) + diff); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_pending.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_pending.cc new file mode 100644 index 000000000..8ccedbf33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_pending.cc @@ -0,0 +1,66 @@ +/* test_deflate_pending.cc - Test deflatePending() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, pending) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int *bits; + unsigned *ped; + int err; + + + bits = (int *)calloc(256, 1); + ASSERT_TRUE(bits != NULL); + ped = (unsigned *)calloc(256, 1); + ASSERT_TRUE(ped != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + EXPECT_EQ(err, Z_OK); + + EXPECT_GE(*bits, 0); + EXPECT_LE(*bits, 7); + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(bits); + free(ped); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_prime.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_prime.cc new file mode 100644 index 000000000..75dcf3177 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_prime.cc @@ -0,0 +1,91 @@ +/* test_deflate_prime.cc - Test deflatePrime() wrapping gzip around deflate stream */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared_ng.h" + +#include + +TEST(deflate, prime) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t crc = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + EXPECT_EQ(err, Z_OK); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + EXPECT_EQ(err, Z_OK); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + EXPECT_EQ(err, Z_OK); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len); + err = deflate_prime_32(&c_stream, crc); + EXPECT_EQ(err, Z_OK); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)hello_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_BUF_ERROR); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_bi_valid.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_bi_valid.cc new file mode 100644 index 000000000..8ce4c229d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_bi_valid.cc @@ -0,0 +1,80 @@ +/* Generated by fuzzing - test bi_valid handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, bi_valid) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[554] = { + 0x8d, 0xff, 0xff, 0xff, 0xa2, 0x00, 0x00, 0xff, 0x00, 0x15, 0x1b, 0x1b, 0xa2, 0xa2, 0xaf, 0xa2, + 0xa2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x07, 0x01, 0x18, 0x00, 0x22, 0x00, + 0x00, 0x00, 0xfd, 0x39, 0xff, 0x00, 0x00, 0x00, 0x1b, 0xfd, 0x3b, 0x00, 0x68, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0x57, 0xf8, 0x1e, 0x00, 0x00, 0xf2, 0xf2, 0xf2, 0xf2, 0xfa, 0xff, 0xff, 0xff, + 0xff, 0x7e, 0x00, 0x00, 0x4a, 0x00, 0xc5, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x01, 0x00, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4a, 0x4a, 0x4a, 0x32, + 0x00, 0xf9, 0xff, 0x00, 0x02, 0x9a, 0xff, 0x00, 0x00, 0x3f, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x08, 0x2f, 0x20, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7a, 0x7a, 0x9e, 0xff, 0xff, 0x00, 0x1b, 0x1b, 0x04, 0x00, 0x1b, 0x1b, + 0x1b, 0x1b, 0x00, 0x00, 0x00, 0xaf, 0xad, 0xaf, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2e, 0xff, + 0xff, 0x2e, 0xc1, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x00, 0xda, 0x67, 0x01, + 0x47, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x3f, + 0x54, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x34, 0x3e, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x40, 0x1b, 0x1b, 0x88, 0x1b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1f, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x50, 0x3e, 0x7a, 0x7a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xff, 0x3d, 0x00, 0x11, 0x4d, 0x00, 0x00, 0x01, 0xd4, 0xd4, 0xd4, 0xd4, 0x2d, 0xd4, + 0xd4, 0xff, 0xff, 0xff, 0xfa, 0x01, 0xd4, 0x00, 0xd4, 0x00, 0x00, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, + 0xd4, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00, 0xfe, 0xf9, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, + 0x16, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, + 0xff, 0x2b, 0x2b, 0x2b, 0x2b, 0x35, 0xd4, 0xd4, 0x47, 0x3f, 0xd4, 0xd4, 0xd6, 0xd4, 0xd4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x4a, 0x4a, 0x4a, 0x4a, 0x71, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, + 0x1f, 0x1b, 0x1b, 0x1b, 0x57, 0x57, 0x57, 0x57, 0x00, 0x00, 0x1b, 0x08, 0x2b, 0x16, 0xc3, 0x00, + 0x00, 0x00, 0x29, 0x30, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x07, 0x00, 0x00, 0x01, 0x0b, 0xff, + 0xff, 0xf5, 0xf5, 0xf5, 0x00, 0x00, 0xfe, 0xfa, 0x0f, 0x0f, 0x08, 0x00, 0xff, 0x00, 0x53, 0x3f, + 0x00, 0x04, 0x5d, 0xa8, 0x2e, 0xff, 0xff, 0x00, 0x2f, 0x2f, 0x05, 0xff, 0xff, 0xff, 0x2f, 0x2f, + 0x2f, 0x0a, 0x0a, 0x0a, 0x0a, 0x30, 0xff, 0xff, 0xff, 0xf0, 0x0a, 0x0a, 0x0a, 0x00, 0xff, 0x3f, + 0x4f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x71, 0x00, 0x71, 0x71, 0x71, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x3f, 0x00, 0xfa, 0x71, 0x71, 0x71, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x71, 0x71, 0x71, 0x71, 0x71}; + strm.next_in = next_in; + unsigned char next_out[1236]; + strm.next_out = next_out; + + strm.avail_in = 554; + strm.avail_out = 31; + + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 0; + strm.avail_out = 498; + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_block_open.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_block_open.cc new file mode 100644 index 000000000..84a1ac8bb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_quick_block_open.cc @@ -0,0 +1,94 @@ +/* Generated by fuzzing - test block_open handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, block_open) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -MAX_WBITS, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[495] = + "\x1d\x1d\x00\x00\x00\x4a\x4a\x4a\xaf\xaf\xaf\xaf\x4a\x4a\x4a\x4a" + "\x3f\x3e\xaf\xff\xff\xff\x11\xff\xff\xff\xff\xdf\x00\x00\x00\x01" + "\x3f\x7d\x00\x50\x00\x00\xc8\x01\x2b\x60\xc8\x00\x24\x06\xff\xff" + "\x4a\x4e\x4a\x7d\xc8\x01\xf1\x2b\x28\xb2\xb2\x60\x25\xc8\x06\x00" + "\x00\x00\x31\x00\x01\xb2\xb2\xb2\xff\xff\xfd\xb2\xb2\x40\xff\x7d" + "\x3b\x34\x3e\xff\xff\x4a\x4a\x01\xf1\xff\x02\xff\x3f\xff\x02\xff" + "\xff\xff\xbf\x0a\xff\x00\x01\x3f\xb3\xff\x26\x00\x00\x13\x00\xc8" + "\x3e\x3e\x3e\x4a\x76\x4a\x4a\x2e\x7d\x3e\x3e\x3e\x3e\x1d\x1d\x1d" + "\xfe\xea\xef\x80\x01\x00\x00\x40\x00\x00\xba\x00\x06\xfa\xb9\x11" + "\xbf\x98\xee\x45\x7e\x04\x00\xff\xff\xff\x67\xc3\xc3\xc3\xc3\x00" + "\x1d\x1d\xe1\xe3\x00\xc3\x1d\x98\x1d\x1d\x1d\x1d\x1d\x00\x00\x00" + "\x02\x00\x00\x00\xe8\x00\x00\x1d\x1d\x1d\xfa\x1e\x12\xff\xff\xff" + "\x00\x01\xa7\xff\xff\xff\x1d\x1d\x1d\x63\xff\xff\xff\x1f\x00\x00" + "\x10\x40\x00\x00\xad\xff\xff\x3f\x51\x00\xf8\xff\xff\x8a\x01\x05" + "\x00\x00\x03\x00\x00\xff\x00\x00\x00\x05\x40\x1f\x08\x0a\x00\xff" + "\xff\x01\x00\x12\x00\x00\x01\x00\x3f\x40\x1d\x1d\x1d\x1d\x1d\x1d" + "\x21\x00\x1d\x00\x00\x00\xe4\x00\x00\x00\x07\x00\x00\xe6\xe6\x34" + "\xe6\xe6\xe6\xe6\xff\x2b\xee\x1d\x1d\x1d\x93\x1d\x1d\x1d\xee\x2b" + "\xee\x01\x81\x1d\x00\x00\x58\x00\x00\x01\x14\x00\x1b\x00\x00\x2c" + "\x00\x00\x00\xdb\x00\x45\x7e\x00\x00\x00\xfb\xbd\x00\x06\x21\xd3" + "\x00\xff\xff\xff\xff\xff\x00\x49\x49\xc9\x49\x3d\x00\x34\x01\x00" + "\x00\x6a\x2b\x00\x00\x50\x40\xf0\xf0\xf0\xf0\xa3\xa3\xa3\xa3\xf0" + "\xf0\x06\xfa\xa9\x01\x10\xbf\x98\x9d\x2b\xee\x2d\x21\x01\xdb\x00" + "\x45\x10\x00\x00\x7e\x00\x00\xe7\x00\xff\xff\x00\xf6\x00\x00\x00" + "\xf9\x00\x00\x00\x11\x00\x00\x00\xe2\x00\x00\x00\x2d\x00\x00\x00" + "\x2f\x00\x3f\x54\x1d\x1d\x1d\x4c\x4c\x4c\x4c\x2a\x4c\x4c\x10\xff" + "\xff\x1a\x00\x00\x01\xff\x00\xff\xf9\x00\x3f\x53\xcc\xcc\xcc\xcc" + "\x6e\x00\x00\x01\xf8\xff\xff\xff\x49\x04\x2c\x01\x00\x1d\x00\x07" + "\x01\xff\x00\x00\x00\xf8\xff\x09\x00\x27\x00\x08\x21\x1c\x00\x00" + "\x00\x00\x1d\x05\x00\x00\x00\x2c\x53\x3f\x00\x01\x00\x00\xe6\xff" + "\xff\xff\x6a\x2b\xee\xe6\x6a\x2b\xee\x2b\xee\xee\x2b\xee"; + strm.next_in = next_in; + unsigned char next_out[1116]; + strm.next_out = next_out; + + strm.avail_in = sizeof(next_in); + while (1) { + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + if (strm.avail_out > 38) + strm.avail_out = 38; + err = PREFIX(deflate)(&strm, Z_FINISH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_deflate_tune.cc b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_tune.cc new file mode 100644 index 000000000..9921ee643 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_deflate_tune.cc @@ -0,0 +1,56 @@ +/* test_deflate_tune.cc - Test deflateTune() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, tune) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateTune)(&c_stream, good_length, max_lazy,nice_length, max_chain); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_dict.cc b/internal-complibs/zlib-ng-2.1.2/test/test_dict.cc new file mode 100644 index 000000000..af9662e3d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_dict.cc @@ -0,0 +1,96 @@ +/* test_dict.cc - Test deflate() and inflate() with preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + +static const char dictionary[] = "hello"; + +TEST(dictionary, basic) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t dict_adler = 0; + uint8_t check_dict[MAX_DICTIONARY_SIZE]; + uint32_t check_dict_len = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char *)dictionary, (int)sizeof(dictionary)); + EXPECT_EQ(err, Z_OK); + + dict_adler = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncompr_len; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + EXPECT_EQ(d_stream.adler, dict_adler); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (uint32_t)sizeof(dictionary)); + EXPECT_EQ(d_stream.adler, dict_adler); + } + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_GE(check_dict_len, sizeof(dictionary)); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dict, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_TRUE(memcmp(dictionary, check_dict, sizeof(dictionary)) == 0); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(strncmp((char*)uncompr, hello, sizeof(hello)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_gzio.cc b/internal-complibs/zlib-ng-2.1.2/test/test_gzio.cc new file mode 100644 index 000000000..3cab1dbe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_gzio.cc @@ -0,0 +1,105 @@ +/* test_gzio.cc - Test read/write of .gz files */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define TESTFILE "foo.gz" + +TEST(gzip, readwrite) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); + GTEST_SKIP(); +#else + uint8_t compr[128], uncompr[128]; + uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + size_t read; + int64_t pos; + gzFile file; + int err; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(TESTFILE, "wb"); + ASSERT_TRUE(file != NULL); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4); + EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8); + /* Write string null-teriminator using gzseek */ + EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0); + /* Write hello, hello! using gzfwrite using best compression level */ + EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK); + EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0UL); + /* Flush compressed bytes to file */ + EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK); + compr_len = (uint32_t)PREFIX(gzoffset)(file); + EXPECT_GE(compr_len, 0UL); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(TESTFILE, "rb"); + ASSERT_TRUE(file != NULL); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len)); + EXPECT_STREQ((char*)uncompr, hello); + + /* Check position at the end of the gz file */ + EXPECT_EQ(PREFIX(gzeof)(file), 1); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + EXPECT_EQ(pos, 6); + EXPECT_EQ(PREFIX(gztell)(file), pos); + EXPECT_EQ(PREFIX(gzgetc)(file), ' '); + EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' '); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len); + EXPECT_EQ(strlen((char*)uncompr), 7UL); /* " hello!" */ + EXPECT_STREQ((char*)uncompr, hello + 6); + + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + EXPECT_EQ(pos, 14); + EXPECT_EQ(PREFIX(gztell)(file), pos); + + /* Check position not at end of file */ + EXPECT_EQ(PREFIX(gzeof)(file), 0); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file); + EXPECT_STREQ((const char *)uncompr, hello); + + pos = PREFIX(gzoffset)(file); + EXPECT_GE(pos, 0); + EXPECT_EQ(pos, (compr_len + 10)); + + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + EXPECT_NE(err, 0); + + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + EXPECT_EQ(err, 0); + + PREFIX(gzclose)(file); + + EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR); + Z_UNUSED(read); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_inflate_adler32.cc b/internal-complibs/zlib-ng-2.1.2/test/test_inflate_adler32.cc new file mode 100644 index 000000000..fb78bb1bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_inflate_adler32.cc @@ -0,0 +1,50 @@ +/* GH-1066 - inflate small amount of data and validate with adler32 checksum. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +const char* original = "The quick brown fox jumped over the lazy dog"; + +z_const unsigned char compressed[] = { + 0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48, + 0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d, + 0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8, + 0x49, 0xac, 0xaa, 0x54, 0x48, 0xc9, 0x4f, 0x07, 0x00, 0x6b, 0x93, 0x10, 0x30 +}; + +TEST(inflate, adler32) { + unsigned char uncompressed[1024]; + PREFIX3(stream) strm; + + memset(&strm, 0, sizeof(strm)); + + int err = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = compressed; + strm.avail_in = sizeof(compressed); + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + EXPECT_EQ(strm.adler, 0x6b931030); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_inflate_sync.cc b/internal-complibs/zlib-ng-2.1.2/test/test_inflate_sync.cc new file mode 100644 index 000000000..a79d867e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_inflate_sync.cc @@ -0,0 +1,75 @@ +/* test_inflate_sync.cc - Test inflateSync using full flush deflate and corrupted data */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(inflate, sync) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + /* build compressed stream with full flush */ + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* force an error in first compressed block */ + compr[3]++; + c_stream.avail_in = hello_len-3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + compr_len = (z_size_t)c_stream.total_out; + + memset(&d_stream, 0, sizeof(d_stream)); + /* just read the zlib header */ + d_stream.next_in = compr; + d_stream.avail_in = 2; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* read all compressed data, but skip damaged part */ + d_stream.avail_in = (uint32_t)compr_len-2; + err = PREFIX(inflateSync)(&d_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_large_buffers.cc b/internal-complibs/zlib-ng-2.1.2/test/test_large_buffers.cc new file mode 100644 index 000000000..3c1208140 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_large_buffers.cc @@ -0,0 +1,87 @@ +/* test_large_buffers.cc - Test deflate() and inflate() with large buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (32 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, large_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + int32_t i; + time_t now; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = compr_len; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, uncompr_len); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_main.cc b/internal-complibs/zlib-ng-2.1.2/test/test_main.cc new file mode 100644 index 000000000..82b39e487 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_main.cc @@ -0,0 +1,19 @@ +/* test_test.cc - Main entry point for test framework */ + +#include + +#include "gtest/gtest.h" + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" + + struct cpu_features test_cpu_features; +} + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + cpu_check_features(&test_cpu_features); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_raw.cc b/internal-complibs/zlib-ng-2.1.2/test/test_raw.cc new file mode 100644 index 000000000..a013d4bb4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_raw.cc @@ -0,0 +1,58 @@ +/* test_raw.cc - Test raw streams. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(raw, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[512]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + stream.adler = 0x12345678; + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x12345678); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + stream.adler = 0x87654321; + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x87654321); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_shared.h b/internal-complibs/zlib-ng-2.1.2/test/test_shared.h new file mode 100644 index 000000000..616f57342 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_shared.h @@ -0,0 +1,18 @@ +#ifndef TEST_SHARED_H +#define TEST_SHARED_H + +/* Test definitions that can be used in the original zlib build environment. */ + +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ +static const char hello[] = "hello, hello!"; +static const int hello_len = sizeof(hello); + +/* Clang static analyzer doesn't understand googletest's ASSERT_TRUE, so we need to tell that it's like assert() */ +#ifdef __clang_analyzer__ +# undef ASSERT_TRUE +# define ASSERT_TRUE assert +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_shared_ng.h b/internal-complibs/zlib-ng-2.1.2/test/test_shared_ng.h new file mode 100644 index 000000000..81e451998 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_shared_ng.h @@ -0,0 +1,23 @@ +#ifndef TEST_SHARED_NG_H +#define TEST_SHARED_NG_H + +#include "test_shared.h" + +/* Test definitions that can only be used in the zlib-ng build environment. */ + +static inline int deflate_prime_32(PREFIX3(stream) *stream, uint32_t value) { + int err; + +#ifdef ZLIBNG_ENABLE_TESTS + err = PREFIX(deflatePrime)(stream, 32, value); +#else + /* zlib's deflatePrime() takes at most 16 bits */ + err = PREFIX(deflatePrime)(stream, 16, value & 0xffff); + if (err != Z_OK) return err; + err = PREFIX(deflatePrime)(stream, 16, value >> 16); +#endif + + return err; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_small_buffers.cc b/internal-complibs/zlib-ng-2.1.2/test/test_small_buffers.cc new file mode 100644 index 000000000..bb3449fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_small_buffers.cc @@ -0,0 +1,69 @@ +/* test_small_buffers.cc - Test deflate() and inflate() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, small_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + /* Finish the stream, still forcing small buffers */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + while (d_stream.total_out < uncompr_len && d_stream.total_in < compr_len) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char*)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_small_window.cc b/internal-complibs/zlib-ng-2.1.2/test/test_small_window.cc new file mode 100644 index 000000000..e351efac0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_small_window.cc @@ -0,0 +1,67 @@ +/* test_small_window.cc - Test deflate() and inflate() with a small window and a preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(small_window, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[128]; + unsigned char dictionary1[(1 << 9) - sizeof(plain) / 2]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_COMPRESSION, Z_DEFLATED, -9, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Use a large dictionary that is loaded in two parts */ + memset(dictionary1, 'a', sizeof(dictionary1)); + err = PREFIX(deflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + err = PREFIX(deflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -9); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + err = PREFIX(inflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.2/test/test_version.cc b/internal-complibs/zlib-ng-2.1.2/test/test_version.cc new file mode 100644 index 000000000..fda87904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/test/test_version.cc @@ -0,0 +1,27 @@ +/* test_version.cc - Test zVersion() and zlibCompileFlags() */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(version, basic) { + static const char *my_version = PREFIX2(VERSION); + + EXPECT_EQ(zVersion()[0], my_version[0]); + EXPECT_STREQ(zVersion(), PREFIX2(VERSION)); + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); +} diff --git a/internal-complibs/zlib-ng-2.1.2/tools/config.sub b/internal-complibs/zlib-ng-2.1.2/tools/config.sub new file mode 100755 index 000000000..dba175ae3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/tools/config.sub @@ -0,0 +1,17 @@ +#!/bin/sh +# Canonicalize CHOST. +# In particular, converts Debian multiarch tuples into GNU triplets. +# See also +# https://wiki.debian.org/Multiarch/Tuples +# https://wiki.gentoo.org/wiki/CHOST +# If you need an architecture not listed here, file a bug at github.com/zlib-ng/zlib-ng +# and work around the problem by dropping libtool's much more comprehensive config.sub +# on top of this file, see +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +case "$1" in +*-*-linux-gnu*) echo $1;; +i686-linux-gnu*|x86_64-linux-gnu*) echo $1 | sed 's/-linux-gnu/-pc-linux-gnu/';; +*-linux-gnu*) echo $1 | sed 's/-linux-gnu/-unknown-linux-gnu/';; +*) echo $1;; +esac diff --git a/internal-complibs/zlib-ng-2.1.2/tools/makecrct.c b/internal-complibs/zlib-ng-2.1.2/tools/makecrct.c new file mode 100644 index 000000000..5c3ba58a1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/tools/makecrct.c @@ -0,0 +1,250 @@ +/* makecrct.c -- output crc32 tables + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#include +#include +#include "zbuild.h" +#include "zutil.h" + +/* + The crc32 table header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. +*/ + +#define W 8 /* Need a 64-bit integer type in order to generate crc32 tables. */ + +#include "crc32_braid_p.h" + +static uint32_t crc_table[256]; +static z_word_t crc_big_table[256]; + +static uint32_t crc_braid_table[W][256]; +static z_word_t crc_braid_big_table[W][256]; +static uint32_t x2n_table[32]; + +#include "crc32_braid_comb_p.h" + +static void make_crc_table(void); +static void print_crc_table(void); + +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w); + +static void write_table(const uint32_t *table, int k); +static void write_table32hi(const z_word_t *table, int k); +static void write_table64(const z_word_t *table, int k); + +/* ========================================================================= */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table(void) { + unsigned i, j, n; + uint32_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; + crc_big_table[i] = ZSWAP64(p); + } + + /* initialize the x^2^n mod p(x) table */ + p = (uint32_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +} + +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + uint32_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp(((z_off64_t)n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = ZSWAP64(q); + } + } +} + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +static void write_table(const uint32_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +static void write_table32hi(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +static void write_table64(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%016" PRIx64 "%s", n == 0 || n % 3 ? "" : " ", + (uint64_t)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +static void print_crc_table(void) { + int k, n; + uint32_t ltl[8][256]; + z_word_t big[8][256]; + + printf("#ifndef CRC32_BRAID_TBL_H_\n"); + printf("#define CRC32_BRAID_TBL_H_\n\n"); + printf("/* crc32_braid_tbl.h -- tables for braided CRC calculation\n"); + printf(" * Generated automatically by makecrct.c\n */\n\n"); + + /* print little-endian CRC table */ + printf("static const uint32_t crc_table[] = {\n"); + printf(" "); + write_table(crc_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 64-bit z_word_t */ + printf("#ifdef W\n\n"); + printf("#if W == 8\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table64(crc_big_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 32-bit z_word_t */ + printf("#else /* W == 4 */\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table32hi(crc_big_table, 256); + printf("};\n\n"); + printf("#endif\n\n"); + printf("#endif /* W */\n\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + printf("#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t */ + printf("\n"); + printf("#if W == 8\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table64(big[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t */ + printf("\n"); + printf("#else /* W == 4 */\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table32hi(big[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("#endif /* W */\n\n"); + + printf("#endif /* N == %d */\n", n); + } + printf("\n"); + + /* write out zeros operator table */ + printf("static const uint32_t x2n_table[] = {\n"); + printf(" "); + write_table(x2n_table, 32); + printf("};\n"); + + printf("\n"); + printf("#endif /* CRC32_BRAID_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate crc32 tables +int main(int argc, char *argv[]) { + Z_UNUSED(argc); + Z_UNUSED(argv); + + make_crc_table(); + print_crc_table(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/tools/makefixed.c b/internal-complibs/zlib-ng-2.1.2/tools/makefixed.c new file mode 100644 index 000000000..7fe71e75e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/tools/makefixed.c @@ -0,0 +1,89 @@ +#include +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +// Build and return state with length and distance decoding tables and index sizes set to fixed code decoding. +void Z_INTERNAL buildfixedtables(struct inflate_state *state) { + static code *lenfix, *distfix; + static code fixed[544]; + + // build fixed huffman tables + unsigned sym, bits; + static code *next; + + // literal/length table + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + zng_inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + // distance table + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + zng_inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + + +// Create fixed tables on the fly and write out a inffixed_tbl.h file that is #include'd above. +// makefixed() writes those tables to stdout, which would be piped to inffixed_tbl.h. +void makefixed(void) { + unsigned low, size; + struct inflate_state state; + + memset(&state, 0, sizeof(state)); + buildfixedtables(&state); + puts("/* inffixed_tbl.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts("/* WARNING: this file should *not* be used by applications."); + puts(" * It is part of the implementation of this library and is"); + puts(" * subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf("static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) + printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); + size = 1U << 5; + printf("\nstatic const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) + printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); +} + +// The output of this application can be piped out to recreate inffixed_tbl.h +int main(void) { + makefixed(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/tools/maketrees.c b/internal-complibs/zlib-ng-2.1.2/tools/maketrees.c new file mode 100644 index 000000000..2c32ccae0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/tools/maketrees.c @@ -0,0 +1,147 @@ +/* maketrees.c -- output static huffman trees + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" + +static ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see zng_tr_init). + */ + +static ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use 5 bits.) + */ + +static unsigned char dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances 3 .. 258, + * the last 256 values correspond to the top 8 bits of the 15 bit distances. + */ + +static unsigned char length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; +/* length code for each normalized match length (0 == STD_MIN_MATCH) */ + +static int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = STD_MIN_MATCH) */ + +static int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + + +static void tr_static_init(void) { + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + length_code[length++] = (unsigned char)code; + } + } + Assert(length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented in two different + * ways: code 284 + 5 bits or code 285, so we overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (unsigned char)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + dist_code[dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) + bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the tree construction + * to get a canonical Huffman tree (longest code all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = PREFIX(bi_reverse)((unsigned)n, 5); + } +} + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +static void gen_trees_header(void) { + int i; + + printf("#ifndef TREES_TBL_H_\n"); + printf("#define TREES_TBL_H_\n\n"); + + printf("/* header created automatically with maketrees.c */\n\n"); + + printf("Z_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + printf("{{%3u},{%u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + printf("Z_INTERNAL const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("{{%2u},{%u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + printf("const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + printf("%2u%s", dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + printf("const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = {\n"); + for (i = 0; i < STD_MAX_MATCH-STD_MIN_MATCH+1; i++) { + printf("%2u%s", length_code[i], SEPARATOR(i, STD_MAX_MATCH-STD_MIN_MATCH, 20)); + } + + printf("Z_INTERNAL const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + printf("%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + printf("Z_INTERNAL const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); + } + + printf("#endif /* TREES_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate trees.h +int main(void) { + tr_static_init(); + gen_trees_header(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.2/trees.c b/internal-complibs/zlib-ng-2.1.2/trees.c new file mode 100644 index 000000000..5bb88389b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/trees.c @@ -0,0 +1,818 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2021 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" +#include "trees_emit.h" +#include "trees_tbl.h" + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const int *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + unsigned int max_length; /* max bit length for the codes */ +}; + +static const static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +static const static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +static const static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +static void init_block (deflate_state *s); +static void pqdownheap (deflate_state *s, ct_data *tree, int k); +static void gen_bitlen (deflate_state *s, tree_desc *desc); +static void build_tree (deflate_state *s, tree_desc *desc); +static void scan_tree (deflate_state *s, ct_data *tree, int max_code); +static void send_tree (deflate_state *s, ct_data *tree, int max_code); +static int build_bl_tree (deflate_state *s); +static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); +static void compress_block (deflate_state *s, const ct_data *ltree, const ct_data *dtree); +static int detect_data_type (deflate_state *s); +static void bi_flush (deflate_state *s); + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void Z_INTERNAL zng_tr_init(deflate_state *s) { + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +static void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) + s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) + s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) + s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +static void pqdownheap(deflate_state *s, ct_data *tree, int k) { + /* tree: the tree to restore */ + /* k: node to move down */ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) + break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +static void gen_bitlen(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const int *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + unsigned int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + unsigned int bits; /* bit length */ + int xbits; /* extra bits */ + uint16_t f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) + s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1u; + if (bits > max_length){ + bits = max_length; + overflow++; + } + tree[n].Len = (uint16_t)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) /* not a leaf node */ + continue; + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (unsigned long)f * (unsigned int)(bits + xbits); + if (stree) + s->static_len += (unsigned long)f * (unsigned int)(stree[n].Len + xbits); + } + if (overflow == 0) + return; + + Tracev((stderr, "\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) + bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2u; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) + continue; + if (tree[m].Len != bits) { + Tracev((stderr, "code %d bits %d->%u\n", m, tree[m].Len, bits)); + s->opt_len += (unsigned long)(bits * tree[m].Freq); + s->opt_len -= (unsigned long)(tree[m].Len * tree[m].Freq); + tree[m].Len = (uint16_t)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +Z_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { + /* tree: the tree to decorate */ + /* max_code: largest code with non zero frequency */ + /* bl_count: number of codes at each bit length */ + uint16_t next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned int code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (uint16_t)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert(code + bl_count[MAX_BITS]-1 == (1 << MAX_BITS)-1, "inconsistent bit counts"); + Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) + continue; + /* Now reverse the bits */ + tree[n].Code = PREFIX(bi_reverse)(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n & 0xff) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +static void build_tree(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0; + s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; + if (stree) + s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) + pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (unsigned char)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (uint16_t)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +static void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code: and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + uint16_t count = 0; /* repeat count of the current code */ + uint16_t max_count = 7; /* max repeat count */ + uint16_t min_count = 4; /* min repeat count */ + + if (nextlen == 0) + max_count = 138, min_count = 3; + + tree[max_code+1].Len = (uint16_t)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) + s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +static void send_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) + max_count = 138, min_count = 3; + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 2, bi_buf, bi_valid); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 3, bi_buf, bi_valid); + + } else { + send_code(s, REPZ_11_138, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-11, 7, bi_buf, bi_valid); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +static int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) + break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((unsigned long)max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +static void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes) { + int rank; /* index in bl_order */ + + Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5, bi_buf, bi_valid); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5, bi_buf, bi_valid); + send_bits(s, blcodes-4, 4, bi_buf, bi_valid); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2u ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3, bi_buf, bi_valid); + } + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + zng_tr_emit_tree(s, STORED_BLOCK, last); /* send block type */ + zng_tr_emit_align(s); /* align on byte boundary */ + cmpr_bits_align(s); + put_short(s, (uint16_t)stored_len); + put_short(s, (uint16_t)~stored_len); + cmpr_bits_add(s, 32); + sent_bits_add(s, 32); + if (stored_len) { + memcpy(s->pending_buf + s->pending, (unsigned char *)buf, stored_len); + s->pending += stored_len; + cmpr_bits_add(s, stored_len << 3); + sent_bits_add(s, stored_len << 3); + } +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void Z_INTERNAL zng_tr_align(deflate_state *s) { + zng_tr_emit_tree(s, STATIC_TREES, 0); + zng_tr_emit_end_block(s, static_ltree, 0); + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block, or NULL if too old */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + unsigned long opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (UNLIKELY(s->sym_next == 0)) { + /* Emit an empty static tree block with no codes */ + opt_lenb = static_lenb = 0; + s->static_len = 7; + } else if (s->level > 0) { + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7) >> 3; + static_lenb = (s->static_len+3+7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %u lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) + opt_lenb = static_lenb; + + } else { + Assert(buf != NULL, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if (stored_len+4 <= opt_lenb && buf != NULL) { + /* 4: two words for the lengths + * The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zng_tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + zng_tr_emit_tree(s, STATIC_TREES, last); + compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); + cmpr_bits_add(s, s->static_len); + } else { + zng_tr_emit_tree(s, DYN_TREES, last); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); + cmpr_bits_add(s, s->opt_len); + } + Assert(s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and unsigned long implemented on 32 bits. + */ + init_block(s); + + if (last) { + zng_tr_emit_align(s); + } + Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +static void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { + /* ltree: literal tree */ + /* dtree: distance tree */ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + + if (s->sym_next != 0) { + do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + zng_emit_lit(s, ltree, lc); + } else { + zng_emit_dist(s, ltree, dtree, lc, dist); + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pending_buf overflow"); + } while (sx < s->sym_next); + } + + zng_emit_end_block(s, ltree, 0); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +static int detect_data_type(deflate_state *s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +static void bi_flush(deflate_state *s) { + if (s->bi_valid == 64) { + put_uint64(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else { + if (s->bi_valid >= 32) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid >= 16) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid >= 8) { + put_byte(s, s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } + } +} + +/* =========================================================================== + * Reverse the first len bits of a code using bit manipulation + */ +Z_INTERNAL uint16_t PREFIX(bi_reverse)(unsigned code, int len) { + /* code: the value to invert */ + /* len: its bit length */ + Assert(len >= 1 && len <= 15, "code length must be 1-15"); +#define bitrev8(b) \ + (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32) + return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len); +} diff --git a/internal-complibs/zlib-ng-2.1.2/trees.h b/internal-complibs/zlib-ng-2.1.2/trees.h new file mode 100644 index 000000000..e57f92648 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/trees.h @@ -0,0 +1,40 @@ +#ifndef TREES_H_ +#define TREES_H_ + +/* Constants */ + +#define DIST_CODE_LEN 512 +/* see definition of array dist_code in trees.c */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +static const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const unsigned char bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + /* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + + +/* Function definitions */ +void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/trees_emit.h b/internal-complibs/zlib-ng-2.1.2/trees_emit.h new file mode 100644 index 000000000..922daae50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/trees_emit.h @@ -0,0 +1,227 @@ +#ifndef TREES_EMIT_H_ +#define TREES_EMIT_H_ + +#include "zbuild.h" +#include "trees.h" + +#ifdef ZLIB_DEBUG +# include +# include +#endif + + +/* trees.h */ +extern Z_INTERNAL const ct_data static_ltree[L_CODES+2]; +extern Z_INTERNAL const ct_data static_dtree[D_CODES]; + +extern const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN]; +extern const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; + +extern Z_INTERNAL const int base_length[LENGTH_CODES]; +extern Z_INTERNAL const int base_dist[D_CODES]; + +/* Bit buffer and deflate code stderr tracing */ +#ifdef ZLIB_DEBUG +# define send_bits_trace(s, value, length) { \ + Tracevv((stderr, " l %2d v %4llx ", (int)(length), (long long)(value))); \ + Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ + } +# define send_code_trace(s, c) \ + if (z_verbose > 2) { \ + fprintf(stderr, "\ncd %3d ", (c)); \ + } +#else +# define send_bits_trace(s, value, length) +# define send_code_trace(s, c) +#endif + +/* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid)) + * unused bits in value. + */ +#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\ + uint64_t val = (uint64_t)t_val;\ + uint32_t len = (uint32_t)t_len;\ + uint32_t total_bits = bi_valid + len;\ + send_bits_trace(s, val, len);\ + sent_bits_add(s, len);\ + if (total_bits < BIT_BUF_SIZE) {\ + bi_buf |= val << bi_valid;\ + bi_valid = total_bits;\ + } else if (bi_valid == BIT_BUF_SIZE) {\ + put_uint64(s, bi_buf);\ + bi_buf = val;\ + bi_valid = len;\ + } else {\ + bi_buf |= val << bi_valid;\ + put_uint64(s, bi_buf);\ + bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\ + bi_valid = total_bits - BIT_BUF_SIZE;\ + }\ +} + +/* Send a code of the given tree. c and tree must not have side effects */ +#ifdef ZLIB_DEBUG +# define send_code(s, c, tree, bi_buf, bi_valid) { \ + send_code_trace(s, c); \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \ +} +#else +# define send_code(s, c, tree, bi_buf, bi_valid) \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid) +#endif + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +static void bi_windup(deflate_state *s) { + if (s->bi_valid > 56) { + put_uint64(s, s->bi_buf); + } else { + if (s->bi_valid > 24) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid > 8) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid > 0) { + put_byte(s, s->bi_buf); + } + } + s->bi_buf = 0; + s->bi_valid = 0; +} + +/* =========================================================================== + * Emit literal code + */ +static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + send_code(s, c, ltree, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + Tracecv(isgraph(c & 0xff), (stderr, " '%c' ", c)); + + return ltree[c].Len; +} + +/* =========================================================================== + * Emit match distance/length code + */ +static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + uint32_t c, extra; + uint8_t code; + uint64_t match_bits; + uint32_t match_bits_len; + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + /* Send the length code, len is the match length - STD_MIN_MATCH */ + code = zng_length_code[lc]; + c = code+LITERALS+1; + Assert(c < L_CODES, "bad l_code"); + send_code_trace(s, c); + + match_bits = ltree[c].Code; + match_bits_len = ltree[c].Len; + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + match_bits |= ((uint64_t)lc << match_bits_len); + match_bits_len += extra; + } + + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert(code < D_CODES, "bad d_code"); + send_code_trace(s, code); + + /* Send the distance code */ + match_bits |= ((uint64_t)dtree[code].Code << match_bits_len); + match_bits_len += dtree[code].Len; + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + match_bits |= ((uint64_t)dist << match_bits_len); + match_bits_len += extra; + } + + send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + return match_bits_len; +} + +/* =========================================================================== + * Emit end block + */ +static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n", + last, s->pending, (uint64_t)s->strm->total_out)); + Z_UNUSED(last); +} + +/* =========================================================================== + * Emit literal and count bits + */ +static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); +} + +/* =========================================================================== + * Emit match and count bits + */ +static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); +} + +/* =========================================================================== + * Emit start of block + */ +static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + uint32_t header_bits = (type << 1) + last; + send_bits(s, header_bits, 3, bi_buf, bi_valid); + cmpr_bits_add(s, 3); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last)); +} + +/* =========================================================================== + * Align bit buffer on a byte boundary and count bits + */ +static inline void zng_tr_emit_align(deflate_state *s) { + bi_windup(s); /* align on byte boundary */ + sent_bits_align(s); +} + +/* =========================================================================== + * Emit an end block and align bit buffer if last block + */ +static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + zng_emit_end_block(s, ltree, last); + cmpr_bits_add(s, 7); + if (last) + zng_tr_emit_align(s); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/trees_tbl.h b/internal-complibs/zlib-ng-2.1.2/trees_tbl.h new file mode 100644 index 000000000..a3912b7fd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/trees_tbl.h @@ -0,0 +1,132 @@ +#ifndef TREES_TBL_H_ +#define TREES_TBL_H_ + +/* header created automatically with maketrees.c */ + +Z_INTERNAL const ct_data static_ltree[L_CODES+2] = { +{{ 12},{8}}, {{140},{8}}, {{ 76},{8}}, {{204},{8}}, {{ 44},{8}}, +{{172},{8}}, {{108},{8}}, {{236},{8}}, {{ 28},{8}}, {{156},{8}}, +{{ 92},{8}}, {{220},{8}}, {{ 60},{8}}, {{188},{8}}, {{124},{8}}, +{{252},{8}}, {{ 2},{8}}, {{130},{8}}, {{ 66},{8}}, {{194},{8}}, +{{ 34},{8}}, {{162},{8}}, {{ 98},{8}}, {{226},{8}}, {{ 18},{8}}, +{{146},{8}}, {{ 82},{8}}, {{210},{8}}, {{ 50},{8}}, {{178},{8}}, +{{114},{8}}, {{242},{8}}, {{ 10},{8}}, {{138},{8}}, {{ 74},{8}}, +{{202},{8}}, {{ 42},{8}}, {{170},{8}}, {{106},{8}}, {{234},{8}}, +{{ 26},{8}}, {{154},{8}}, {{ 90},{8}}, {{218},{8}}, {{ 58},{8}}, +{{186},{8}}, {{122},{8}}, {{250},{8}}, {{ 6},{8}}, {{134},{8}}, +{{ 70},{8}}, {{198},{8}}, {{ 38},{8}}, {{166},{8}}, {{102},{8}}, +{{230},{8}}, {{ 22},{8}}, {{150},{8}}, {{ 86},{8}}, {{214},{8}}, +{{ 54},{8}}, {{182},{8}}, {{118},{8}}, {{246},{8}}, {{ 14},{8}}, +{{142},{8}}, {{ 78},{8}}, {{206},{8}}, {{ 46},{8}}, {{174},{8}}, +{{110},{8}}, {{238},{8}}, {{ 30},{8}}, {{158},{8}}, {{ 94},{8}}, +{{222},{8}}, {{ 62},{8}}, {{190},{8}}, {{126},{8}}, {{254},{8}}, +{{ 1},{8}}, {{129},{8}}, {{ 65},{8}}, {{193},{8}}, {{ 33},{8}}, +{{161},{8}}, {{ 97},{8}}, {{225},{8}}, {{ 17},{8}}, {{145},{8}}, +{{ 81},{8}}, {{209},{8}}, {{ 49},{8}}, {{177},{8}}, {{113},{8}}, +{{241},{8}}, {{ 9},{8}}, {{137},{8}}, {{ 73},{8}}, {{201},{8}}, +{{ 41},{8}}, {{169},{8}}, {{105},{8}}, {{233},{8}}, {{ 25},{8}}, +{{153},{8}}, {{ 89},{8}}, {{217},{8}}, {{ 57},{8}}, {{185},{8}}, +{{121},{8}}, {{249},{8}}, {{ 5},{8}}, {{133},{8}}, {{ 69},{8}}, +{{197},{8}}, {{ 37},{8}}, {{165},{8}}, {{101},{8}}, {{229},{8}}, +{{ 21},{8}}, {{149},{8}}, {{ 85},{8}}, {{213},{8}}, {{ 53},{8}}, +{{181},{8}}, {{117},{8}}, {{245},{8}}, {{ 13},{8}}, {{141},{8}}, +{{ 77},{8}}, {{205},{8}}, {{ 45},{8}}, {{173},{8}}, {{109},{8}}, +{{237},{8}}, {{ 29},{8}}, {{157},{8}}, {{ 93},{8}}, {{221},{8}}, +{{ 61},{8}}, {{189},{8}}, {{125},{8}}, {{253},{8}}, {{ 19},{9}}, +{{275},{9}}, {{147},{9}}, {{403},{9}}, {{ 83},{9}}, {{339},{9}}, +{{211},{9}}, {{467},{9}}, {{ 51},{9}}, {{307},{9}}, {{179},{9}}, +{{435},{9}}, {{115},{9}}, {{371},{9}}, {{243},{9}}, {{499},{9}}, +{{ 11},{9}}, {{267},{9}}, {{139},{9}}, {{395},{9}}, {{ 75},{9}}, +{{331},{9}}, {{203},{9}}, {{459},{9}}, {{ 43},{9}}, {{299},{9}}, +{{171},{9}}, {{427},{9}}, {{107},{9}}, {{363},{9}}, {{235},{9}}, +{{491},{9}}, {{ 27},{9}}, {{283},{9}}, {{155},{9}}, {{411},{9}}, +{{ 91},{9}}, {{347},{9}}, {{219},{9}}, {{475},{9}}, {{ 59},{9}}, +{{315},{9}}, {{187},{9}}, {{443},{9}}, {{123},{9}}, {{379},{9}}, +{{251},{9}}, {{507},{9}}, {{ 7},{9}}, {{263},{9}}, {{135},{9}}, +{{391},{9}}, {{ 71},{9}}, {{327},{9}}, {{199},{9}}, {{455},{9}}, +{{ 39},{9}}, {{295},{9}}, {{167},{9}}, {{423},{9}}, {{103},{9}}, +{{359},{9}}, {{231},{9}}, {{487},{9}}, {{ 23},{9}}, {{279},{9}}, +{{151},{9}}, {{407},{9}}, {{ 87},{9}}, {{343},{9}}, {{215},{9}}, +{{471},{9}}, {{ 55},{9}}, {{311},{9}}, {{183},{9}}, {{439},{9}}, +{{119},{9}}, {{375},{9}}, {{247},{9}}, {{503},{9}}, {{ 15},{9}}, +{{271},{9}}, {{143},{9}}, {{399},{9}}, {{ 79},{9}}, {{335},{9}}, +{{207},{9}}, {{463},{9}}, {{ 47},{9}}, {{303},{9}}, {{175},{9}}, +{{431},{9}}, {{111},{9}}, {{367},{9}}, {{239},{9}}, {{495},{9}}, +{{ 31},{9}}, {{287},{9}}, {{159},{9}}, {{415},{9}}, {{ 95},{9}}, +{{351},{9}}, {{223},{9}}, {{479},{9}}, {{ 63},{9}}, {{319},{9}}, +{{191},{9}}, {{447},{9}}, {{127},{9}}, {{383},{9}}, {{255},{9}}, +{{511},{9}}, {{ 0},{7}}, {{ 64},{7}}, {{ 32},{7}}, {{ 96},{7}}, +{{ 16},{7}}, {{ 80},{7}}, {{ 48},{7}}, {{112},{7}}, {{ 8},{7}}, +{{ 72},{7}}, {{ 40},{7}}, {{104},{7}}, {{ 24},{7}}, {{ 88},{7}}, +{{ 56},{7}}, {{120},{7}}, {{ 4},{7}}, {{ 68},{7}}, {{ 36},{7}}, +{{100},{7}}, {{ 20},{7}}, {{ 84},{7}}, {{ 52},{7}}, {{116},{7}}, +{{ 3},{8}}, {{131},{8}}, {{ 67},{8}}, {{195},{8}}, {{ 35},{8}}, +{{163},{8}}, {{ 99},{8}}, {{227},{8}} +}; + +Z_INTERNAL const ct_data static_dtree[D_CODES] = { +{{ 0},{5}}, {{16},{5}}, {{ 8},{5}}, {{24},{5}}, {{ 4},{5}}, +{{20},{5}}, {{12},{5}}, {{28},{5}}, {{ 2},{5}}, {{18},{5}}, +{{10},{5}}, {{26},{5}}, {{ 6},{5}}, {{22},{5}}, {{14},{5}}, +{{30},{5}}, {{ 1},{5}}, {{17},{5}}, {{ 9},{5}}, {{25},{5}}, +{{ 5},{5}}, {{21},{5}}, {{13},{5}}, {{29},{5}}, {{ 3},{5}}, +{{19},{5}}, {{11},{5}}, {{27},{5}}, {{ 7},{5}}, {{23},{5}} +}; + +const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +Z_INTERNAL const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +Z_INTERNAL const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + +#endif /* TREES_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/uncompr.c b/internal-complibs/zlib-ng-2.1.2/uncompr.c new file mode 100644 index 000000000..311eca2b0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/uncompr.c @@ -0,0 +1,80 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int Z_EXPORT PREFIX(uncompress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t *sourceLen) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_uintmax_t len, left; + unsigned char buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(inflateInit)(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (unsigned long)max ? max : (unsigned int)len; + len -= stream.avail_in; + } + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = (z_size_t)stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + PREFIX(inflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int Z_EXPORT PREFIX(uncompress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(uncompress2)(dest, destLen, source, &sourceLen); +} diff --git a/internal-complibs/zlib-ng-2.1.2/win32/Makefile.a64 b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.a64 new file mode 100644 index 000000000..2a0f3cfe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.a64 @@ -0,0 +1,243 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.a64 (standard build) +# nmake -f win32/Makefile.a64 LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_NEON_HASLD4 \ + -DARM_FEATURES \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM64 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_quick.obj \ + deflate_medium.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +WFLAGS = $(WFLAGS) \ + -DARM_ACLE \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x55A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_neon.obj: $(SRCDIR)/arch/arm/slide_hash_neon.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.2/win32/Makefile.arm b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.arm new file mode 100644 index 000000000..7d3f1b58a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.arm @@ -0,0 +1,255 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.arm (standard build) +# nmake -f win32/Makefile.arm LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_FEATURES \ + -DARM_NEON_HASLD4 \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +WITH_ACLE = +WITH_NEON = +WITH_VFPV3 = +NEON_ARCH = /arch:VFPv4 +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +!if "$(WITH_ACLE)" != "" +WFLAGS = $(WFLAGS) -DARM_ACLE +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj +!endif +!if "$(WITH_VFPV3)" != "" +NEON_ARCH = /arch:VFPv3 +!endif +!if "$(WITH_NEON)" != "" +CFLAGS = $(CFLAGS) $(NEON_ARCH) +WFLAGS = $(WFLAGS) \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.2/win32/Makefile.msc b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.msc new file mode 100644 index 000000000..9ed26f283 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/Makefile.msc @@ -0,0 +1,266 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DX86_FEATURES \ + -DX86_PCLMULQDQ_CRC \ + -DX86_SSE2 \ + -DX86_SSE42 \ + -DX86_SSE42_CRC_INTRIN \ + -DX86_SSSE3 \ + -DX86_AVX2 + +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_avx2.obj \ + adler32_avx512.obj \ + adler32_avx512_vnni.obj \ + adler32_sse42.obj \ + adler32_ssse3.obj \ + adler32_fold.obj \ + chunkset.obj \ + chunkset_avx2.obj \ + chunkset_sse2.obj \ + chunkset_ssse3.obj \ + compare256.obj \ + compare256_avx2.obj \ + compare256_sse2.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + crc32_pclmulqdq.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + insert_string_sse42.obj \ + slide_hash.obj \ + slide_hash_avx2.obj \ + slide_hash_sse2.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + x86_features.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/x86}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_avx2.obj: $(SRCDIR)/arch/x86/adler32_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/fallback_builtins.h +adler32_avx512.obj: $(SRCDIR)/arch/x86/adler32_avx512.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_avx512_vnni.obj: $(SRCDIR)/arch/x86/adler32_avx512_vnni.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_sse42.obj: $(SRCDIR)/arch/x86/adler32_sse42.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_ssse3.obj: $(SRCDIR)/arch/x86/adler32_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_avx2.obj: $(SRCDIR)/arch/x86/chunkset_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_sse2.obj: $(SRCDIR)/arch/x86/chunkset_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_ssse3.obj: $(SRCDIR)/arch/x86/chunkset_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +crc32_pclmulqdq.obj: $(SRCDIR)/arch/x86/crc32_pclmulqdq.c $(SRCDIR)/arch/x86/crc32_pclmulqdq_tpl.h $(SRCDIR)/arch/x86/crc32_fold_pclmulqdq_tpl.h \ + $(SRCDIR)/crc32_fold.h $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_avx2.obj: $(SRCDIR)/arch/x86/slide_hash_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_sse2.obj: $(SRCDIR)/arch/x86/slide_hash_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.2/win32/replace.vbs b/internal-complibs/zlib-ng-2.1.2/win32/replace.vbs new file mode 100644 index 000000000..6779971d0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/replace.vbs @@ -0,0 +1,15 @@ +strInputFileName = Wscript.Arguments(0) +strOutputFileName = Wscript.Arguments(1) +strOldText = Wscript.Arguments(2) +strNewText = Wscript.Arguments(3) + +Set objFSO = CreateObject("Scripting.FileSystemObject") +Set objFile = objFSO.OpenTextFile(strInputFileName, 1) + +strText = objFile.ReadAll +objFile.Close +strNewText = Replace(strText, strOldText, strNewText) + +Set objFile = objFSO.OpenTextFile(strOutputFileName, 2, True) +objFile.Write strNewText +objFile.Close diff --git a/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng.def.in b/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng.def.in new file mode 100644 index 000000000..53b2bc21f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng.def.in @@ -0,0 +1,60 @@ +; zlib-ng data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibng_version + @ZLIB_SYMBOL_PREFIX@zng_deflate + @ZLIB_SYMBOL_PREFIX@zng_deflateEnd + @ZLIB_SYMBOL_PREFIX@zng_deflateInit + @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflate + @ZLIB_SYMBOL_PREFIX@zng_inflateEnd + @ZLIB_SYMBOL_PREFIX@zng_inflateInit + @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +; advanced functions + @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateCopy + @ZLIB_SYMBOL_PREFIX@zng_deflateReset + @ZLIB_SYMBOL_PREFIX@zng_deflateParams + @ZLIB_SYMBOL_PREFIX@zng_deflateTune + @ZLIB_SYMBOL_PREFIX@zng_deflateBound + @ZLIB_SYMBOL_PREFIX@zng_deflatePending + @ZLIB_SYMBOL_PREFIX@zng_deflatePrime + @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader + @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams + @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateSync + @ZLIB_SYMBOL_PREFIX@zng_inflateCopy + @ZLIB_SYMBOL_PREFIX@zng_inflateReset + @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 + @ZLIB_SYMBOL_PREFIX@zng_inflatePrime + @ZLIB_SYMBOL_PREFIX@zng_inflateMark + @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader + @ZLIB_SYMBOL_PREFIX@zng_inflateBack + @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@zng_compress + @ZLIB_SYMBOL_PREFIX@zng_compress2 + @ZLIB_SYMBOL_PREFIX@zng_compressBound + @ZLIB_SYMBOL_PREFIX@zng_uncompress + @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +; checksum functions + @ZLIB_SYMBOL_PREFIX@zng_adler32 + @ZLIB_SYMBOL_PREFIX@zng_adler32_z + @ZLIB_SYMBOL_PREFIX@zng_crc32 + @ZLIB_SYMBOL_PREFIX@zng_crc32_z + @ZLIB_SYMBOL_PREFIX@zng_adler32_combine + @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@zng_zError + @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@zng_get_crc_table + @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine + @ZLIB_SYMBOL_PREFIX@zng_inflateValidate + @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep + @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng1.rc b/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng1.rc new file mode 100644 index 000000000..327f17fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/zlib-ng1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib-ng.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + PRODUCTVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIBNG_VERSION "\0" + VALUE "InternalName", "zlib-ng1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib-ng1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIBNG_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.2/win32/zlib.def.in b/internal-complibs/zlib-ng-2.1.2/win32/zlib.def.in new file mode 100644 index 000000000..561a42f7f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/zlib.def.in @@ -0,0 +1,64 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 +; large file functions + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.2/win32/zlib1.rc b/internal-complibs/zlib-ng-2.1.2/win32/zlib1.rc new file mode 100644 index 000000000..73bc4389c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/zlib1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.2/win32/zlibcompat.def.in b/internal-complibs/zlib-ng-2.1.2/win32/zlibcompat.def.in new file mode 100644 index 000000000..52a713cf0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/win32/zlibcompat.def.in @@ -0,0 +1,97 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 + @ZLIB_SYMBOL_PREFIX@gzopen + @ZLIB_SYMBOL_PREFIX@gzdopen + @ZLIB_SYMBOL_PREFIX@gzbuffer + @ZLIB_SYMBOL_PREFIX@gzsetparams + @ZLIB_SYMBOL_PREFIX@gzread + @ZLIB_SYMBOL_PREFIX@gzfread + @ZLIB_SYMBOL_PREFIX@gzwrite + @ZLIB_SYMBOL_PREFIX@gzfwrite + @ZLIB_SYMBOL_PREFIX@gzprintf + @ZLIB_SYMBOL_PREFIX@gzvprintf + @ZLIB_SYMBOL_PREFIX@gzputs + @ZLIB_SYMBOL_PREFIX@gzgets + @ZLIB_SYMBOL_PREFIX@gzputc + @ZLIB_SYMBOL_PREFIX@gzgetc + @ZLIB_SYMBOL_PREFIX@gzungetc + @ZLIB_SYMBOL_PREFIX@gzflush + @ZLIB_SYMBOL_PREFIX@gzseek + @ZLIB_SYMBOL_PREFIX@gzrewind + @ZLIB_SYMBOL_PREFIX@gztell + @ZLIB_SYMBOL_PREFIX@gzoffset + @ZLIB_SYMBOL_PREFIX@gzeof + @ZLIB_SYMBOL_PREFIX@gzdirect + @ZLIB_SYMBOL_PREFIX@gzclose + @ZLIB_SYMBOL_PREFIX@gzclose_r + @ZLIB_SYMBOL_PREFIX@gzclose_w + @ZLIB_SYMBOL_PREFIX@gzerror + @ZLIB_SYMBOL_PREFIX@gzclearerr +; large file functions + @ZLIB_SYMBOL_PREFIX@gzopen64 + @ZLIB_SYMBOL_PREFIX@gzseek64 + @ZLIB_SYMBOL_PREFIX@gztell64 + @ZLIB_SYMBOL_PREFIX@gzoffset64 + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@gzgetc_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep + @ZLIB_SYMBOL_PREFIX@gzopen_w diff --git a/internal-complibs/zlib-ng-2.1.2/zbuild.h b/internal-complibs/zlib-ng-2.1.2/zbuild.h new file mode 100644 index 000000000..525a34d8d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zbuild.h @@ -0,0 +1,248 @@ +#ifndef _ZBUILD_H +#define _ZBUILD_H + +#define _POSIX_SOURCE 1 /* fileno */ +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200809L /* snprintf, posix_memalign, strdup */ +#endif +#ifndef _ISOC11_SOURCE +# define _ISOC11_SOURCE 1 /* aligned_alloc */ +#endif +#ifdef __OpenBSD__ +# define _BSD_SOURCE 1 +#endif + +#include +#include +#include +#include + +/* Determine compiler version of C Standard */ +#ifdef __STDC_VERSION__ +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +# if __STDC_VERSION__ >= 201112L +# ifndef STDC11 +# define STDC11 +# endif +# endif +#endif + +/* Determine compiler support for TLS */ +#ifndef Z_TLS +# ifdef HAVE_THREAD_LOCAL +# define Z_TLS _Thread_local +# elif defined(__GNUC__) || defined(__SUNPRO_C) +# define Z_TLS __thread +# elif defined(_WIN32) && (defined(_MSC_VER) || defined(__ICL)) +# define Z_TLS __declspec(thread) +# else +# warning Unable to detect Thread Local Storage support. +# define Z_TLS +# endif +#endif + +#ifndef Z_HAS_ATTRIBUTE +# if defined(__has_attribute) +# define Z_HAS_ATTRIBUTE(a) __has_attribute(a) +# else +# define Z_HAS_ATTRIBUTE(a) 0 +# endif +#endif + +#ifndef Z_FALLTHROUGH +# if Z_HAS_ATTRIBUTE(__fallthrough__) || (defined(__GNUC__) && (__GNUC__ >= 7)) +# define Z_FALLTHROUGH __attribute__((__fallthrough__)) +# else +# define Z_FALLTHROUGH do {} while(0) /* fallthrough */ +# endif +#endif + +/* This has to be first include that defines any types */ +#if defined(_MSC_VER) +# if defined(_WIN64) + typedef __int64 ssize_t; +# else + typedef long ssize_t; +# endif + +# if defined(_WIN64) + #define SSIZE_MAX _I64_MAX +# else + #define SSIZE_MAX LONG_MAX +# endif +#endif + +/* MS Visual Studio does not allow inline in C, only C++. + But it provides __inline instead, so use that. */ +#if defined(_MSC_VER) && !defined(inline) && !defined(__cplusplus) +# define inline __inline +#endif + +#if defined(ZLIB_COMPAT) +# define PREFIX(x) x +# define PREFIX2(x) ZLIB_ ## x +# define PREFIX3(x) z_ ## x +# define PREFIX4(x) x ## 64 +# define zVersion zlibVersion +#else +# define PREFIX(x) zng_ ## x +# define PREFIX2(x) ZLIBNG_ ## x +# define PREFIX3(x) zng_ ## x +# define PREFIX4(x) zng_ ## x +# define zVersion zlibng_version +# define z_size_t size_t +#endif + +/* In zlib-compat some functions and types use unsigned long, but zlib-ng use size_t */ +#if defined(ZLIB_COMPAT) +# define z_uintmax_t unsigned long +#else +# define z_uintmax_t size_t +#endif + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) +/* Maximum of a and b. */ +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +/* Ignore unused variable warning */ +#define Z_UNUSED(var) (void)(var) + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#ifndef __cplusplus +# define Z_REGISTER register +#else +# define Z_REGISTER +#endif + +/* Reverse the bytes in a value. Use compiler intrinsics when + possible to take advantage of hardware implementations. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +# include +# pragma intrinsic(_byteswap_ulong) +# define ZSWAP16(q) _byteswap_ushort(q) +# define ZSWAP32(q) _byteswap_ulong(q) +# define ZSWAP64(q) _byteswap_uint64(q) + +#elif defined(__clang__) || (defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +# define ZSWAP16(q) __builtin_bswap16(q) +# define ZSWAP32(q) __builtin_bswap32(q) +# define ZSWAP64(q) __builtin_bswap64(q) + +#elif defined(__GNUC__) && (__GNUC__ >= 2) && defined(__linux__) +# include +# define ZSWAP16(q) bswap_16(q) +# define ZSWAP32(q) bswap_32(q) +# define ZSWAP64(q) bswap_64(q) + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +# include +# define ZSWAP16(q) bswap16(q) +# define ZSWAP32(q) bswap32(q) +# define ZSWAP64(q) bswap64(q) +#elif defined(__OpenBSD__) +# include +# define ZSWAP16(q) swap16(q) +# define ZSWAP32(q) swap32(q) +# define ZSWAP64(q) swap64(q) +#elif defined(__INTEL_COMPILER) +/* ICC does not provide a two byte swap. */ +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) _bswap(q) +# define ZSWAP64(q) _bswap64(q) + +#else +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) +# define ZSWAP64(q) \ + (((q & 0xFF00000000000000u) >> 56u) | \ + ((q & 0x00FF000000000000u) >> 40u) | \ + ((q & 0x0000FF0000000000u) >> 24u) | \ + ((q & 0x000000FF00000000u) >> 8u) | \ + ((q & 0x00000000FF000000u) << 8u) | \ + ((q & 0x0000000000FF0000u) << 24u) | \ + ((q & 0x000000000000FF00u) << 40u) | \ + ((q & 0x00000000000000FFu) << 56u)) +#endif + +/* Only enable likely/unlikely if the compiler is known to support it */ +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__INTEL_COMPILER) || defined(__clang__) +# define LIKELY_NULL(x) __builtin_expect((x) != 0, 0) +# define LIKELY(x) __builtin_expect(!!(x), 1) +# define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +# define LIKELY_NULL(x) x +# define LIKELY(x) x +# define UNLIKELY(x) x +#endif /* (un)likely */ + +#if defined(HAVE_ATTRIBUTE_ALIGNED) +# define ALIGNED_(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +# define ALIGNED_(x) __declspec(align(x)) +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int Z_INTERNAL z_verbose; + extern void Z_INTERNAL z_error(const char *m); +# define Assert(cond, msg) {if (!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose >= 0) fprintf x;} +# define Tracev(x) {if (z_verbose > 0) fprintf x;} +# define Tracevv(x) {if (z_verbose > 1) fprintf x;} +# define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x;} +# define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x;} +#else +# define Assert(cond, msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c, x) +# define Tracecv(c, x) +#endif + +#ifndef NO_UNALIGNED +# if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) || defined(_M_AMD64) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(_X86_) || defined(_M_IX86) +# define UNALIGNED_OK +# elif defined(__aarch64__) || defined(_M_ARM64) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# elif defined(__arm__) || (_M_ARM >= 7) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# endif +# elif defined(__powerpc64__) || defined(__ppc64__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# endif +#endif + +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# define Z_MEMORY_SANITIZER 1 +# include +# endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/zconf-ng.h.in b/internal-complibs/zlib-ng-2.1.2/zconf-ng.h.in new file mode 100644 index 000000000..226f06a03 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zconf-ng.h.in @@ -0,0 +1,176 @@ +/* zconf-ng.h -- configuration of the zlib-ng compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONFNG_H +#define ZCONFNG_H + +#include "zlib_name_mangling-ng.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +/* Always define z_const as const */ +#define z_const const + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_EXPORT + +/* Fallback for something that includes us. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && defined(WITH_GZFILEOP) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +#endif /* ZCONFNG_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/zconf.h.in b/internal-complibs/zlib-ng-2.1.2/zconf.h.in new file mode 100644 index 000000000..074f02551 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zconf.h.in @@ -0,0 +1,203 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONF_H +#define ZCONF_H + +#include "zlib_name_mangling.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + + +#ifndef OF /* function prototypes */ +# define OF(args) args +#endif + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_INTERNAL + +/* For backwards compatibility */ + +#ifndef ZEXTERN +# define ZEXTERN Z_EXTERN +#endif +#ifndef ZEXPORT +# define ZEXPORT Z_EXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA Z_EXPORTVA +#endif + +/* Legacy zlib typedefs for backwards compatibility. Don't assume stdint.h is defined. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +typedef unsigned int z_crc_t; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +typedef size_t z_size_t; + +#endif /* ZCONF_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/zendian.h b/internal-complibs/zlib-ng-2.1.2/zendian.h new file mode 100644 index 000000000..3fdb13041 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zendian.h @@ -0,0 +1,60 @@ +/* zendian.h -- define BYTE_ORDER for endian tests + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ENDIAN_H_ +#define ENDIAN_H_ + +/* First check whether the compiler knows the target __BYTE_ORDER__. */ +#if defined(__BYTE_ORDER__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER BIG_ENDIAN +# endif +# endif +#elif defined(__MINGW32__) +# include +#elif defined(_WIN32) +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) || defined (_M_ARM64) +# define BYTE_ORDER LITTLE_ENDIAN +# else +# error Unknown endianness! +# endif +#elif defined(__linux__) +# include +#elif defined(__APPLE__) +# include +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) +# include +#elif defined(__sun) || defined(sun) +# include +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN 4321 +# endif +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN 1234 +# endif +# if !defined(BYTE_ORDER) +# if defined(_BIG_ENDIAN) +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# endif +#else +# include +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/zlib-ng.h.in b/internal-complibs/zlib-ng-2.1.2/zlib-ng.h.in new file mode 100644 index 000000000..2abd32022 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib-ng.h.in @@ -0,0 +1,1867 @@ +#ifndef ZNGLIB_H_ +#define ZNGLIB_H_ +/* zlib-ng.h -- interface of the 'zlib-ng' compression library, forked from zlib. + + Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf-ng.h" + +#ifndef ZCONFNG_H +# error Missing zconf-ng.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.2" +#define ZLIBNG_VERNUM 0x020102F0L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 2 +#define ZLIBNG_VER_STATUS F /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct zng_stream_s { + const uint8_t *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + size_t total_in; /* total number of input bytes read so far */ + + uint8_t *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + size_t total_out; /* total number of bytes output so far */ + + const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uint32_t adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} zng_stream; + +typedef zng_stream *zng_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct zng_gz_header_s { + int32_t text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int32_t xflags; /* extra flags (not used when writing a gzip file) */ + int32_t os; /* operating system */ + uint8_t *extra; /* pointer to extra field or NULL if none */ + uint32_t extra_len; /* extra field length (valid if extra != NULL) */ + uint32_t extra_max; /* space at extra (only when reading header) */ + uint8_t *name; /* pointer to zero-terminated file name or NULL */ + uint32_t name_max; /* space at name (only when reading header) */ + uint8_t *comment; /* pointer to zero-terminated comment or NULL */ + uint32_t comm_max; /* space at comment (only when reading header) */ + int32_t hcrc; /* true if there was or will be a header crc */ + int32_t done; /* true when done reading gzip header (not used when writing a gzip file) */ +} zng_gz_header; + +typedef zng_gz_header *zng_gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + + + /* basic functions */ + +Z_EXTERN Z_EXPORT +const char *zlibng_version(void); +/* The application can compare zlibng_version and ZLIBNG_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib-ng.h header file used by the application. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit(zng_stream *strm, int32_t level); +/* + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level. + msg is set to null if there is no error message. deflateInit does not perform + any compression: this will be done by deflate(). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflate(zng_stream *strm, int32_t flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit(zng_stream *strm); +/* + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit does not perform any decompression. Actual decompression will + be done by inflate(). So next_in, and avail_in, next_out, and avail_out + are unused and unchanged. The current implementation of inflateInit() + does not process any header information -- that is deferred until inflate() + is called. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflate(zng_stream *strm, int32_t flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit2(zng_stream *strm, int32_t level, int32_t method, int32_t windowBits, int32_t memLevel, int32_t strategy); +/* + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method). + msg is set to null if there is no error message. deflateInit2 does not perform + any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateReset(zng_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateParams(zng_stream *strm, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateTune(zng_stream *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN Z_EXPORT +unsigned long zng_deflateBound(zng_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePending(zng_stream *strm, uint32_t *pending, int32_t *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetHeader(zng_stream *strm, zng_gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided zng_gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit2(zng_stream *strm, int32_t windowBits); +/* + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit2 does not perform any decompression apart from possibly reading + the zlib header if present: actual decompression will be done by inflate(). + (So next_in and avail_in may be modified, but next_out and avail_out are + unused and unchanged.) The current implementation of inflateInit2() does not + process any header information -- that is deferred until inflate() is called. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSync(zng_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset(zng_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset2(zng_stream *strm, int32_t windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +long zng_inflateMark(zng_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetHeader(zng_stream *strm, zng_gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided zng_gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackInit(zng_stream *strm, int32_t windowBits, uint8_t *window); +/* + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated. +*/ + +typedef uint32_t (*in_func) (void *, const uint8_t * *); +typedef int32_t (*out_func) (void *, uint8_t *, uint32_t); + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBack(zng_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackEnd(zng_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +unsigned long zng_zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen, int32_t level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_compressBound(size_t sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + +#ifdef WITH_GZFILEOP + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +Z_EXTERN Z_EXPORT +gzFile zng_gzopen(const char *path, const char *mode); +/* + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN Z_EXPORT +gzFile zng_gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzbuffer(gzFile file, uint32_t size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzsetparams(gzFile file, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzread(gzFile file, void *buf, uint32_t len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfread(void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzwrite(gzFile file, void const *buf, uint32_t len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORTVA +int32_t zng_gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +char * zng_gzgets(gzFile file, char *buf, int32_t len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputc(gzFile file, int32_t c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzungetc(int32_t c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzflush(gzFile file, int32_t flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzseek(gzFile file, z_off64_t offset, int whence); +/* + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gztell(gzFile file); +/* + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzoffset(gzFile file); +/* + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_r(gzFile file); +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN Z_EXPORT +const char * zng_gzerror(gzFile file, int32_t *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN Z_EXPORT +void zng_gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* WITH_GZFILEOP */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32(uint32_t adler, const uint8_t *buf, uint32_t len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_z(uint32_t adler, const uint8_t *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_combine(uint32_t adler1, uint32_t adler2, z_off64_t len2); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32(uint32_t crc, const uint8_t *buf, uint32_t len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_z(uint32_t crc, const uint8_t *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine(uint32_t crc1, uint32_t crc2, z_off64_t len2); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_gen(z_off64_t len2); + +/* + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_op(uint32_t crc1, uint32_t crc2, const uint32_t op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + /* various hacks, don't look :) */ + +#ifdef WITH_GZFILEOP + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +# define @ZLIB_SYMBOL_PREFIX@zng_gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@zng_gzgetc)(g)) + +#endif /* WITH_GZFILEOP */ + + +typedef enum { + Z_DEFLATE_LEVEL = 0, /* compression level, represented as an int */ + Z_DEFLATE_STRATEGY = 1, /* compression strategy, represented as an int */ + Z_DEFLATE_REPRODUCIBLE = 2, + /* + Whether reproducible compression results are required. Represented as an int, where 0 means that it is allowed + to trade reproducibility for e.g. improved performance or compression ratio, and non-0 means that + reproducibility is strictly required. Reproducibility is guaranteed only when using an identical zlib-ng build. + Default is 0. + */ +} zng_deflate_param; + +typedef struct { + zng_deflate_param param; /* parameter ID */ + void *buf; /* parameter value */ + size_t size; /* parameter value size */ + int32_t status; /* result of the last set/get call */ +} zng_deflate_param_value; + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Sets the values of the given zlib-ng deflate stream parameters. All the buffers are copied internally, so the + caller still owns them after this function returns. Returns Z_OK if success. + + If the size of at least one of the buffers is too small to hold the entire value of the corresponding parameter, + or if the same parameter is specified multiple times, Z_BUF_ERROR is returned. The caller may inspect status fields + in order to determine which of the parameters caused this error. No other changes are performed. + + If the stream state is inconsistent or if at least one of the values cannot be updated, Z_STREAM_ERROR is + returned. The caller may inspect status fields in order to determine which of the parameters caused this error. + Parameters, whose status field is equal to Z_OK, have been applied successfully. If all status fields are not equal + to Z_STREAM_ERROR, then the error was caused by a stream state inconsistency. + + If there are no other errors, but at least one parameter is not supported by the current zlib-ng version, + Z_VERSION_ERROR is returned. The caller may inspect status fields in order to determine which of the parameters + caused this error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Copies the values of the given zlib-ng deflate stream parameters into the user-provided buffers. Returns Z_OK if + success, Z_VERSION_ERROR if at least one parameter is not supported by the current zlib-ng version, Z_STREAM_ERROR + if the stream state is inconsistent, and Z_BUF_ERROR if the size of at least one buffer is too small to hold the + entire value of the corresponding parameter. +*/ + +/* undocumented functions */ +Z_EXTERN Z_EXPORT const char * zng_zError (int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateSyncPoint (zng_stream *); +Z_EXTERN Z_EXPORT const uint32_t * zng_get_crc_table (void); +Z_EXTERN Z_EXPORT int32_t zng_inflateUndermine (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateValidate (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT unsigned long zng_inflateCodesUsed (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_inflateResetKeep (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_deflateResetKeep (zng_stream *); + +#ifdef WITH_GZFILEOP +# if defined(_WIN32) + Z_EXTERN Z_EXPORT gzFile zng_gzopen_w(const wchar_t *path, const char *mode); +# endif +Z_EXTERN Z_EXPORTVA int32_t zng_gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZNGLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/zlib-ng.map b/internal-complibs/zlib-ng-2.1.2/zlib-ng.map new file mode 100644 index 000000000..64411ab10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib-ng.map @@ -0,0 +1,111 @@ +ZLIB_NG_2.1.0 { + global: + zng_deflateInit; + zng_deflateInit2; + zng_inflateBackInit; + zng_inflateInit; + zng_inflateInit2; + zlibng_version; +}; + +ZLIB_NG_2.0.0 { + global: + zng_adler32; + zng_adler32_combine; + zng_adler32_z; + zng_compress; + zng_compress2; + zng_compressBound; + zng_crc32; + zng_crc32_combine; + zng_crc32_combine_gen; + zng_crc32_combine_op; + zng_crc32_z; + zng_deflate; + zng_deflateBound; + zng_deflateCopy; + zng_deflateEnd; + zng_deflateGetDictionary; + zng_deflateGetParams; + zng_deflateInit_; + zng_deflateInit2_; + zng_deflateParams; + zng_deflatePending; + zng_deflatePrime; + zng_deflateReset; + zng_deflateResetKeep; + zng_deflateSetDictionary; + zng_deflateSetHeader; + zng_deflateSetParams; + zng_deflateTune; + zng_get_crc_table; + zng_inflate; + zng_inflateBack; + zng_inflateBackEnd; + zng_inflateBackInit_; + zng_inflateCodesUsed; + zng_inflateCopy; + zng_inflateEnd; + zng_inflateGetDictionary; + zng_inflateGetHeader; + zng_inflateInit_; + zng_inflateInit2_; + zng_inflateMark; + zng_inflatePrime; + zng_inflateReset; + zng_inflateReset2; + zng_inflateResetKeep; + zng_inflateSetDictionary; + zng_inflateSync; + zng_inflateSyncPoint; + zng_inflateUndermine; + zng_inflateValidate; + zng_uncompress; + zng_uncompress2; + zng_zError; + zng_zlibCompileFlags; + zng_vstring; + local: + zng_deflate_copyright; + zng_inflate_copyright; + zng_zcalloc; + zng_zcfree; + zng_z_errmsg; + gz_error; + _*; +}; + +ZLIB_NG_GZ_2.0.0 { + global: + zng_gzbuffer; + zng_gzclearerr; + zng_gzclose; + zng_gzclose_r; + zng_gzclose_w; + zng_gzdirect; + zng_gzdopen; + zng_gzeof; + zng_gzerror; + zng_gzflush; + zng_gzfread; + zng_gzfwrite; + zng_gzgetc; + zng_gzgets; + zng_gzoffset; + zng_gzopen; + zng_gzprintf; + zng_gzputc; + zng_gzputs; + zng_gzread; + zng_gzrewind; + zng_gzseek; + zng_gzsetparams; + zng_gztell; + zng_gzungetc; + zng_gzvprintf; + zng_gzwrite; +}; + +FAIL { + local: *; +}; diff --git a/internal-complibs/zlib-ng-2.1.2/zlib.h.in b/internal-complibs/zlib-ng-2.1.2/zlib.h.in new file mode 100644 index 000000000..6788bf778 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib.h.in @@ -0,0 +1,1855 @@ +#ifndef ZLIB_H_ +#define ZLIB_H_ +/* zlib.h -- interface of the 'zlib-ng' compression library + Forked from and compatible with zlib 1.2.13 + + Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZNGLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf.h" + +#ifndef ZCONF_H +# error Missing zconf.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.2" +#define ZLIBNG_VERNUM 0x020102F0L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 2 +#define ZLIBNG_VER_STATUS F /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +#define ZLIB_VERSION "1.2.13.zlib-ng" +#define ZLIB_VERNUM 0x12df +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_SUBREVISION 15 /* 15=fork (0xf) */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct z_stream_s { + z_const unsigned char *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + unsigned long total_in; /* total number of input bytes read so far */ + + unsigned char *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + unsigned long total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + unsigned long adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream *z_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + unsigned char *extra; /* pointer to extra field or NULL if none */ + unsigned int extra_len; /* extra field length (valid if extra != NULL) */ + unsigned int extra_max; /* space at extra (only when reading header) */ + unsigned char *name; /* pointer to zero-terminated file name or NULL */ + unsigned int name_max; /* space at name (only when reading header) */ + unsigned char *comment; /* pointer to zero-terminated comment or NULL */ + unsigned int comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used when writing a gzip file) */ +} gz_header; + +typedef gz_header *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +Z_EXTERN const char * Z_EXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +Z_EXTERN int Z_EXPORT deflateInit (z_stream *strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +Z_EXTERN int Z_EXPORT deflate(z_stream *strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN int Z_EXPORT deflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +Z_EXTERN int Z_EXPORT inflateInit (z_stream *strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +Z_EXTERN int Z_EXPORT inflate(z_stream *strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN int Z_EXPORT inflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +Z_EXTERN int Z_EXPORT deflateInit2 (z_stream *strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateSetDictionary(z_stream *strm, + const unsigned char *dictionary, + unsigned int dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateGetDictionary (z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT deflateReset(z_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT deflateParams(z_stream *strm, int level, int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN int Z_EXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN unsigned long Z_EXPORT deflateBound(z_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN int Z_EXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN int Z_EXPORT deflatePrime(z_stream *strm, int bits, int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateSetHeader(z_stream *strm, gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateInit2(z_stream *strm, int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +Z_EXTERN int Z_EXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN int Z_EXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateSync(z_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN int Z_EXPORT inflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT inflateReset(z_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT inflateReset2(z_stream *strm, int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN int Z_EXPORT inflatePrime(z_stream *strm, int bits, int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN long Z_EXPORT inflateMark(z_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateGetHeader(z_stream *strm, gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateBackInit (z_stream *strm, int windowBits, unsigned char *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef uint32_t (*in_func) (void *, z_const unsigned char * *); +typedef int (*out_func) (void *, unsigned char *, uint32_t); + +Z_EXTERN int Z_EXPORT inflateBack(z_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN int Z_EXPORT inflateBackEnd(z_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN unsigned long Z_EXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN int Z_EXPORT compress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN int Z_EXPORT compress2(unsigned char *dest, unsigned long *destLen, const unsigned char *source, + unsigned long sourceLen, int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN unsigned long Z_EXPORT compressBound(unsigned long sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN int Z_EXPORT uncompress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN int Z_EXPORT uncompress2 (unsigned char *dest, unsigned long *destLen, + const unsigned char *source, unsigned long *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +Z_EXTERN gzFile Z_EXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN gzFile Z_EXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN int Z_EXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN int Z_EXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN int Z_EXPORT gzread(gzFile file, void *buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN size_t Z_EXPORT gzfread (void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN int Z_EXPORT gzwrite(gzFile file, void const *buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN size_t Z_EXPORT gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN int Z_EXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN int Z_EXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN char * Z_EXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN int Z_EXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN int Z_EXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN int Z_EXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN int Z_EXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzseek (gzFile file, z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN int Z_EXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN int Z_EXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN int Z_EXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN int Z_EXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN int Z_EXPORT gzclose_r(gzFile file); +Z_EXTERN int Z_EXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN const char * Z_EXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN void Z_EXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32(unsigned long adler, const unsigned char *buf, unsigned int len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32_z(unsigned long adler, const unsigned char *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT adler32_combine(unsigned long adler1, unsigned long adler2, z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_z(unsigned long crc, const unsigned char *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine(unsigned long crc1, unsigned long crc2, z_off64_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_combine_op(unsigned long crc1, unsigned long crc2, + const unsigned long op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +Z_EXTERN int Z_EXPORT deflateInit_(z_stream *strm, int level, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit_(z_stream *strm, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, int memLevel, + int strategy, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateBackInit_(z_stream *strm, int windowBits, unsigned char *window, + const char *version, int stream_size); +#define @ZLIB_SYMBOL_PREFIX@deflateInit(strm, level) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit(strm) inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit2(strm, windowBits) inflateInit2_((strm), (windowBits), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), ZLIB_VERSION, (int)sizeof(z_stream)) + + +#ifndef Z_SOLO +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +Z_EXTERN int Z_EXPORT gzgetc_(gzFile file); /* backward compatibility */ +# define @ZLIB_SYMBOL_PREFIX@gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@gzgetc)(g)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT gzopen64(const char *, const char *); + Z_EXTERN z_off64_t Z_EXPORT gzseek64(gzFile, z_off64_t, int); + Z_EXTERN z_off64_t Z_EXPORT gztell64(gzFile); + Z_EXTERN z_off64_t Z_EXPORT gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT adler32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen64(z_off64_t); +#endif +#endif + +#if !defined(Z_SOLO) && !defined(Z_INTERNAL) && defined(Z_WANT64) +# define @ZLIB_SYMBOL_PREFIX@gzopen @ZLIB_SYMBOL_PREFIX@gzopen64 +# define @ZLIB_SYMBOL_PREFIX@gzseek @ZLIB_SYMBOL_PREFIX@gzseek64 +# define @ZLIB_SYMBOL_PREFIX@gztell @ZLIB_SYMBOL_PREFIX@gztell64 +# define @ZLIB_SYMBOL_PREFIX@gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define @ZLIB_SYMBOL_PREFIX@adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +# ifndef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen64(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek64(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell64(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64(z_off64_t); +# endif +#else +# ifndef Z_SOLO + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset(gzFile); +# endif + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen(z_off_t); +#endif + +/* undocumented functions */ +Z_EXTERN const char * Z_EXPORT zError (int); +Z_EXTERN int Z_EXPORT inflateSyncPoint (z_stream *); +Z_EXTERN const uint32_t * Z_EXPORT get_crc_table (void); +Z_EXTERN int Z_EXPORT inflateUndermine (z_stream *, int); +Z_EXTERN int Z_EXPORT inflateValidate (z_stream *, int); +Z_EXTERN unsigned long Z_EXPORT inflateCodesUsed (z_stream *); +Z_EXTERN int Z_EXPORT inflateResetKeep (z_stream *); +Z_EXTERN int Z_EXPORT deflateResetKeep (z_stream *); + +#ifndef Z_SOLO +#if defined(_WIN32) + Z_EXTERN gzFile Z_EXPORT gzopen_w(const wchar_t *path, const char *mode); +#endif +Z_EXTERN int Z_EXPORTVA gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/zlib.map b/internal-complibs/zlib-ng-2.1.2/zlib.map new file mode 100644 index 000000000..ebca10d35 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib.map @@ -0,0 +1,97 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + zcalloc; + zcfree; + z_errmsg; + gz_error; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; + +ZLIB_1.2.9 { + inflateCodesUsed; + inflateValidate; + uncompress2; + gzfread; + gzfwrite; + deflateGetDictionary; + adler32_z; + crc32_z; +} ZLIB_1.2.7.1; + +ZLIB_1.2.12 { + crc32_combine_gen; + crc32_combine_gen64; + crc32_combine_op; +} ZLIB_1.2.9; diff --git a/internal-complibs/zlib-ng-2.1.2/zlib.pc.cmakein b/internal-complibs/zlib-ng-2.1.2/zlib.pc.cmakein new file mode 100644 index 000000000..3d440ce6b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib.pc.cmakein @@ -0,0 +1,14 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +symbol_prefix=@ZLIB_SYMBOL_PREFIX@ +libdir=@PC_LIB_INSTALL_DIR@ +sharedlibdir=${libdir} +includedir=@PC_INC_INSTALL_DIR@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @ZLIB_FULL_VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.2/zlib.pc.in b/internal-complibs/zlib-ng-2.1.2/zlib.pc.in new file mode 100644 index 000000000..a0678fbe0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +symbol_prefix=@symbol_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling-ng.h.in b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling-ng.h.in new file mode 100644 index 000000000..e90904a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling-ng.h.in @@ -0,0 +1,178 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define zng__dist_code @ZLIB_SYMBOL_PREFIX@zng__dist_code +#define zng__length_code @ZLIB_SYMBOL_PREFIX@zng__length_code +#define zng__tr_align @ZLIB_SYMBOL_PREFIX@zng__tr_align +#define zng__tr_flush_bits @ZLIB_SYMBOL_PREFIX@zng__tr_flush_bits +#define zng__tr_flush_block @ZLIB_SYMBOL_PREFIX@zng__tr_flush_block +#define zng__tr_init @ZLIB_SYMBOL_PREFIX@zng__tr_init +#define zng__tr_stored_block @ZLIB_SYMBOL_PREFIX@zng__tr_stored_block +#define zng__tr_tally @ZLIB_SYMBOL_PREFIX@zng__tr_tally +#define zng_adler32 @ZLIB_SYMBOL_PREFIX@zng_adler32 +#define zng_adler32_combine @ZLIB_SYMBOL_PREFIX@zng_adler32_combine +#define zng_adler32_combine64 @ZLIB_SYMBOL_PREFIX@zng_adler32_combine64 +#define zng_adler32_z @ZLIB_SYMBOL_PREFIX@zng_adler32_z +#define zng_compress @ZLIB_SYMBOL_PREFIX@zng_compress +#define zng_compress2 @ZLIB_SYMBOL_PREFIX@zng_compress2 +#define zng_compressBound @ZLIB_SYMBOL_PREFIX@zng_compressBound +#define zng_crc32 @ZLIB_SYMBOL_PREFIX@zng_crc32 +#define zng_crc32_combine @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +#define zng_crc32_combine64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine64 +#define zng_crc32_combine_gen @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen +#define zng_crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen64 +#define zng_crc32_combine_op @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_op +#define zng_crc32_z @ZLIB_SYMBOL_PREFIX@zng_crc32_z +#define zng_deflate @ZLIB_SYMBOL_PREFIX@zng_deflate +#define zng_deflateBound @ZLIB_SYMBOL_PREFIX@zng_deflateBound +#define zng_deflateCopy @ZLIB_SYMBOL_PREFIX@zng_deflateCopy +#define zng_deflateEnd @ZLIB_SYMBOL_PREFIX@zng_deflateEnd +#define zng_deflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary +#define zng_deflateInit @ZLIB_SYMBOL_PREFIX@zng_deflateInit +#define zng_deflateInit2 @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 +#define zng_deflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit2_ +#define zng_deflateInit_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit_ +#define zng_deflateParams @ZLIB_SYMBOL_PREFIX@zng_deflateParams +#define zng_deflatePending @ZLIB_SYMBOL_PREFIX@zng_deflatePending +#define zng_deflatePrime @ZLIB_SYMBOL_PREFIX@zng_deflatePrime +#define zng_deflateReset @ZLIB_SYMBOL_PREFIX@zng_deflateReset +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep +#define zng_deflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary +#define zng_deflateSetHeader @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader +#define zng_deflateTune @ZLIB_SYMBOL_PREFIX@zng_deflateTune +#define zng_deflate_copyright @ZLIB_SYMBOL_PREFIX@zng_deflate_copyright +#define zng_fill_window @ZLIB_SYMBOL_PREFIX@zng_fill_window +#define zng_fixedtables @ZLIB_SYMBOL_PREFIX@zng_fixedtables +#define zng_flush_pending @ZLIB_SYMBOL_PREFIX@zng_flush_pending +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#ifdef WITH_GZFILEOP +# define zng_gz_error @ZLIB_SYMBOL_PREFIX@zng_gz_error +# define zng_gz_strwinerror @ZLIB_SYMBOL_PREFIX@zng_gz_strwinerror +# define zng_gzbuffer @ZLIB_SYMBOL_PREFIX@zng_gzbuffer +# define zng_gzclearerr @ZLIB_SYMBOL_PREFIX@zng_gzclearerr +# define zng_gzclose @ZLIB_SYMBOL_PREFIX@zng_gzclose +# define zng_gzclose_r @ZLIB_SYMBOL_PREFIX@zng_gzclose_r +# define zng_gzclose_w @ZLIB_SYMBOL_PREFIX@zng_gzclose_w +# define zng_gzdirect @ZLIB_SYMBOL_PREFIX@zng_gzdirect +# define zng_gzdopen @ZLIB_SYMBOL_PREFIX@zng_gzdopen +# define zng_gzeof @ZLIB_SYMBOL_PREFIX@zng_gzeof +# define zng_gzerror @ZLIB_SYMBOL_PREFIX@zng_gzerror +# define zng_gzflush @ZLIB_SYMBOL_PREFIX@zng_gzflush +# define zng_gzfread @ZLIB_SYMBOL_PREFIX@zng_gzfread +# define zng_gzfwrite @ZLIB_SYMBOL_PREFIX@zng_gzfwrite +# define zng_gzgetc @ZLIB_SYMBOL_PREFIX@zng_gzgetc +# define zng_gzgetc_ @ZLIB_SYMBOL_PREFIX@zng_gzgetc_ +# define zng_gzgets @ZLIB_SYMBOL_PREFIX@zng_gzgets +# define zng_gzoffset @ZLIB_SYMBOL_PREFIX@zng_gzoffset +# define zng_gzoffset64 @ZLIB_SYMBOL_PREFIX@zng_gzoffset64 +# define zng_gzopen @ZLIB_SYMBOL_PREFIX@zng_gzopen +# define zng_gzopen64 @ZLIB_SYMBOL_PREFIX@zng_gzopen64 +# ifdef _WIN32 +# define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +# endif +# define zng_gzprintf @ZLIB_SYMBOL_PREFIX@zng_gzprintf +# define zng_gzputc @ZLIB_SYMBOL_PREFIX@zng_gzputc +# define zng_gzputs @ZLIB_SYMBOL_PREFIX@zng_gzputs +# define zng_gzread @ZLIB_SYMBOL_PREFIX@zng_gzread +# define zng_gzrewind @ZLIB_SYMBOL_PREFIX@zng_gzrewind +# define zng_gzseek @ZLIB_SYMBOL_PREFIX@zng_gzseek +# define zng_gzseek64 @ZLIB_SYMBOL_PREFIX@zng_gzseek64 +# define zng_gzsetparams @ZLIB_SYMBOL_PREFIX@zng_gzsetparams +# define zng_gztell @ZLIB_SYMBOL_PREFIX@zng_gztell +# define zng_gztell64 @ZLIB_SYMBOL_PREFIX@zng_gztell64 +# define zng_gzungetc @ZLIB_SYMBOL_PREFIX@zng_gzungetc +# define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf +# define zng_gzwrite @ZLIB_SYMBOL_PREFIX@zng_gzwrite +#endif +#define zng_inflate @ZLIB_SYMBOL_PREFIX@zng_inflate +#define zng_inflateBack @ZLIB_SYMBOL_PREFIX@zng_inflateBack +#define zng_inflateBackEnd @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd +#define zng_inflateBackInit @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +#define zng_inflateBackInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit_ +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateCopy @ZLIB_SYMBOL_PREFIX@zng_inflateCopy +#define zng_inflateEnd @ZLIB_SYMBOL_PREFIX@zng_inflateEnd +#define zng_inflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary +#define zng_inflateGetHeader @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader +#define zng_inflateInit @ZLIB_SYMBOL_PREFIX@zng_inflateInit +#define zng_inflateInit2 @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 +#define zng_inflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit2_ +#define zng_inflateInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit_ +#define zng_inflateMark @ZLIB_SYMBOL_PREFIX@zng_inflateMark +#define zng_inflatePrime @ZLIB_SYMBOL_PREFIX@zng_inflatePrime +#define zng_inflateReset @ZLIB_SYMBOL_PREFIX@zng_inflateReset +#define zng_inflateReset2 @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_inflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary +#define zng_inflateSync @ZLIB_SYMBOL_PREFIX@zng_inflateSync +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflate_copyright @ZLIB_SYMBOL_PREFIX@zng_inflate_copyright +#define zng_inflate_ensure_window @ZLIB_SYMBOL_PREFIX@zng_inflate_ensure_window +#define zng_inflate_fast @ZLIB_SYMBOL_PREFIX@zng_inflate_fast +#define zng_inflate_table @ZLIB_SYMBOL_PREFIX@zng_inflate_table +#define zng_read_buf @ZLIB_SYMBOL_PREFIX@zng_read_buf +#define zng_uncompress @ZLIB_SYMBOL_PREFIX@zng_uncompress +#define zng_uncompress2 @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError +#define zng_zcalloc @ZLIB_SYMBOL_PREFIX@zng_zcalloc +#define zng_zcfree @ZLIB_SYMBOL_PREFIX@zng_zcfree +#define zng_zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +#define zng_zlibVersion @ZLIB_SYMBOL_PREFIX@zng_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifdef WITH_GZFILEOP +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define zng_gz_header_s @ZLIB_SYMBOL_PREFIX@zng_gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* zlib-ng specific symbols */ +#define zng_deflate_param @ZLIB_SYMBOL_PREFIX@zng_deflate_param +#define zng_deflate_param_value @ZLIB_SYMBOL_PREFIX@zng_deflate_param_value +#define zng_deflateSetParams @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams +#define zng_deflateGetParams @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version +#define zng_vstring @ZLIB_SYMBOL_PREFIX@zng_vstring +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError + +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep + +#define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +#define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.empty b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.empty new file mode 100644 index 000000000..b24cb834a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.empty @@ -0,0 +1,8 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.empty because ZLIB_SYMBOL_PREFIX was NOT set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.in b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.in new file mode 100644 index 000000000..f49615818 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zlib_name_mangling.h.in @@ -0,0 +1,170 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define _dist_code @ZLIB_SYMBOL_PREFIX@_dist_code +#define _length_code @ZLIB_SYMBOL_PREFIX@_length_code +#define _tr_align @ZLIB_SYMBOL_PREFIX@_tr_align +#define _tr_flush_bits @ZLIB_SYMBOL_PREFIX@_tr_flush_bits +#define _tr_flush_block @ZLIB_SYMBOL_PREFIX@_tr_flush_block +#define _tr_init @ZLIB_SYMBOL_PREFIX@_tr_init +#define _tr_stored_block @ZLIB_SYMBOL_PREFIX@_tr_stored_block +#define _tr_tally @ZLIB_SYMBOL_PREFIX@_tr_tally +#define adler32 @ZLIB_SYMBOL_PREFIX@adler32 +#define adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine +#define adler32_combine64 @ZLIB_SYMBOL_PREFIX@adler32_combine64 +#define adler32_z @ZLIB_SYMBOL_PREFIX@adler32_z +#ifndef Z_SOLO +# define compress @ZLIB_SYMBOL_PREFIX@compress +# define compress2 @ZLIB_SYMBOL_PREFIX@compress2 +# define compressBound @ZLIB_SYMBOL_PREFIX@compressBound +#endif +#define crc32 @ZLIB_SYMBOL_PREFIX@crc32 +#define crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine +#define crc32_combine64 @ZLIB_SYMBOL_PREFIX@crc32_combine64 +#define crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen +#define crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +#define crc32_combine_op @ZLIB_SYMBOL_PREFIX@crc32_combine_op +#define crc32_z @ZLIB_SYMBOL_PREFIX@crc32_z +#define deflate @ZLIB_SYMBOL_PREFIX@deflate +#define deflateBound @ZLIB_SYMBOL_PREFIX@deflateBound +#define deflateCopy @ZLIB_SYMBOL_PREFIX@deflateCopy +#define deflateEnd @ZLIB_SYMBOL_PREFIX@deflateEnd +#define deflateGetDictionary @ZLIB_SYMBOL_PREFIX@deflateGetDictionary +#define deflateInit @ZLIB_SYMBOL_PREFIX@deflateInit +#define deflateInit2 @ZLIB_SYMBOL_PREFIX@deflateInit2 +#define deflateInit2_ @ZLIB_SYMBOL_PREFIX@deflateInit2_ +#define deflateInit_ @ZLIB_SYMBOL_PREFIX@deflateInit_ +#define deflateParams @ZLIB_SYMBOL_PREFIX@deflateParams +#define deflatePending @ZLIB_SYMBOL_PREFIX@deflatePending +#define deflatePrime @ZLIB_SYMBOL_PREFIX@deflatePrime +#define deflateReset @ZLIB_SYMBOL_PREFIX@deflateReset +#define deflateResetKeep @ZLIB_SYMBOL_PREFIX@deflateResetKeep +#define deflateSetDictionary @ZLIB_SYMBOL_PREFIX@deflateSetDictionary +#define deflateSetHeader @ZLIB_SYMBOL_PREFIX@deflateSetHeader +#define deflateTune @ZLIB_SYMBOL_PREFIX@deflateTune +#define deflate_copyright @ZLIB_SYMBOL_PREFIX@deflate_copyright +#define fill_window @ZLIB_SYMBOL_PREFIX@fill_window +#define fixedtables @ZLIB_SYMBOL_PREFIX@fixedtables +#define flush_pending @ZLIB_SYMBOL_PREFIX@flush_pending +#define get_crc_table @ZLIB_SYMBOL_PREFIX@get_crc_table +#ifndef Z_SOLO +# define gz_error @ZLIB_SYMBOL_PREFIX@gz_error +# define gz_strwinerror @ZLIB_SYMBOL_PREFIX@gz_strwinerror +# define gzbuffer @ZLIB_SYMBOL_PREFIX@gzbuffer +# define gzclearerr @ZLIB_SYMBOL_PREFIX@gzclearerr +# define gzclose @ZLIB_SYMBOL_PREFIX@gzclose +# define gzclose_r @ZLIB_SYMBOL_PREFIX@gzclose_r +# define gzclose_w @ZLIB_SYMBOL_PREFIX@gzclose_w +# define gzdirect @ZLIB_SYMBOL_PREFIX@gzdirect +# define gzdopen @ZLIB_SYMBOL_PREFIX@gzdopen +# define gzeof @ZLIB_SYMBOL_PREFIX@gzeof +# define gzerror @ZLIB_SYMBOL_PREFIX@gzerror +# define gzflush @ZLIB_SYMBOL_PREFIX@gzflush +# define gzfread @ZLIB_SYMBOL_PREFIX@gzfread +# define gzfwrite @ZLIB_SYMBOL_PREFIX@gzfwrite +# define gzgetc @ZLIB_SYMBOL_PREFIX@gzgetc +# define gzgetc_ @ZLIB_SYMBOL_PREFIX@gzgetc_ +# define gzgets @ZLIB_SYMBOL_PREFIX@gzgets +# define gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset +# define gzoffset64 @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define gzopen @ZLIB_SYMBOL_PREFIX@gzopen +# define gzopen64 @ZLIB_SYMBOL_PREFIX@gzopen64 +# ifdef _WIN32 +# define gzopen_w @ZLIB_SYMBOL_PREFIX@gzopen_w +# endif +# define gzprintf @ZLIB_SYMBOL_PREFIX@gzprintf +# define gzputc @ZLIB_SYMBOL_PREFIX@gzputc +# define gzputs @ZLIB_SYMBOL_PREFIX@gzputs +# define gzread @ZLIB_SYMBOL_PREFIX@gzread +# define gzrewind @ZLIB_SYMBOL_PREFIX@gzrewind +# define gzseek @ZLIB_SYMBOL_PREFIX@gzseek +# define gzseek64 @ZLIB_SYMBOL_PREFIX@gzseek64 +# define gzsetparams @ZLIB_SYMBOL_PREFIX@gzsetparams +# define gztell @ZLIB_SYMBOL_PREFIX@gztell +# define gztell64 @ZLIB_SYMBOL_PREFIX@gztell64 +# define gzungetc @ZLIB_SYMBOL_PREFIX@gzungetc +# define gzvprintf @ZLIB_SYMBOL_PREFIX@gzvprintf +# define gzwrite @ZLIB_SYMBOL_PREFIX@gzwrite +#endif +#define inflate @ZLIB_SYMBOL_PREFIX@inflate +#define inflateBack @ZLIB_SYMBOL_PREFIX@inflateBack +#define inflateBackEnd @ZLIB_SYMBOL_PREFIX@inflateBackEnd +#define inflateBackInit @ZLIB_SYMBOL_PREFIX@inflateBackInit +#define inflateBackInit_ @ZLIB_SYMBOL_PREFIX@inflateBackInit_ +#define inflateCodesUsed @ZLIB_SYMBOL_PREFIX@inflateCodesUsed +#define inflateCopy @ZLIB_SYMBOL_PREFIX@inflateCopy +#define inflateEnd @ZLIB_SYMBOL_PREFIX@inflateEnd +#define inflateGetDictionary @ZLIB_SYMBOL_PREFIX@inflateGetDictionary +#define inflateGetHeader @ZLIB_SYMBOL_PREFIX@inflateGetHeader +#define inflateInit @ZLIB_SYMBOL_PREFIX@inflateInit +#define inflateInit2 @ZLIB_SYMBOL_PREFIX@inflateInit2 +#define inflateInit2_ @ZLIB_SYMBOL_PREFIX@inflateInit2_ +#define inflateInit_ @ZLIB_SYMBOL_PREFIX@inflateInit_ +#define inflateMark @ZLIB_SYMBOL_PREFIX@inflateMark +#define inflatePrime @ZLIB_SYMBOL_PREFIX@inflatePrime +#define inflateReset @ZLIB_SYMBOL_PREFIX@inflateReset +#define inflateReset2 @ZLIB_SYMBOL_PREFIX@inflateReset2 +#define inflateResetKeep @ZLIB_SYMBOL_PREFIX@inflateResetKeep +#define inflateSetDictionary @ZLIB_SYMBOL_PREFIX@inflateSetDictionary +#define inflateSync @ZLIB_SYMBOL_PREFIX@inflateSync +#define inflateSyncPoint @ZLIB_SYMBOL_PREFIX@inflateSyncPoint +#define inflateUndermine @ZLIB_SYMBOL_PREFIX@inflateUndermine +#define inflateValidate @ZLIB_SYMBOL_PREFIX@inflateValidate +#define inflate_copyright @ZLIB_SYMBOL_PREFIX@inflate_copyright +#define inflate_ensure_window @ZLIB_SYMBOL_PREFIX@inflate_ensure_window +#define inflate_fast @ZLIB_SYMBOL_PREFIX@inflate_fast +#define inflate_table @ZLIB_SYMBOL_PREFIX@inflate_table +#define read_buf @ZLIB_SYMBOL_PREFIX@read_buf +#ifndef Z_SOLO +# define uncompress @ZLIB_SYMBOL_PREFIX@uncompress +# define uncompress2 @ZLIB_SYMBOL_PREFIX@uncompress2 +#endif +#define zError @ZLIB_SYMBOL_PREFIX@zError +#ifndef Z_SOLO +# define zcalloc @ZLIB_SYMBOL_PREFIX@zcalloc +# define zcfree @ZLIB_SYMBOL_PREFIX@zcfree +#endif +#define zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +#define zlibVersion @ZLIB_SYMBOL_PREFIX@zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifndef Z_SOLO +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define gz_header_s @ZLIB_SYMBOL_PREFIX@gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* all zlib structs in zutil.h */ +#define z_errmsg @ZLIB_SYMBOL_PREFIX@z_errmsg +#define z_vstring @ZLIB_SYMBOL_PREFIX@z_vstring +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version + +/* zlib-ng specific symbols */ +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/zutil.c b/internal-complibs/zlib-ng-2.1.2/zutil.c new file mode 100644 index 000000000..9ab667df8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zutil.c @@ -0,0 +1,159 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "zutil.h" + +z_const char * const PREFIX(z_errmsg)[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + +const char PREFIX3(vstring)[] = + " zlib-ng 2.1.2"; + +#ifdef ZLIB_COMPAT +const char * Z_EXPORT zlibVersion(void) { + return ZLIB_VERSION; +} +#else +const char * Z_EXPORT zlibng_version(void) { + return ZLIBNG_VERSION; +} +#endif + +unsigned long Z_EXPORT PREFIX(zlibCompileFlags)(void) { + unsigned long flags; + + flags = 0; + switch ((int)(sizeof(unsigned int))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(unsigned long))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(void *))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif + /* Bit 13 reserved for DYNAMIC_CRC_TABLE */ +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +# include +# ifndef verbose +# define verbose 0 +# endif +int Z_INTERNAL z_verbose = verbose; + +void Z_INTERNAL z_error(const char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * Z_EXPORT PREFIX(zError)(int err) { + return ERR_MSG(err); +} + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size) { + Z_UNUSED(opaque); + return zng_alloc((size_t)items * (size_t)size); +} + +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr) { + Z_UNUSED(opaque); + zng_free(ptr); +} + +/* Since we support custom memory allocators, some which might not align memory as we expect, + * we have to ask for extra memory and return an aligned pointer. */ +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align) { + uintptr_t return_ptr, original_ptr; + uint32_t alloc_size, align_diff; + void *ptr; + + /* If no custom calloc function used then call zlib-ng's aligned calloc */ + if (zalloc == PREFIX(zcalloc)) + return PREFIX(zcalloc)(opaque, items, size); + + /* Allocate enough memory for proper alignment and to store the original memory pointer */ + alloc_size = sizeof(void *) + (items * size) + align; + ptr = zalloc(opaque, 1, alloc_size); + if (!ptr) + return NULL; + + /* Calculate return pointer address with space enough to store original pointer */ + align_diff = align - ((uintptr_t)ptr % align); + return_ptr = (uintptr_t)ptr + align_diff; + if (align_diff < sizeof(void *)) + return_ptr += align; + + /* Store the original pointer for free() */ + original_ptr = return_ptr - sizeof(void *); + memcpy((void *)original_ptr, &ptr, sizeof(void *)); + + /* Return properly aligned pointer in allocation */ + return (void *)return_ptr; +} + +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr) { + /* If no custom cfree function used then call zlib-ng's aligned cfree */ + if (zfree == PREFIX(zcfree)) { + PREFIX(zcfree)(opaque, ptr); + return; + } + if (!ptr) + return; + + /* Calculate offset to original memory allocation pointer */ + void *original_ptr = (void *)((uintptr_t)ptr - sizeof(void *)); + void *free_ptr = *(void **)original_ptr; + + /* Free original memory allocation */ + zfree(opaque, free_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.2/zutil.h b/internal-complibs/zlib-ng-2.1.2/zutil.h new file mode 100644 index 000000000..663616b44 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zutil.h @@ -0,0 +1,148 @@ +#ifndef ZUTIL_H_ +#define ZUTIL_H_ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +typedef unsigned char uch; /* Included for compatibility with external code only */ +typedef uint16_t ush; /* Included for compatibility with external code only */ +typedef unsigned long ulg; + +extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) PREFIX(z_errmsg)[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm, err) return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#define MAX_BITS 15 +/* all codes must not exceed MAX_BITS bits */ +#define MAX_DIST_EXTRA_BITS 13 +/* maximum number of extra distance bits */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define STD_MIN_MATCH 3 +#define STD_MAX_MATCH 258 +/* The minimum and maximum match lengths mandated by the deflate standard */ + +#define WANT_MIN_MATCH 4 +/* The minimum wanted match length, affects deflate_quick, deflate_fast, deflate_medium and deflate_slow */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + +#define ADLER32_INITIAL_VALUE 1 /* initial adler-32 hash value */ +#define CRC32_INITIAL_VALUE 0 /* initial crc-32 hash value */ + +#define ZLIB_WRAPLEN 6 /* zlib format overhead */ +#define GZIP_WRAPLEN 18 /* gzip format overhead */ + +#define DEFLATE_HEADER_BITS 3 +#define DEFLATE_EOBS_BITS 15 +#define DEFLATE_PAD_BITS 6 +#define DEFLATE_BLOCK_OVERHEAD ((DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3) +/* deflate block overhead: 3 bits for block start + 15 bits for block end + padding to nearest byte */ + +#define DEFLATE_QUICK_LIT_MAX_BITS 9 +#define DEFLATE_QUICK_OVERHEAD(x) ((x * (DEFLATE_QUICK_LIT_MAX_BITS - 8) + 7) >> 3) +/* deflate_quick worst-case overhead: 9 bits per literal, round up to next byte (+7) */ + + + /* target dependencies */ + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + + /* macros */ + +#define CHECK_VER_STSIZE(_ver,_stsize) ((_ver) == NULL || (_ver)[0] != PREFIX2(VERSION)[0] || (_stsize) != (int32_t)sizeof(PREFIX3(stream))) + + /* memory allocation functions */ + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size); +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr); + +typedef void *zng_calloc_func(void *opaque, unsigned items, unsigned size); +typedef void zng_cfree_func(void *opaque, void *ptr); + +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align); +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr); + +#define ZALLOC(strm, items, size) PREFIX3(alloc_aligned)((strm)->zalloc, (strm)->opaque, (items), (size), 64) +#define ZFREE(strm, addr) PREFIX3(free_aligned)((strm)->zfree, (strm)->opaque, (void *)(addr)) + +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/zutil_p.h b/internal-complibs/zlib-ng-2.1.2/zutil_p.h new file mode 100644 index 000000000..caec91d50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/zutil_p.h @@ -0,0 +1,71 @@ +/* zutil_p.h -- Private inline functions used internally in zlib-ng + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZUTIL_P_H +#define ZUTIL_P_H + +#if defined(__APPLE__) || defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC) +# include +#elif defined(__FreeBSD__) +# include +# include +#else +# include +#endif + +/* Function to allocate 16 or 64-byte aligned memory */ +static inline void *zng_alloc(size_t size) { +#ifdef HAVE_POSIX_MEMALIGN + void *ptr; + return posix_memalign(&ptr, 64, size) ? NULL : ptr; +#elif defined(_WIN32) + return (void *)_aligned_malloc(size, 64); +#elif defined(__APPLE__) + return (void *)malloc(size); /* MacOS always aligns to 16 bytes */ +#elif defined(HAVE_ALIGNED_ALLOC) + return (void *)aligned_alloc(64, size); +#else + return (void *)memalign(64, size); +#endif +} + +/* Function that can free aligned memory */ +static inline void zng_free(void *ptr) { +#if defined(_WIN32) + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +/* Use memcpy instead of memcmp to avoid older compilers not converting memcmp calls to + unaligned comparisons when unaligned access is supported. */ +static inline int32_t zng_memcmp_2(const void *src0, const void *src1) { + uint16_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_4(const void *src0, const void *src1) { + uint32_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_8(const void *src0, const void *src1) { + uint64_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +#endif From 7574e41bddea23aa1e4bf1fa725fb4fb7144e731 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:13:23 +0100 Subject: [PATCH 4/5] Remove .git* files --- .../zlib-ng-2.1.0-beta1/.gitattributes | 8 - .../zlib-ng-2.1.0-beta1/.github/FUNDING.yml | 1 - .../.github/workflows/analyze.yml | 78 --- .../.github/workflows/cmake.yml | 609 ----------------- .../.github/workflows/codeql.yml | 41 -- .../.github/workflows/configure.yml | 238 ------- .../.github/workflows/fuzz.yml | 36 - .../.github/workflows/libpng.yml | 51 -- .../.github/workflows/link.yml | 66 -- .../.github/workflows/nmake.yml | 68 -- .../.github/workflows/pigz.yml | 131 ---- .../.github/workflows/pkgcheck.yml | 176 ----- .../.github/workflows/release.yml | 100 --- .../zlib-ng-2.1.0-beta1/.gitignore | 97 --- .../zlib-ng-2.1.1-beta2/.gitattributes | 8 - .../zlib-ng-2.1.1-beta2/.github/FUNDING.yml | 1 - .../.github/workflows/analyze.yml | 78 --- .../.github/workflows/cmake.yml | 623 ----------------- .../.github/workflows/codeql.yml | 41 -- .../.github/workflows/configure.yml | 238 ------- .../.github/workflows/fuzz.yml | 36 - .../.github/workflows/libpng.yml | 51 -- .../.github/workflows/link.yml | 66 -- .../.github/workflows/nmake.yml | 68 -- .../.github/workflows/pigz.yml | 131 ---- .../.github/workflows/pkgcheck.yml | 176 ----- .../.github/workflows/release.yml | 100 --- .../zlib-ng-2.1.1-beta2/.gitignore | 97 --- .../zlib-ng-2.1.2/.gitattributes | 8 - .../zlib-ng-2.1.2/.github/FUNDING.yml | 1 - .../.github/workflows/analyze.yml | 78 --- .../zlib-ng-2.1.2/.github/workflows/cmake.yml | 635 ------------------ .../.github/workflows/codeql.yml | 41 -- .../.github/workflows/configure.yml | 252 ------- .../zlib-ng-2.1.2/.github/workflows/fuzz.yml | 36 - .../.github/workflows/libpng.yml | 51 -- .../zlib-ng-2.1.2/.github/workflows/link.yml | 66 -- .../zlib-ng-2.1.2/.github/workflows/nmake.yml | 68 -- .../zlib-ng-2.1.2/.github/workflows/pigz.yml | 131 ---- .../.github/workflows/pkgcheck.yml | 192 ------ .../.github/workflows/release.yml | 100 --- internal-complibs/zlib-ng-2.1.2/.gitignore | 97 --- 42 files changed, 5170 deletions(-) delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml delete mode 100644 internal-complibs/zlib-ng-2.1.0-beta1/.gitignore delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml delete mode 100644 internal-complibs/zlib-ng-2.1.1-beta2/.gitignore delete mode 100644 internal-complibs/zlib-ng-2.1.2/.gitattributes delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml delete mode 100644 internal-complibs/zlib-ng-2.1.2/.gitignore diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes b/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes deleted file mode 100644 index ac21ec459..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -* text=auto -*.abi text eol=lf -*.c text -*.h text -*.sh text eol=lf -crc32_braid_tbl.h hooks-max-size=1000000 -Makefile text -configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml deleted file mode 100644 index 7cd812915..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml deleted file mode 100644 index cbdea0e50..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/analyze.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Static Analysis -on: [push, pull_request] -jobs: - static-analysis: - name: GCC - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y gcc-10 - - - name: Generate project files - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CC: gcc-10 - CFLAGS: - -fanalyzer - -Werror - -Wanalyzer-double-fclose - -Wanalyzer-double-free - -Wanalyzer-exposure-through-output-file - -Wanalyzer-file-leak - -Wanalyzer-free-of-non-heap - -Wanalyzer-malloc-leak - -Wanalyzer-null-argument - -Wanalyzer-null-dereference - -Wanalyzer-possible-null-argument - -Wanalyzer-possible-null-dereference - -Wanalyzer-stale-setjmp-buffer - -Wanalyzer-tainted-array-index - -Wanalyzer-unsafe-call-within-signal-handler - -Wanalyzer-use-after-free - -Wanalyzer-use-of-pointer-in-stale-stack-frame - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release > /dev/null - - Clang: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y clang-tools - - - name: Generate project files - run: | - scan-build --status-bugs \ - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CI: true - - - name: Compile source code - run: | - scan-build --status-bugs \ - cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml deleted file mode 100644 index d50a2dcfa..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/cmake.yml +++ /dev/null @@ -1,609 +0,0 @@ -name: CMake -on: [push, pull_request] -env: - TERM: xterm-256color - GTEST_COLOR: 1 -jobs: - cmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SANITIZER=Address - codecov: ubuntu_gcc - - - name: Ubuntu GCC Benchmark - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_BENCHMARKS=ON - codecov: ubuntu_gcc_benchmark - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_sprefix - - - name: Ubuntu GCC Compat Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_compat_sprefix - - - name: Ubuntu GCC -O3 OSB - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng - codecov: ubuntu_gcc_osb - cflags: -O3 - - - name: Ubuntu GCC -O3 OSB add_subdirectory - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng/test/add-subdirectory-project - - - name: Ubuntu GCC -O1 No Unaligned UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_o1 - cflags: -O1 - - - name: Ubuntu GCC 32-bit - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 - packages: gcc-multilib g++-multilib - codecov: ubuntu_gcc_m32 - - - name: Ubuntu GCC No CTZLL - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF - codecov: ubuntu_gcc_no_ctzll - - - name: Ubuntu GCC No CTZ - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF - codecov: ubuntu_gcc_no_ctz - - - name: Ubuntu GCC No AVX2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_avx2 - - - name: Ubuntu GCC No SSE2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse2 - - - name: Ubuntu GCC No SSE4.2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse42 - - - name: Ubuntu GCC No PCLMULQDQ UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_pclmulqdq - - - name: Ubuntu GCC Compat No Opt ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address - codecov: ubuntu_gcc_compat_no_opt - cflags: -DNOT_TWEAK_COMPILER - - - name: Ubuntu GCC ARM SF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf - - - name: Ubuntu GCC ARM SF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf_compat_no_opt - - - name: Ubuntu GCC ARM HF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf - - - name: Ubuntu GCC ARM HF No ACLE ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_acle - - - name: Ubuntu GCC ARM HF No NEON ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_neon - - - name: Ubuntu GCC ARM HF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_compat_no_opt - - - name: Ubuntu GCC AARCH64 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64 - - - name: Ubuntu GCC AARCH64 No ACLE UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_acle - - - name: Ubuntu GCC AARCH64 No NEON UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_neon - - - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_compat_no_opt - - - name: Ubuntu GCC PPC - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc_no_power8 - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake - packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross - ldflags: -static - codecov: ubuntu_gcc_ppc64 - - - name: Ubuntu GCC PPC64LE - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross - codecov: ubuntu_gcc_ppc64le - - - name: Ubuntu GCC SPARC64 - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake - packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross - ldflags: -static - codecov: ubuntu_gcc_sparc64 - - - name: Ubuntu GCC S390X ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X No vectorized CRC32 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x_no_crc32 - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC ASAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC Compat UBSAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc_compat - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu Clang S390X DFLTCC MSAN - os: z15 - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu MinGW i686 - os: ubuntu-22.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake - packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 - ldflags: -static - codecov: ubuntu_gcc_mingw_i686 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu MinGW x86_64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake - packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 - ldflags: -static - codecov: ubuntu_gcc_mingw_x86_64 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu 20.04 Clang - os: ubuntu-20.04 - compiler: clang-6.0 - cxx-compiler: clang++-6.0 - packages: clang-6.0 - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang - - # Check for undefined symbols in the version script for the modern api - - name: Ubuntu Clang Undefined Symbols - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF - build-shared: ON - packages: clang-11 llvm-11 lld - - # Check for undefined symbols in the version script for the compat api - - name: Ubuntu Clang Undefined Symbols Compat - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON - build-shared: ON - packages: clang-11 llvm-11 lld - - - name: Ubuntu Clang Inflate Strict - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_STRICT=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_strict - - - name: Ubuntu Clang Inflate Allow Invalid Dist - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_allow_invalid_dist - - - name: Ubuntu Clang Reduced Memory - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_REDUCED_MEM=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_reduced_mem - - - name: Ubuntu Clang Memory Map - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cflags: -DUSE_MMAP - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_mmap - - - name: Ubuntu Clang Debug - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_debug - build-config: Debug - - - name: Ubuntu Clang MSAN - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_SANITIZER=Memory - packages: ninja-build clang-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - # https://github.com/llvm/llvm-project/issues/55785 - msan-options: use_sigaltstack=0 - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON - - - name: Windows MSVC 2022 v143 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 - - - name: Windows MSVC 2022 v143 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 - - - name: Windows MSVC 2022 v142 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 - - - name: Windows MSVC 2022 v142 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 - - - name: Windows MSVC 2022 v141 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 - - - name: Windows MSVC 2022 v141 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 - - - name: Windows MSVC 2019 v140 Win32 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 - - - name: Windows MSVC 2019 v140 Win64 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 - - - name: Windows MSVC ARM No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM - - - name: Windows MSVC ARM64 No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - - - name: Windows ClangCl Win32 - os: windows-latest - cmake-args: -T ClangCl -A Win32 - - - name: Windows ClangCl Win64 - os: windows-latest - cmake-args: -T ClangCl -A x64 - - - name: Windows GCC - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja - codecov: win64_gcc - - - name: Windows GCC Compat No Opt - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF - codecov: win64_gcc_compat_no_opt - - - name: macOS Clang ASAN - os: macos-latest - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_SANITIZER=Address - codecov: macos_clang - - - name: macOS GCC UBSAN - os: macos-latest - compiler: gcc-10 - cxx-compiler: g++-10 - cmake-args: -DWITH_SANITIZER=Undefined - packages: gcc@10 - gcov-exec: gcov-10 - codecov: macos_gcc - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs - # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. - if: contains(matrix.name, 'MinGW') == false - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add repositories (Wine) - if: contains(matrix.packages, 'wine32') - run: sudo dpkg --add-architecture i386 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} - - - name: Install packages (Windows) - if: runner.os == 'Windows' - run: | - # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. - # zlib-ng does not need perl, so simply remove it. - choco uninstall --no-progress strawberryperl - choco install --no-progress ninja ${{ matrix.packages }} - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Initialize Wine - # Prevent parallel test jobs from initializing Wine at the same time - if: contains(matrix.packages, 'wine') - run: wineboot --init - - - name: Compile LLVM C++ libraries (MSAN) - if: contains(matrix.name, 'MSAN') - run: | - git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 - cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_USE_SANITIZER=MemoryWithOrigins \ - -DLLVM_LIBC_ENABLE_LINTING=OFF - cmake --build llvm-project/build -j2 -- cxx cxxabi - echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - - - name: Generate project files - shell: bash - # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources - run: | - cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ - -DWITH_FUZZERS=ON \ - -DWITH_MAINTAINER_WARNINGS=ON \ - ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} - - - name: Run test cases - # Don't run tests on Windows ARM - if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: ${{ matrix.build-dir || '.' }} - env: - ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 - - - name: Generate coverage report - if: matrix.codecov - shell: bash - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root ${{ matrix.build-src-dir || '.' }} \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - directory: ${{ matrix.build-src-dir || '.' }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml deleted file mode 100644 index 1cfa4d7fa..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/codeql.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "develop" ] - pull_request: - branches: [ "develop" ] - schedule: - - cron: "27 17 * * 0" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ cpp ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - queries: +security-and-quality - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml deleted file mode 100644 index 51861533e..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/configure.yml +++ /dev/null @@ -1,238 +0,0 @@ -name: Configure -on: [push, pull_request] -jobs: - configure: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - configure-args: --warn - - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - configure-args: --warn - - - name: Ubuntu GCC OSB - os: ubuntu-latest - compiler: gcc - configure-args: --warn - build-dir: ../build - build-src-dir: ../zlib-ng - - - name: Ubuntu GCC Compat No Opt - os: ubuntu-latest - compiler: gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - - - name: Ubuntu GCC ARM SF - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM SF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No ACLE - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-acle - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No NEON - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-neon - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No ACLE - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-acle - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No NEON - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-neon - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 Compat No Opt - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --without-power8 - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - compiler: powerpc64-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - compiler: powerpc64le-linux-gnu-gcc - configure-args: --warn - chost: powerpc64le-linux-gnu - packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross - - - name: Ubuntu GCC S390X - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X No vectorized CRC32 - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static --without-crc32-vx - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X DFLTCC - os: z15 - compiler: gcc - configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu GCC S390X DFLTCC Compat - os: z15 - compiler: gcc - configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - configure-args: --warn --zlib-compat --static - configure-prefix: emconfigure - cflags: -static - ldflags: -static - emu-run: node - - - name: macOS GCC Symbol Prefix - os: macOS-latest - compiler: gcc-11 - configure-args: --sprefix=zTest_ - - - name: macOS GCC Symbol Prefix & Compat - os: macOS-latest - compiler: gcc-11 - configure-args: --zlib-compat --sprefix=zTest_ - - - name: macOS GCC - os: macOS-latest - compiler: gcc-11 - configure-args: --warn - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Generate project files - run: | - mkdir ${{ matrix.build-dir || '.not-used' }} - cd ${{ matrix.build-dir || '.' }} - ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CHOST: ${{ matrix.chost }} - EMU_RUN: ${{ matrix.emu-run }} - CI: true - - - name: Compile source code - run: make -j2 - working-directory: ${{ matrix.build-dir }} - - - name: Run test cases - run: make test - working-directory: ${{ matrix.build-dir }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (configure) - path: | - **/Makefile - ${{ matrix.build-dir || '.' }}/configure.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml deleted file mode 100644 index 95d64e67a..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/fuzz.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: OSS-Fuzz -on: - pull_request: - push: - branches: - - stable - - develop - - pre-release - - '2.*' - tags: - - '*' - -jobs: - fuzzing: - name: Fuzzing - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - dry-run: false - - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - fuzz-seconds: 600 - dry-run: false - - - name: Upload Crash - uses: actions/upload-artifact@v3 - if: failure() - with: - name: artifacts - path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml deleted file mode 100644 index c5fea574f..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/libpng.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Libpng -on: [push, pull_request] -jobs: - libpng: - name: Ubuntu Clang - runs-on: ubuntu-latest - steps: - - name: Checkout repository (zlib-ng) - uses: actions/checkout@v3 - - - name: Generate project files (zlib-ng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_COMPAT=ON \ - -DZLIB_ENABLE_TESTS=OFF - env: - CC: clang - CFLAGS: -fPIC - CI: true - - - name: Compile source code (zlib-ng) - run: cmake --build . -j2 --config Release - - - name: Checkout repository (libpng) - uses: actions/checkout@v3 - with: - repository: glennrp/libpng - path: libpng - - - name: Generate project files (libpng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DPNG_TESTS=ON \ - -DPNG_STATIC=OFF \ - -DZLIB_INCLUDE_DIR=.. \ - -DZLIB_LIBRARY=$PWD/../libz.a - working-directory: libpng - env: - CC: clang - CI: true - - - name: Compile source code (libpng) - run: cmake --build . -j2 --config Release - working-directory: libpng - - - name: Run test cases (libpng) - run: ctest -j2 -C Release --output-on-failure --max-width 120 - working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml deleted file mode 100644 index 5de669840..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/link.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Link -on: [push, pull_request] -jobs: - zlib: - name: Link zlib - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout zlib repository - uses: actions/checkout@v3 - with: - repository: madler/zlib - path: zlib - - - name: Generate project files (zlib) - run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF - - - name: Compile source code (zlib) - run: cmake --build zlib/build -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 - - zlib-ng-compat: - name: Link zlib-ng compat - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Generate project files (compat) - run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON - - - name: Compile source code (compat) - run: cmake --build compat -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib-ng compat (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml deleted file mode 100644 index 38e669093..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/nmake.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: NMake -on: [push, pull_request] -jobs: - nmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows NMake x86 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86 - - - name: Windows NMake x64 compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes - - - name: Windows NMake x64 Symbol Prefix - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 Symbol Prefix Compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - - - name: Windows NMake ARM No Test - os: windows-2022 - makefile: win32/Makefile.arm - arch: x86_arm - - - name: Windows NMake ARM64 No Test - os: windows-2022 - makefile: win32/Makefile.a64 - arch: x86_arm64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup development environment - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: ${{ matrix.arch }} - - - name: Compile source code - shell: cmd - run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} - - - name: Run test cases - shell: cmd - # Don't run tests on Windows ARM - if: contains(matrix.arch, 'arm') == false - run: | - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml deleted file mode 100644 index be4e1ce50..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pigz.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Pigz -on: [push, pull_request] -jobs: - pigz: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz - - - name: Ubuntu Clang No Optim - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_optim - cmake-args: -DWITH_OPTIM=OFF - - # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 - - name: Ubuntu Clang No Threads - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_threads - cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_pigz_aarch64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Generate project files - run: | - cmake ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_ROOT=../.. \ - -DWITH_CODE_COVERAGE=ON \ - -DWITH_MAINTAINER_WARNINGS=ON - working-directory: test/pigz - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} - working-directory: test/pigz - - - name: Run test cases - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: test/pigz - - - name: Generate coverage report - if: matrix.codecov - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root . \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml deleted file mode 100644 index 8888cf37e..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/pkgcheck.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Package Check -on: [push, pull_request] -jobs: - pkgcheck: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC -m32 - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - packages: gcc-multilib g++-multilib - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 - cflags: -m32 - cxxflags: -m32 - ldflags: -m32 - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - chost: arm-linux-gnueabihf - compiler: arm-linux-gnueabihf-gcc - cxx-compiler: g++-arm-linux-gnueabihf - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake - packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - chost: aarch64-linux-gnu - compiler: aarch64-linux-gnu-gcc - cxx-compiler: g++-aarch64-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake - packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - chost: powerpc-linux-gnu - compiler: powerpc-linux-gnu-gcc - cxx-compiler: g++-powerpc-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - chost: powerpc64le-linux-gnu - compiler: powerpc64le-linux-gnu-gcc - cxx-compiler: g++-powerpc64le-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross - - - name: macOS Clang - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - - - name: macOS Clang Native - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON - configure-args: --native - - - name: macOS Clang Symbol Prefix - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - configure-args: --sprefix=zTest_ - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ - abigail-tools \ - diffoscope \ - ninja-build - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja diffoscope ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Select Xcode version (macOS) - # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports - # AppleClang linking with libtool using -D argument - # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 - if: runner.os == 'macOS' - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '11.7.0' - - - name: Compare builds - run: sh test/pkgcheck.sh - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Compare builds (compat) - run: sh test/pkgcheck.sh --zlib-compat - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI (compat) - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --zlib-compat --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} - path: | - **/*.abi - btmp1/configure.log - btmp1/CMakeFiles/CMakeOutput.log - btmp1/CMakeFiles/CMakeError.log - btmp2/configure.log - btmp2/CMakeFiles/CMakeOutput.log - btmp2/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml deleted file mode 100644 index b64933cc7..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.github/workflows/release.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Release -on: - push: - tags: - - '*' -jobs: - release: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows MSVC Win32 - os: windows-latest - compiler: cl - cmake-args: -A Win32 - deploy-name: win-x86 - - - name: Windows MSVC Win32 Compat - os: windows-latest - compiler: cl - cmake-args: -A Win32 -DZLIB_COMPAT=ON - deploy-name: win-x86-compat - - - name: Windows MSVC Win64 - os: windows-latest - compiler: cl - cmake-args: -A x64 - deploy-name: win-x86-64 - - - name: Windows MSVC Win64 Compat - os: windows-latest - compiler: cl - cmake-args: -A x64 -DZLIB_COMPAT=ON - deploy-name: win-x86-64-compat - - - name: Windows MSVC ARM - os: windows-latest - compiler: cl - cmake-args: -A ARM - deploy-name: win-arm - - - name: Windows MSVC ARM Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM -DZLIB_COMPAT=ON - deploy-name: win-arm-compat - - - name: Windows MSVC ARM64 - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - deploy-name: win-arm64 - - - name: Windows MSVC ARM64 Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM64 -DZLIB_COMPAT=ON - deploy-name: win-arm64-compat - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set environment variables - shell: bash - run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - - - name: Generate project files - shell: bash - run: | - cmake . ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DZLIB_ENABLE_TESTS=ON \ - -DCMAKE_INSTALL_PREFIX=out \ - -DINSTALL_UTILS=ON - env: - CC: ${{ matrix.compiler }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release --target install - - - name: Package release (Windows) - if: runner.os == 'Windows' - run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md - working-directory: out - - - name: Upload release (Windows) - uses: svenstaro/upload-release-action@v2 - if: runner.os == 'Windows' - with: - asset_name: zlib-ng-${{ matrix.deploy-name }}.zip - file: zlib-ng-${{ matrix.deploy-name }}.zip - tag: ${{env.tag}} - repo_token: ${{ secrets.GITHUB_TOKEN }} - overwrite: true - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore b/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore deleted file mode 100644 index cd4a9c3fe..000000000 --- a/internal-complibs/zlib-ng-2.1.0-beta1/.gitignore +++ /dev/null @@ -1,97 +0,0 @@ -*.diff -*.patch -*.orig -*.rej - -*~ -*.a -*.lo -*.o -*.dylib - -*.gcda -*.gcno -*.gcov - -/benchmark_zlib -/example -/example64 -/examplesh -/gtest_zlib -/libz.so* -/libz-ng.so* -/makefixed -/minigzip -/minigzip64 -/minigzipsh -/switchlevels -/zlib.pc -/zlib-ng.pc - -.DS_Store -*_fuzzer -*.obj -*.exe -*.pdb -*.exp -*.lib -*.dll -*.res -foo.gz -*.manifest -*.opensdf -*.sln -*.sdf -*.vcxproj -*.vcxproj.filters -*.vcxproj.user -.vs - -CMakeCache.txt -CMakeFiles -Testing -/*.cmake -*.stackdump -*._h -zconf.h -zconf.h.cmakein -zconf.h.included -zconf-ng.h -zconf-ng.h.cmakein -ztest* -/test/CTestTestfile.cmake -/test/cmake_install.cmake - -configure.log -a.out - -/Makefile -/arch/arm/Makefile -/arch/generic/Makefile -/arch/power/Makefile -/arch/x86/Makefile -.kdev4 -*.kdev4 - -/Debug -/example.dir -/minigzip.dir -/zlib.dir -/zlibstatic.dir -/test/*.dir/ -/build/ -/build[.-]*/ -/btmp[12]/ -/pkgtmp[12]/ - -/.idea -/cmake-build-debug -/x64/Debug/ -/x64/Release/ -/win32/Debug/ -/win32/Release/ -/ARM*/Debug/ -/ARM*/Release/ -MinSizeRel -RelWithDebInfo -/_deps/googletest* diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes b/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes deleted file mode 100644 index ac21ec459..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -* text=auto -*.abi text eol=lf -*.c text -*.h text -*.sh text eol=lf -crc32_braid_tbl.h hooks-max-size=1000000 -Makefile text -configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml deleted file mode 100644 index 7cd812915..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml deleted file mode 100644 index cbdea0e50..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Static Analysis -on: [push, pull_request] -jobs: - static-analysis: - name: GCC - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y gcc-10 - - - name: Generate project files - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CC: gcc-10 - CFLAGS: - -fanalyzer - -Werror - -Wanalyzer-double-fclose - -Wanalyzer-double-free - -Wanalyzer-exposure-through-output-file - -Wanalyzer-file-leak - -Wanalyzer-free-of-non-heap - -Wanalyzer-malloc-leak - -Wanalyzer-null-argument - -Wanalyzer-null-dereference - -Wanalyzer-possible-null-argument - -Wanalyzer-possible-null-dereference - -Wanalyzer-stale-setjmp-buffer - -Wanalyzer-tainted-array-index - -Wanalyzer-unsafe-call-within-signal-handler - -Wanalyzer-use-after-free - -Wanalyzer-use-of-pointer-in-stale-stack-frame - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release > /dev/null - - Clang: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y clang-tools - - - name: Generate project files - run: | - scan-build --status-bugs \ - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CI: true - - - name: Compile source code - run: | - scan-build --status-bugs \ - cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml deleted file mode 100644 index 2a148626a..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml +++ /dev/null @@ -1,623 +0,0 @@ -name: CMake -on: [push, pull_request] -env: - TERM: xterm-256color - GTEST_COLOR: 1 -jobs: - cmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SANITIZER=Address - codecov: ubuntu_gcc - - - name: Ubuntu GCC Benchmark - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_BENCHMARKS=ON - codecov: ubuntu_gcc_benchmark - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_sprefix - - - name: Ubuntu GCC Compat Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_compat_sprefix - - - name: Ubuntu GCC -O3 OSB - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng - codecov: ubuntu_gcc_osb - cflags: -O3 - - - name: Ubuntu GCC -O3 OSB add_subdirectory - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng/test/add-subdirectory-project - - - name: Ubuntu GCC -O1 No Unaligned UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_o1 - cflags: -O1 - - - name: Ubuntu GCC 32-bit - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 - packages: gcc-multilib g++-multilib - codecov: ubuntu_gcc_m32 - - - name: Ubuntu GCC No CTZLL - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF - codecov: ubuntu_gcc_no_ctzll - - - name: Ubuntu GCC No CTZ - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF - codecov: ubuntu_gcc_no_ctz - - - name: Ubuntu GCC No AVX2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_avx2 - - - name: Ubuntu GCC No SSE2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse2 - - - name: Ubuntu GCC No SSE4.2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse42 - - - name: Ubuntu GCC No PCLMULQDQ UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_pclmulqdq - - - name: Ubuntu GCC Compat No Opt ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address - codecov: ubuntu_gcc_compat_no_opt - cflags: -DNOT_TWEAK_COMPILER - - - name: Ubuntu GCC ARM SF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf - - - name: Ubuntu GCC ARM SF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf_compat_no_opt - - - name: Ubuntu GCC ARM HF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf - - - name: Ubuntu GCC ARM HF No ACLE ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_acle - - - name: Ubuntu GCC ARM HF No NEON ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_neon - - - name: Ubuntu GCC ARM HF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_compat_no_opt - - - name: Ubuntu GCC AARCH64 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64 - - - name: Ubuntu GCC AARCH64 No ACLE UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_acle - - - name: Ubuntu GCC AARCH64 No NEON UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_neon - - - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_compat_no_opt - - - name: Ubuntu GCC PPC - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc_no_power8 - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake - packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross - ldflags: -static - codecov: ubuntu_gcc_ppc64 - - - name: Ubuntu GCC PPC64LE - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross - codecov: ubuntu_gcc_ppc64le - - - name: Ubuntu GCC SPARC64 - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake - packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross - ldflags: -static - codecov: ubuntu_gcc_sparc64 - - - name: Ubuntu GCC S390X ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X No vectorized CRC32 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x_no_crc32 - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC ASAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC Compat UBSAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc_compat - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu Clang S390X DFLTCC MSAN - os: z15 - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu MinGW i686 - os: ubuntu-22.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake - packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 libgcc-s1:i386 libstdc++6:i386 - ldflags: -static - codecov: ubuntu_gcc_mingw_i686 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu MinGW x86_64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake - packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 - ldflags: -static - codecov: ubuntu_gcc_mingw_x86_64 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu 20.04 Clang - os: ubuntu-20.04 - compiler: clang-6.0 - cxx-compiler: clang++-6.0 - packages: clang-6.0 - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang - - # Check for undefined symbols in the version script for the modern api - - name: Ubuntu Clang Undefined Symbols - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF - build-shared: ON - packages: clang-11 llvm-11 lld - - # Check for undefined symbols in the version script for the compat api - - name: Ubuntu Clang Undefined Symbols Compat - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON - build-shared: ON - packages: clang-11 llvm-11 lld - - - name: Ubuntu Clang Inflate Strict - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_STRICT=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_strict - - - name: Ubuntu Clang Inflate Allow Invalid Dist - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_allow_invalid_dist - - - name: Ubuntu Clang Reduced Memory - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_REDUCED_MEM=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_reduced_mem - - - name: Ubuntu Clang Memory Map - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cflags: -DUSE_MMAP - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_mmap - - - name: Ubuntu Clang Debug - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_debug - build-config: Debug - - - name: Ubuntu Clang MSAN - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_SANITIZER=Memory - packages: ninja-build clang-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - # https://github.com/llvm/llvm-project/issues/55785 - msan-options: use_sigaltstack=0 - - - name: Ubuntu Clang RISC-V - os: ubuntu-latest - cmake-args: -GNinja -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake -DTOOLCHAIN_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-clang -DQEMU_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64 - packages: build-essential cmake ninja-build - codecov: ubuntu_clang_toolchain_riscv - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON - - - name: Windows MSVC 2022 v143 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 - - - name: Windows MSVC 2022 v143 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 - - - name: Windows MSVC 2022 v142 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 - - - name: Windows MSVC 2022 v142 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 - - - name: Windows MSVC 2022 v141 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 - - - name: Windows MSVC 2022 v141 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 - - - name: Windows MSVC 2019 v140 Win32 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 - - - name: Windows MSVC 2019 v140 Win64 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 - - - name: Windows MSVC ARM No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM - - - name: Windows MSVC ARM64 No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - - - name: Windows ClangCl Win32 - os: windows-latest - cmake-args: -T ClangCl -A Win32 - - - name: Windows ClangCl Win64 - os: windows-latest - cmake-args: -T ClangCl -A x64 - - - name: Windows GCC - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja - codecov: win64_gcc - - - name: Windows GCC Compat No Opt - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF - codecov: win64_gcc_compat_no_opt - - - name: macOS Clang ASAN - os: macos-latest - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_SANITIZER=Address - codecov: macos_clang - - - name: macOS GCC UBSAN - os: macos-latest - compiler: gcc-10 - cxx-compiler: g++-10 - cmake-args: -DWITH_SANITIZER=Undefined - packages: gcc@10 - gcov-exec: gcov-10 - codecov: macos_gcc - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs - # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. - if: contains(matrix.name, 'MinGW') == false - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add repositories (Wine) - if: contains(matrix.packages, 'wine32') - run: sudo dpkg --add-architecture i386 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} - - - name: Download prebuilt RISC-V Clang toolchain & QEMU emulator - if: runner.os == 'Linux' && contains(matrix.name, 'RISC-V') - run: | - gh release download ubuntu20.04_llvm16.0.0_qemu7.0.0 --repo sifive/prepare-riscv-toolchain-qemu - tar zxvf prebuilt-riscv-toolchain-qemu.tar.gz - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Install packages (Windows) - if: runner.os == 'Windows' - run: | - # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. - # zlib-ng does not need perl, so simply remove it. - choco uninstall --no-progress strawberryperl - choco install --no-progress ninja ${{ matrix.packages }} - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Initialize Wine - # Prevent parallel test jobs from initializing Wine at the same time - if: contains(matrix.packages, 'wine') - run: wineboot --init - - - name: Compile LLVM C++ libraries (MSAN) - if: contains(matrix.name, 'MSAN') - run: | - git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 - cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_USE_SANITIZER=MemoryWithOrigins \ - -DLLVM_LIBC_ENABLE_LINTING=OFF - cmake --build llvm-project/build -j2 -- cxx cxxabi - echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - - - name: Generate project files - shell: bash - # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources - run: | - cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ - -DWITH_FUZZERS=ON \ - -DWITH_MAINTAINER_WARNINGS=ON \ - ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} - - - name: Run test cases - # Don't run tests on Windows ARM - if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: ${{ matrix.build-dir || '.' }} - env: - ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 - - - name: Generate coverage report - if: matrix.codecov - shell: bash - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root ${{ matrix.build-src-dir || '.' }} \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - directory: ${{ matrix.build-src-dir || '.' }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml deleted file mode 100644 index 1cfa4d7fa..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "develop" ] - pull_request: - branches: [ "develop" ] - schedule: - - cron: "27 17 * * 0" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ cpp ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - queries: +security-and-quality - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml deleted file mode 100644 index 51861533e..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml +++ /dev/null @@ -1,238 +0,0 @@ -name: Configure -on: [push, pull_request] -jobs: - configure: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - configure-args: --warn - - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - configure-args: --warn - - - name: Ubuntu GCC OSB - os: ubuntu-latest - compiler: gcc - configure-args: --warn - build-dir: ../build - build-src-dir: ../zlib-ng - - - name: Ubuntu GCC Compat No Opt - os: ubuntu-latest - compiler: gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - - - name: Ubuntu GCC ARM SF - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM SF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No ACLE - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-acle - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No NEON - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-neon - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No ACLE - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-acle - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No NEON - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-neon - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 Compat No Opt - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --without-power8 - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - compiler: powerpc64-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - compiler: powerpc64le-linux-gnu-gcc - configure-args: --warn - chost: powerpc64le-linux-gnu - packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross - - - name: Ubuntu GCC S390X - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X No vectorized CRC32 - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static --without-crc32-vx - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X DFLTCC - os: z15 - compiler: gcc - configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu GCC S390X DFLTCC Compat - os: z15 - compiler: gcc - configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - configure-args: --warn --zlib-compat --static - configure-prefix: emconfigure - cflags: -static - ldflags: -static - emu-run: node - - - name: macOS GCC Symbol Prefix - os: macOS-latest - compiler: gcc-11 - configure-args: --sprefix=zTest_ - - - name: macOS GCC Symbol Prefix & Compat - os: macOS-latest - compiler: gcc-11 - configure-args: --zlib-compat --sprefix=zTest_ - - - name: macOS GCC - os: macOS-latest - compiler: gcc-11 - configure-args: --warn - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Generate project files - run: | - mkdir ${{ matrix.build-dir || '.not-used' }} - cd ${{ matrix.build-dir || '.' }} - ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CHOST: ${{ matrix.chost }} - EMU_RUN: ${{ matrix.emu-run }} - CI: true - - - name: Compile source code - run: make -j2 - working-directory: ${{ matrix.build-dir }} - - - name: Run test cases - run: make test - working-directory: ${{ matrix.build-dir }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (configure) - path: | - **/Makefile - ${{ matrix.build-dir || '.' }}/configure.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml deleted file mode 100644 index 95d64e67a..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: OSS-Fuzz -on: - pull_request: - push: - branches: - - stable - - develop - - pre-release - - '2.*' - tags: - - '*' - -jobs: - fuzzing: - name: Fuzzing - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - dry-run: false - - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - fuzz-seconds: 600 - dry-run: false - - - name: Upload Crash - uses: actions/upload-artifact@v3 - if: failure() - with: - name: artifacts - path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml deleted file mode 100644 index c5fea574f..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Libpng -on: [push, pull_request] -jobs: - libpng: - name: Ubuntu Clang - runs-on: ubuntu-latest - steps: - - name: Checkout repository (zlib-ng) - uses: actions/checkout@v3 - - - name: Generate project files (zlib-ng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_COMPAT=ON \ - -DZLIB_ENABLE_TESTS=OFF - env: - CC: clang - CFLAGS: -fPIC - CI: true - - - name: Compile source code (zlib-ng) - run: cmake --build . -j2 --config Release - - - name: Checkout repository (libpng) - uses: actions/checkout@v3 - with: - repository: glennrp/libpng - path: libpng - - - name: Generate project files (libpng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DPNG_TESTS=ON \ - -DPNG_STATIC=OFF \ - -DZLIB_INCLUDE_DIR=.. \ - -DZLIB_LIBRARY=$PWD/../libz.a - working-directory: libpng - env: - CC: clang - CI: true - - - name: Compile source code (libpng) - run: cmake --build . -j2 --config Release - working-directory: libpng - - - name: Run test cases (libpng) - run: ctest -j2 -C Release --output-on-failure --max-width 120 - working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml deleted file mode 100644 index 5de669840..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Link -on: [push, pull_request] -jobs: - zlib: - name: Link zlib - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout zlib repository - uses: actions/checkout@v3 - with: - repository: madler/zlib - path: zlib - - - name: Generate project files (zlib) - run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF - - - name: Compile source code (zlib) - run: cmake --build zlib/build -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 - - zlib-ng-compat: - name: Link zlib-ng compat - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Generate project files (compat) - run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON - - - name: Compile source code (compat) - run: cmake --build compat -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib-ng compat (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml deleted file mode 100644 index 38e669093..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: NMake -on: [push, pull_request] -jobs: - nmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows NMake x86 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86 - - - name: Windows NMake x64 compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes - - - name: Windows NMake x64 Symbol Prefix - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 Symbol Prefix Compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - - - name: Windows NMake ARM No Test - os: windows-2022 - makefile: win32/Makefile.arm - arch: x86_arm - - - name: Windows NMake ARM64 No Test - os: windows-2022 - makefile: win32/Makefile.a64 - arch: x86_arm64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup development environment - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: ${{ matrix.arch }} - - - name: Compile source code - shell: cmd - run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} - - - name: Run test cases - shell: cmd - # Don't run tests on Windows ARM - if: contains(matrix.arch, 'arm') == false - run: | - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml deleted file mode 100644 index be4e1ce50..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Pigz -on: [push, pull_request] -jobs: - pigz: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz - - - name: Ubuntu Clang No Optim - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_optim - cmake-args: -DWITH_OPTIM=OFF - - # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 - - name: Ubuntu Clang No Threads - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_threads - cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_pigz_aarch64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Generate project files - run: | - cmake ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_ROOT=../.. \ - -DWITH_CODE_COVERAGE=ON \ - -DWITH_MAINTAINER_WARNINGS=ON - working-directory: test/pigz - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} - working-directory: test/pigz - - - name: Run test cases - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: test/pigz - - - name: Generate coverage report - if: matrix.codecov - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root . \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml deleted file mode 100644 index 8888cf37e..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Package Check -on: [push, pull_request] -jobs: - pkgcheck: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC -m32 - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - packages: gcc-multilib g++-multilib - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 - cflags: -m32 - cxxflags: -m32 - ldflags: -m32 - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - chost: arm-linux-gnueabihf - compiler: arm-linux-gnueabihf-gcc - cxx-compiler: g++-arm-linux-gnueabihf - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake - packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - chost: aarch64-linux-gnu - compiler: aarch64-linux-gnu-gcc - cxx-compiler: g++-aarch64-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake - packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - chost: powerpc-linux-gnu - compiler: powerpc-linux-gnu-gcc - cxx-compiler: g++-powerpc-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - chost: powerpc64le-linux-gnu - compiler: powerpc64le-linux-gnu-gcc - cxx-compiler: g++-powerpc64le-linux-gnu - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross - - - name: macOS Clang - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - - - name: macOS Clang Native - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON - configure-args: --native - - - name: macOS Clang Symbol Prefix - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - configure-args: --sprefix=zTest_ - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ - abigail-tools \ - diffoscope \ - ninja-build - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja diffoscope ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Select Xcode version (macOS) - # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports - # AppleClang linking with libtool using -D argument - # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 - if: runner.os == 'macOS' - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '11.7.0' - - - name: Compare builds - run: sh test/pkgcheck.sh - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Compare builds (compat) - run: sh test/pkgcheck.sh --zlib-compat - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI (compat) - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --zlib-compat --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} - path: | - **/*.abi - btmp1/configure.log - btmp1/CMakeFiles/CMakeOutput.log - btmp1/CMakeFiles/CMakeError.log - btmp2/configure.log - btmp2/CMakeFiles/CMakeOutput.log - btmp2/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml deleted file mode 100644 index b64933cc7..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Release -on: - push: - tags: - - '*' -jobs: - release: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows MSVC Win32 - os: windows-latest - compiler: cl - cmake-args: -A Win32 - deploy-name: win-x86 - - - name: Windows MSVC Win32 Compat - os: windows-latest - compiler: cl - cmake-args: -A Win32 -DZLIB_COMPAT=ON - deploy-name: win-x86-compat - - - name: Windows MSVC Win64 - os: windows-latest - compiler: cl - cmake-args: -A x64 - deploy-name: win-x86-64 - - - name: Windows MSVC Win64 Compat - os: windows-latest - compiler: cl - cmake-args: -A x64 -DZLIB_COMPAT=ON - deploy-name: win-x86-64-compat - - - name: Windows MSVC ARM - os: windows-latest - compiler: cl - cmake-args: -A ARM - deploy-name: win-arm - - - name: Windows MSVC ARM Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM -DZLIB_COMPAT=ON - deploy-name: win-arm-compat - - - name: Windows MSVC ARM64 - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - deploy-name: win-arm64 - - - name: Windows MSVC ARM64 Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM64 -DZLIB_COMPAT=ON - deploy-name: win-arm64-compat - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set environment variables - shell: bash - run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - - - name: Generate project files - shell: bash - run: | - cmake . ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DZLIB_ENABLE_TESTS=ON \ - -DCMAKE_INSTALL_PREFIX=out \ - -DINSTALL_UTILS=ON - env: - CC: ${{ matrix.compiler }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release --target install - - - name: Package release (Windows) - if: runner.os == 'Windows' - run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md - working-directory: out - - - name: Upload release (Windows) - uses: svenstaro/upload-release-action@v2 - if: runner.os == 'Windows' - with: - asset_name: zlib-ng-${{ matrix.deploy-name }}.zip - file: zlib-ng-${{ matrix.deploy-name }}.zip - tag: ${{env.tag}} - repo_token: ${{ secrets.GITHUB_TOKEN }} - overwrite: true - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore b/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore deleted file mode 100644 index cd4a9c3fe..000000000 --- a/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore +++ /dev/null @@ -1,97 +0,0 @@ -*.diff -*.patch -*.orig -*.rej - -*~ -*.a -*.lo -*.o -*.dylib - -*.gcda -*.gcno -*.gcov - -/benchmark_zlib -/example -/example64 -/examplesh -/gtest_zlib -/libz.so* -/libz-ng.so* -/makefixed -/minigzip -/minigzip64 -/minigzipsh -/switchlevels -/zlib.pc -/zlib-ng.pc - -.DS_Store -*_fuzzer -*.obj -*.exe -*.pdb -*.exp -*.lib -*.dll -*.res -foo.gz -*.manifest -*.opensdf -*.sln -*.sdf -*.vcxproj -*.vcxproj.filters -*.vcxproj.user -.vs - -CMakeCache.txt -CMakeFiles -Testing -/*.cmake -*.stackdump -*._h -zconf.h -zconf.h.cmakein -zconf.h.included -zconf-ng.h -zconf-ng.h.cmakein -ztest* -/test/CTestTestfile.cmake -/test/cmake_install.cmake - -configure.log -a.out - -/Makefile -/arch/arm/Makefile -/arch/generic/Makefile -/arch/power/Makefile -/arch/x86/Makefile -.kdev4 -*.kdev4 - -/Debug -/example.dir -/minigzip.dir -/zlib.dir -/zlibstatic.dir -/test/*.dir/ -/build/ -/build[.-]*/ -/btmp[12]/ -/pkgtmp[12]/ - -/.idea -/cmake-build-debug -/x64/Debug/ -/x64/Release/ -/win32/Debug/ -/win32/Release/ -/ARM*/Debug/ -/ARM*/Release/ -MinSizeRel -RelWithDebInfo -/_deps/googletest* diff --git a/internal-complibs/zlib-ng-2.1.2/.gitattributes b/internal-complibs/zlib-ng-2.1.2/.gitattributes deleted file mode 100644 index ac21ec459..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.gitattributes +++ /dev/null @@ -1,8 +0,0 @@ -* text=auto -*.abi text eol=lf -*.c text -*.h text -*.sh text eol=lf -crc32_braid_tbl.h hooks-max-size=1000000 -Makefile text -configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml deleted file mode 100644 index 7cd812915..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml +++ /dev/null @@ -1 +0,0 @@ -github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml deleted file mode 100644 index cbdea0e50..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml +++ /dev/null @@ -1,78 +0,0 @@ -name: Static Analysis -on: [push, pull_request] -jobs: - static-analysis: - name: GCC - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y gcc-10 - - - name: Generate project files - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CC: gcc-10 - CFLAGS: - -fanalyzer - -Werror - -Wanalyzer-double-fclose - -Wanalyzer-double-free - -Wanalyzer-exposure-through-output-file - -Wanalyzer-file-leak - -Wanalyzer-free-of-non-heap - -Wanalyzer-malloc-leak - -Wanalyzer-null-argument - -Wanalyzer-null-dereference - -Wanalyzer-possible-null-argument - -Wanalyzer-possible-null-dereference - -Wanalyzer-stale-setjmp-buffer - -Wanalyzer-tainted-array-index - -Wanalyzer-unsafe-call-within-signal-handler - -Wanalyzer-use-after-free - -Wanalyzer-use-of-pointer-in-stale-stack-frame - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release > /dev/null - - Clang: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install packages (Ubuntu) - run: sudo apt-get install -y clang-tools - - - name: Generate project files - run: | - scan-build --status-bugs \ - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DWITH_FUZZERS=OFF \ - -DWITH_CODE_COVERAGE=OFF \ - -DWITH_MAINTAINER_WARNINGS=OFF - env: - CI: true - - - name: Compile source code - run: | - scan-build --status-bugs \ - cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml deleted file mode 100644 index f16ab99c7..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml +++ /dev/null @@ -1,635 +0,0 @@ -name: CMake -on: [push, pull_request] -env: - TERM: xterm-256color - GTEST_COLOR: 1 -jobs: - cmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - timeout-minutes: 60 - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SANITIZER=Address - codecov: ubuntu_gcc - - - name: Ubuntu GCC Benchmark - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_BENCHMARKS=ON - codecov: ubuntu_gcc_benchmark - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_sprefix - - - name: Ubuntu GCC Compat Symbol Prefix - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ - codecov: ubuntu_gcc_compat_sprefix - - - name: Ubuntu GCC -O3 OSB - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng - codecov: ubuntu_gcc_osb - cflags: -O3 - - - name: Ubuntu GCC -O3 OSB add_subdirectory - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - build-dir: ../build - build-src-dir: ../zlib-ng/test/add-subdirectory-project - - - name: Ubuntu GCC -O1 No Unaligned UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_o1 - cflags: -O1 - - - name: Ubuntu GCC 32-bit - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 - packages: gcc-multilib g++-multilib - codecov: ubuntu_gcc_m32 - - - name: Ubuntu GCC No CTZLL - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF - codecov: ubuntu_gcc_no_ctzll - - - name: Ubuntu GCC No CTZ - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF - codecov: ubuntu_gcc_no_ctz - - - name: Ubuntu GCC No AVX2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_avx2 - - - name: Ubuntu GCC No SSE2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse2 - - - name: Ubuntu GCC No SSE4.2 UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_sse42 - - - name: Ubuntu GCC No PCLMULQDQ UBSAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined - codecov: ubuntu_gcc_no_pclmulqdq - - - name: Ubuntu GCC Compat No Opt ASAN - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address - codecov: ubuntu_gcc_compat_no_opt - cflags: -DNOT_TWEAK_COMPILER - - - name: Ubuntu GCC ARM SF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf - - - name: Ubuntu GCC ARM SF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross - codecov: ubuntu_gcc_armsf_compat_no_opt - - - name: Ubuntu GCC ARM HF ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf - - - name: Ubuntu GCC ARM HF No ACLE ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_acle - - - name: Ubuntu GCC ARM HF No NEON ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_no_neon - - - name: Ubuntu GCC ARM HF Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross - codecov: ubuntu_gcc_armhf_compat_no_opt - - - name: Ubuntu GCC AARCH64 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64 - - - name: Ubuntu GCC AARCH64 No ACLE UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_acle - - - name: Ubuntu GCC AARCH64 No NEON UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_no_neon - - - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined - packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_aarch64_compat_no_opt - - - name: Ubuntu GCC MIPS - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips.cmake - packages: qemu qemu-user gcc-mips-linux-gnu g++-mips-linux-gnu libc-dev-mips-cross - codecov: ubuntu_gcc_mips - - - name: Ubuntu GCC MIPS64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips64.cmake - packages: qemu qemu-user gcc-mips64-linux-gnuabi64 g++-mips64-linux-gnuabi64 libc-dev-mips64-cross - codecov: ubuntu_gcc_mips64 - - - name: Ubuntu GCC PPC - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF - packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross - codecov: ubuntu_gcc_ppc_no_power8 - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake - packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross - ldflags: -static - codecov: ubuntu_gcc_ppc64 - - - name: Ubuntu GCC PPC64LE - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross - codecov: ubuntu_gcc_ppc64le - - - name: Ubuntu GCC SPARC64 - os: ubuntu-20.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake - packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross - ldflags: -static - codecov: ubuntu_gcc_sparc64 - - - name: Ubuntu GCC S390X ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X No vectorized CRC32 ASAN - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross - ldflags: -static - codecov: ubuntu_gcc_s390x_no_crc32 - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC ASAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address - asan-options: detect_leaks=0 - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu GCC S390X DFLTCC Compat UBSAN - os: z15 - compiler: gcc - cxx-compiler: g++ - cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined - ldflags: -static - codecov: ubuntu_gcc_s390x_dfltcc_compat - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu Clang S390X DFLTCC MSAN - os: z15 - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory - # The dedicated test VM has 4 cores - parallels-jobs: 4 - - - name: Ubuntu MinGW i686 - os: ubuntu-22.04 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake - packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 libgcc-s1:i386 libstdc++6:i386 - ldflags: -static - codecov: ubuntu_gcc_mingw_i686 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu MinGW x86_64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake - packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 - ldflags: -static - codecov: ubuntu_gcc_mingw_x86_64 - # Limit parallel test jobs to prevent wine errors - parallels-jobs: 1 - - - name: Ubuntu 20.04 Clang - os: ubuntu-20.04 - compiler: clang-6.0 - cxx-compiler: clang++-6.0 - packages: clang-6.0 - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang - - # Check for undefined symbols in the version script for the modern api - - name: Ubuntu Clang Undefined Symbols - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF - build-shared: ON - packages: clang-11 llvm-11 lld - - # Check for undefined symbols in the version script for the compat api - - name: Ubuntu Clang Undefined Symbols Compat - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON - build-shared: ON - packages: clang-11 llvm-11 lld - - - name: Ubuntu Clang Inflate Strict - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_STRICT=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_strict - - - name: Ubuntu Clang Inflate Allow Invalid Dist - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_inflate_allow_invalid_dist - - - name: Ubuntu Clang Reduced Memory - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -DWITH_REDUCED_MEM=ON - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_reduced_mem - - - name: Ubuntu Clang Memory Map - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cflags: -DUSE_MMAP - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_mmap - - - name: Ubuntu Clang Debug - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - packages: clang-11 llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_debug - build-config: Debug - - - name: Ubuntu Clang MSAN - os: ubuntu-latest - compiler: clang-11 - cxx-compiler: clang++-11 - cmake-args: -GNinja -DWITH_SANITIZER=Memory - packages: ninja-build clang-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - # https://github.com/llvm/llvm-project/issues/55785 - msan-options: use_sigaltstack=0 - - - name: Ubuntu Clang RISC-V - os: ubuntu-latest - cmake-args: -GNinja -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake -DTOOLCHAIN_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-clang -DQEMU_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64 - packages: build-essential cmake ninja-build - codecov: ubuntu_clang_toolchain_riscv - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON - - - name: Windows MSVC 2022 v143 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 - - - name: Windows MSVC 2022 v143 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 - - - name: Windows MSVC 2022 v142 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 - - - name: Windows MSVC 2022 v142 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 - - - name: Windows MSVC 2022 v141 Win32 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 - - - name: Windows MSVC 2022 v141 Win64 - os: windows-latest - compiler: cl - cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 - - - name: Windows MSVC 2019 v140 Win32 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 - - - name: Windows MSVC 2019 v140 Win64 - os: windows-2019 - compiler: cl - cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 - - - name: Windows MSVC ARM No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM - - - name: Windows MSVC ARM64 No Test - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - - - name: Windows ClangCl Win32 - os: windows-latest - cmake-args: -T ClangCl -A Win32 - - - name: Windows ClangCl Win64 - os: windows-latest - cmake-args: -T ClangCl -A x64 - - - name: Windows GCC - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja - codecov: win64_gcc - - - name: Windows GCC Compat No Opt - os: windows-latest - compiler: gcc - cxx-compiler: g++ - cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF - codecov: win64_gcc_compat_no_opt - - - name: macOS Clang ASAN - os: macos-latest - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_SANITIZER=Address - codecov: macos_clang - - - name: macOS GCC UBSAN - os: macos-latest - compiler: gcc-10 - cxx-compiler: g++-10 - cmake-args: -DWITH_SANITIZER=Undefined - packages: gcc@10 - gcov-exec: gcov-10 - codecov: macos_gcc - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs - # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. - if: contains(matrix.name, 'MinGW') == false - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add repositories (Wine) - if: contains(matrix.packages, 'wine32') - run: sudo dpkg --add-architecture i386 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} - - - name: Download prebuilt RISC-V Clang toolchain & QEMU emulator - if: runner.os == 'Linux' && contains(matrix.name, 'RISC-V') - run: | - gh release download ubuntu20.04_llvm16.0.0_qemu7.0.0 --repo sifive/prepare-riscv-toolchain-qemu - tar zxvf prebuilt-riscv-toolchain-qemu.tar.gz - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - - name: Install packages (Windows) - if: runner.os == 'Windows' - run: | - # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. - # zlib-ng does not need perl, so simply remove it. - choco uninstall --no-progress strawberryperl - choco install --no-progress ninja ${{ matrix.packages }} - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Initialize Wine - # Prevent parallel test jobs from initializing Wine at the same time - if: contains(matrix.packages, 'wine') - run: wineboot --init - - - name: Compile LLVM C++ libraries (MSAN) - if: contains(matrix.name, 'MSAN') - run: | - git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 - cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ - -DCMAKE_BUILD_TYPE=Release \ - -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ - -DLLVM_USE_SANITIZER=MemoryWithOrigins \ - -DLLVM_LIBC_ENABLE_LINTING=OFF - cmake --build llvm-project/build -j2 -- cxx cxxabi - echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - - - name: Generate project files - shell: bash - # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources - run: | - cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ - -DWITH_FUZZERS=ON \ - -DWITH_MAINTAINER_WARNINGS=ON \ - ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} - - - name: Run test cases - # Don't run tests on Windows ARM - if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: ${{ matrix.build-dir || '.' }} - env: - ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 - UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 - - - name: Generate coverage report - if: matrix.codecov - shell: bash - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root ${{ matrix.build-src-dir || '.' }} \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - directory: ${{ matrix.build-src-dir || '.' }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml deleted file mode 100644 index 1cfa4d7fa..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: "CodeQL" - -on: - push: - branches: [ "develop" ] - pull_request: - branches: [ "develop" ] - schedule: - - cron: "27 17 * * 0" - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ cpp ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: ${{ matrix.language }} - queries: +security-and-quality - - - name: Autobuild - uses: github/codeql-action/autobuild@v2 - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml deleted file mode 100644 index 02a36005f..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml +++ /dev/null @@ -1,252 +0,0 @@ -name: Configure -on: [push, pull_request] -jobs: - configure: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - configure-args: --warn - - - name: Ubuntu 20.04 GCC - os: ubuntu-20.04 - compiler: gcc - configure-args: --warn - - - name: Ubuntu GCC OSB - os: ubuntu-latest - compiler: gcc - configure-args: --warn - build-dir: ../build - build-src-dir: ../zlib-ng - - - name: Ubuntu GCC Compat No Opt - os: ubuntu-latest - compiler: gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - - - name: Ubuntu GCC ARM SF - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM SF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabi-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabi - packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No ACLE - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-acle - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF No NEON - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --without-neon - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC ARM HF Compat No Opt - os: ubuntu-latest - compiler: arm-linux-gnueabihf-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: arm-linux-gnueabihf - packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No ACLE - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-acle - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 No NEON - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --without-neon - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC AARCH64 Compat No Opt - os: ubuntu-latest - compiler: aarch64-linux-gnu-gcc - configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies - chost: aarch64-linux-gnu - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - - - name: Ubuntu GCC MIPS - os: ubuntu-latest - compiler: mips-linux-gnu-gcc - configure-args: --warn - chost: mips-linux-gnu - packages: qemu qemu-user gcc-mips-linux-gnu libc-dev-mips-cross - - - name: Ubuntu GCC MIPS64 - os: ubuntu-latest - compiler: mips64-linux-gnuabi64-gcc - configure-args: --warn - chost: mips64-linux-gnuabi64 - packages: qemu qemu-user gcc-mips64-linux-gnuabi64 libc-dev-mips64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC No Power8 - os: ubuntu-latest - compiler: powerpc-linux-gnu-gcc - configure-args: --warn --without-power8 - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross - - - name: Ubuntu GCC PPC64 - os: ubuntu-latest - compiler: powerpc64-linux-gnu-gcc - configure-args: --warn --static - chost: powerpc-linux-gnu - packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - compiler: powerpc64le-linux-gnu-gcc - configure-args: --warn - chost: powerpc64le-linux-gnu - packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross - - - name: Ubuntu GCC S390X - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X No vectorized CRC32 - os: ubuntu-latest - compiler: s390x-linux-gnu-gcc - configure-args: --warn --static --without-crc32-vx - chost: s390x-linux-gnu - packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross - cflags: -static - ldflags: -static - - - name: Ubuntu GCC S390X DFLTCC - os: z15 - compiler: gcc - configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu GCC S390X DFLTCC Compat - os: z15 - compiler: gcc - configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate - - - name: Ubuntu Emscripten WASM32 - os: ubuntu-latest - chost: wasm32 - configure-args: --warn --zlib-compat --static - configure-prefix: emconfigure - cflags: -static - ldflags: -static - emu-run: node - - - name: macOS GCC Symbol Prefix - os: macOS-latest - compiler: gcc-11 - configure-args: --sprefix=zTest_ - - - name: macOS GCC Symbol Prefix & Compat - os: macOS-latest - compiler: gcc-11 - configure-args: --zlib-compat --sprefix=zTest_ - - - name: macOS GCC - os: macOS-latest - compiler: gcc-11 - configure-args: --warn - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Install Emscripten - if: contains(matrix.name, 'WASM32') - uses: mymindstorm/setup-emsdk@v12 - - - name: Generate project files - run: | - mkdir ${{ matrix.build-dir || '.not-used' }} - cd ${{ matrix.build-dir || '.' }} - ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CHOST: ${{ matrix.chost }} - EMU_RUN: ${{ matrix.emu-run }} - CI: true - - - name: Compile source code - run: make -j2 - working-directory: ${{ matrix.build-dir }} - - - name: Run test cases - run: make test - working-directory: ${{ matrix.build-dir }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (configure) - path: | - **/Makefile - ${{ matrix.build-dir || '.' }}/configure.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml deleted file mode 100644 index 95d64e67a..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: OSS-Fuzz -on: - pull_request: - push: - branches: - - stable - - develop - - pre-release - - '2.*' - tags: - - '*' - -jobs: - fuzzing: - name: Fuzzing - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - dry-run: false - - - name: Run Fuzzers - uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master - with: - oss-fuzz-project-name: 'zlib-ng' - fuzz-seconds: 600 - dry-run: false - - - name: Upload Crash - uses: actions/upload-artifact@v3 - if: failure() - with: - name: artifacts - path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml deleted file mode 100644 index c5fea574f..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Libpng -on: [push, pull_request] -jobs: - libpng: - name: Ubuntu Clang - runs-on: ubuntu-latest - steps: - - name: Checkout repository (zlib-ng) - uses: actions/checkout@v3 - - - name: Generate project files (zlib-ng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_COMPAT=ON \ - -DZLIB_ENABLE_TESTS=OFF - env: - CC: clang - CFLAGS: -fPIC - CI: true - - - name: Compile source code (zlib-ng) - run: cmake --build . -j2 --config Release - - - name: Checkout repository (libpng) - uses: actions/checkout@v3 - with: - repository: glennrp/libpng - path: libpng - - - name: Generate project files (libpng) - run: | - cmake . \ - -DCMAKE_BUILD_TYPE=Release \ - -DPNG_TESTS=ON \ - -DPNG_STATIC=OFF \ - -DZLIB_INCLUDE_DIR=.. \ - -DZLIB_LIBRARY=$PWD/../libz.a - working-directory: libpng - env: - CC: clang - CI: true - - - name: Compile source code (libpng) - run: cmake --build . -j2 --config Release - working-directory: libpng - - - name: Run test cases (libpng) - run: ctest -j2 -C Release --output-on-failure --max-width 120 - working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml deleted file mode 100644 index 5de669840..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: Link -on: [push, pull_request] -jobs: - zlib: - name: Link zlib - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout zlib repository - uses: actions/checkout@v3 - with: - repository: madler/zlib - path: zlib - - - name: Generate project files (zlib) - run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF - - - name: Compile source code (zlib) - run: cmake --build zlib/build -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 - - zlib-ng-compat: - name: Link zlib-ng compat - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Generate project files (compat) - run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON - - - name: Compile source code (compat) - run: cmake --build compat -j2 --config Release - - - name: Generate project files (native) - run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat - - - name: Compile source code (native) - run: cmake --build native -j2 --config Release - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: Link zlib-ng compat (CMake Logs) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml deleted file mode 100644 index 38e669093..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: NMake -on: [push, pull_request] -jobs: - nmake: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows NMake x86 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86 - - - name: Windows NMake x64 compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes - - - name: Windows NMake x64 Symbol Prefix - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 Symbol Prefix Compat - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ - - - name: Windows NMake x64 - os: windows-2022 - makefile: win32/Makefile.msc - arch: x86_amd64 - - - name: Windows NMake ARM No Test - os: windows-2022 - makefile: win32/Makefile.arm - arch: x86_arm - - - name: Windows NMake ARM64 No Test - os: windows-2022 - makefile: win32/Makefile.a64 - arch: x86_arm64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Setup development environment - uses: ilammy/msvc-dev-cmd@v1.12.1 - with: - arch: ${{ matrix.arch }} - - - name: Compile source code - shell: cmd - run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} - - - name: Run test cases - shell: cmd - # Don't run tests on Windows ARM - if: contains(matrix.arch, 'arm') == false - run: | - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test - nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml deleted file mode 100644 index be4e1ce50..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml +++ /dev/null @@ -1,131 +0,0 @@ -name: Pigz -on: [push, pull_request] -jobs: - pigz: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - - - name: Ubuntu GCC Symbol Prefix - os: ubuntu-latest - compiler: gcc - codecov: ubuntu_gcc_pigz - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - - - name: Ubuntu Clang - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz - - - name: Ubuntu Clang No Optim - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_optim - cmake-args: -DWITH_OPTIM=OFF - - # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 - - name: Ubuntu Clang No Threads - os: ubuntu-latest - compiler: clang - packages: llvm-11 llvm-11-tools - gcov-exec: llvm-cov-11 gcov - codecov: ubuntu_clang_pigz_no_threads - cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake - packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross - codecov: ubuntu_gcc_pigz_aarch64 - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Checkout test corpora - uses: actions/checkout@v3 - with: - repository: zlib-ng/corpora - path: test/data/corpora - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' && matrix.packages - run: | - sudo apt-get update - sudo apt-get install -y ${{ matrix.packages }} - - - name: Generate project files - run: | - cmake ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ - -DBUILD_SHARED_LIBS=OFF \ - -DZLIB_ROOT=../.. \ - -DWITH_CODE_COVERAGE=ON \ - -DWITH_MAINTAINER_WARNINGS=ON - working-directory: test/pigz - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - LDFLAGS: ${{ matrix.ldflags }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} - working-directory: test/pigz - - - name: Run test cases - run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} - working-directory: test/pigz - - - name: Generate coverage report - if: matrix.codecov - run: | - python3 -u -m pip install --user gcovr==5.0 - python3 -m gcovr -j 3 --verbose \ - --exclude-unreachable-branches \ - --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ - --root . \ - --xml --output coverage.xml - - - name: Upload coverage report - uses: codecov/codecov-action@v3 - if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') - with: - token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} - flags: ${{ matrix.codecov }} - name: ${{ matrix.name }} - verbose: true - fail_ci_if_error: true - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} (cmake) - path: | - **/CMakeFiles/CMakeOutput.log - **/CMakeFiles/CMakeError.log - **/Testing/Temporary/* - coverage.xml - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml deleted file mode 100644 index 4e07f021b..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml +++ /dev/null @@ -1,192 +0,0 @@ -name: Package Check -on: [push, pull_request] -jobs: - pkgcheck: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Ubuntu GCC - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - - - name: Ubuntu GCC -m32 - os: ubuntu-latest - compiler: gcc - cxx-compiler: g++ - packages: gcc-multilib g++-multilib - cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 - cflags: -m32 - cxxflags: -m32 - ldflags: -m32 - - - name: Ubuntu GCC ARM HF - os: ubuntu-latest - chost: arm-linux-gnueabihf - compiler: arm-linux-gnueabihf-gcc - cxx-compiler: arm-linux-gnueabihf-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake - packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross - - - name: Ubuntu GCC AARCH64 - os: ubuntu-latest - chost: aarch64-linux-gnu - compiler: aarch64-linux-gnu-gcc - cxx-compiler: aarch64-linux-gnu-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake - packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross - - - name: Ubuntu GCC MIPS - os: ubuntu-latest - chost: mips-linux-gnu - compiler: mips-linux-gnu-gcc - cxx-compiler: mips-linux-gnu-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips.cmake - packages: qemu gcc-mips-linux-gnu g++-mips-linux-gnu libc6-dev-mips-cross - - - name: Ubuntu GCC MIPS64 - os: ubuntu-latest - chost: mips64-linux-gnuabi64 - compiler: mips64-linux-gnuabi64-gcc - cxx-compiler: mips64-linux-gnuabi64-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips64.cmake - packages: qemu gcc-mips64-linux-gnuabi64 g++-mips64-linux-gnuabi64 libc6-dev-mips64-cross - - - name: Ubuntu GCC PPC - os: ubuntu-latest - chost: powerpc-linux-gnu - compiler: powerpc-linux-gnu-gcc - cxx-compiler: powerpc-linux-gnu-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake - packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross - - - name: Ubuntu GCC PPC64LE - os: ubuntu-latest - chost: powerpc64le-linux-gnu - compiler: powerpc64le-linux-gnu-gcc - cxx-compiler: powerpc64le-linux-gnu-g++ - cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake - packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross - - - name: macOS Clang - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - - - name: macOS Clang Native - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON - configure-args: --native - - - name: macOS Clang Symbol Prefix - os: macOS-11 - compiler: clang - cxx-compiler: clang++ - cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ - configure-args: --sprefix=zTest_ - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Add ubuntu mirrors - if: runner.os == 'Linux' && matrix.packages - run: | - # Github Actions caching proxy is at times unreliable - echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt - curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt - sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list - - - name: Install packages (Ubuntu) - if: runner.os == 'Linux' - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ - abigail-tools \ - diffoscope \ - ninja-build - - - name: Install packages (macOS) - if: runner.os == 'macOS' - run: brew install ninja diffoscope ${{ matrix.packages }} - env: - HOMEBREW_NO_INSTALL_CLEANUP: 1 - - - name: Select Xcode version (macOS) - # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports - # AppleClang linking with libtool using -D argument - # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 - if: runner.os == 'macOS' - uses: maxim-lobanov/setup-xcode@v1 - with: - xcode-version: '11.7.0' - - - name: Compare builds - run: sh test/pkgcheck.sh - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Compare builds (compat) - run: sh test/pkgcheck.sh --zlib-compat - env: - CC: ${{ matrix.compiler }} - CFLAGS: ${{ matrix.cflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Check ABI (compat) - # macOS runner does not contain abigail - if: runner.os != 'macOS' - run: sh test/abicheck.sh --zlib-compat --refresh-if - env: - CC: ${{ matrix.compiler }} - CXX: ${{ matrix.cxx-compiler }} - CFLAGS: ${{ matrix.cflags }} - CXXFLAGS: ${{ matrix.cxxflags }} - CHOST: ${{ matrix.chost }} - CMAKE_ARGS: ${{ matrix.cmake-args }} - CONFIGURE_ARGS: ${{ matrix.configure-args }} - LDFLAGS: ${{ matrix.ldflags }} - - - name: Upload build errors - uses: actions/upload-artifact@v3 - if: failure() - with: - name: ${{ matrix.name }} - path: | - **/*.abi - btmp1/configure.log - btmp1/CMakeFiles/CMakeOutput.log - btmp1/CMakeFiles/CMakeError.log - btmp2/configure.log - btmp2/CMakeFiles/CMakeOutput.log - btmp2/CMakeFiles/CMakeError.log - retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml deleted file mode 100644 index b64933cc7..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Release -on: - push: - tags: - - '*' -jobs: - release: - name: ${{ matrix.name }} - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - name: Windows MSVC Win32 - os: windows-latest - compiler: cl - cmake-args: -A Win32 - deploy-name: win-x86 - - - name: Windows MSVC Win32 Compat - os: windows-latest - compiler: cl - cmake-args: -A Win32 -DZLIB_COMPAT=ON - deploy-name: win-x86-compat - - - name: Windows MSVC Win64 - os: windows-latest - compiler: cl - cmake-args: -A x64 - deploy-name: win-x86-64 - - - name: Windows MSVC Win64 Compat - os: windows-latest - compiler: cl - cmake-args: -A x64 -DZLIB_COMPAT=ON - deploy-name: win-x86-64-compat - - - name: Windows MSVC ARM - os: windows-latest - compiler: cl - cmake-args: -A ARM - deploy-name: win-arm - - - name: Windows MSVC ARM Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM -DZLIB_COMPAT=ON - deploy-name: win-arm-compat - - - name: Windows MSVC ARM64 - os: windows-latest - compiler: cl - cmake-args: -A ARM64 - deploy-name: win-arm64 - - - name: Windows MSVC ARM64 Compat - os: windows-latest - compiler: cl - cmake-args: -A ARM64 -DZLIB_COMPAT=ON - deploy-name: win-arm64-compat - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Set environment variables - shell: bash - run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV - - - name: Generate project files - shell: bash - run: | - cmake . ${{ matrix.cmake-args }} \ - -DCMAKE_BUILD_TYPE=Release \ - -DZLIB_ENABLE_TESTS=ON \ - -DCMAKE_INSTALL_PREFIX=out \ - -DINSTALL_UTILS=ON - env: - CC: ${{ matrix.compiler }} - CI: true - - - name: Compile source code - run: cmake --build . -j2 --config Release --target install - - - name: Package release (Windows) - if: runner.os == 'Windows' - run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md - working-directory: out - - - name: Upload release (Windows) - uses: svenstaro/upload-release-action@v2 - if: runner.os == 'Windows' - with: - asset_name: zlib-ng-${{ matrix.deploy-name }}.zip - file: zlib-ng-${{ matrix.deploy-name }}.zip - tag: ${{env.tag}} - repo_token: ${{ secrets.GITHUB_TOKEN }} - overwrite: true - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.2/.gitignore b/internal-complibs/zlib-ng-2.1.2/.gitignore deleted file mode 100644 index cd4a9c3fe..000000000 --- a/internal-complibs/zlib-ng-2.1.2/.gitignore +++ /dev/null @@ -1,97 +0,0 @@ -*.diff -*.patch -*.orig -*.rej - -*~ -*.a -*.lo -*.o -*.dylib - -*.gcda -*.gcno -*.gcov - -/benchmark_zlib -/example -/example64 -/examplesh -/gtest_zlib -/libz.so* -/libz-ng.so* -/makefixed -/minigzip -/minigzip64 -/minigzipsh -/switchlevels -/zlib.pc -/zlib-ng.pc - -.DS_Store -*_fuzzer -*.obj -*.exe -*.pdb -*.exp -*.lib -*.dll -*.res -foo.gz -*.manifest -*.opensdf -*.sln -*.sdf -*.vcxproj -*.vcxproj.filters -*.vcxproj.user -.vs - -CMakeCache.txt -CMakeFiles -Testing -/*.cmake -*.stackdump -*._h -zconf.h -zconf.h.cmakein -zconf.h.included -zconf-ng.h -zconf-ng.h.cmakein -ztest* -/test/CTestTestfile.cmake -/test/cmake_install.cmake - -configure.log -a.out - -/Makefile -/arch/arm/Makefile -/arch/generic/Makefile -/arch/power/Makefile -/arch/x86/Makefile -.kdev4 -*.kdev4 - -/Debug -/example.dir -/minigzip.dir -/zlib.dir -/zlibstatic.dir -/test/*.dir/ -/build/ -/build[.-]*/ -/btmp[12]/ -/pkgtmp[12]/ - -/.idea -/cmake-build-debug -/x64/Debug/ -/x64/Release/ -/win32/Debug/ -/win32/Release/ -/ARM*/Debug/ -/ARM*/Release/ -MinSizeRel -RelWithDebInfo -/_deps/googletest* From 63ab292a1cf13a5b28a16cd78acdc667134795b9 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Fri, 6 Dec 2024 11:13:58 +0100 Subject: [PATCH 5/5] Experiment with zlib-ng versions --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8dee780f6..74cca645b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,7 +203,7 @@ if(NOT DEACTIVATE_ZLIB) message(STATUS "Using ZLIB-NG internal sources for ZLIB support.") set(HAVE_ZLIB_NG TRUE) add_definitions(-DZLIB_COMPAT) - set(ZLIB_NG_DIR "zlib-ng-2.0.7") # update to the actual included version + set(ZLIB_NG_DIR "zlib-ng-2.1.0-beta1") # update to the actual included version set(ZLIB_COMPAT TRUE) set(SKIP_INSTALL_ALL TRUE) set(BUILD_SHARED_LIBS FALSE)

  • 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℞AMkzQ=&V-bWaym-?9j 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%0ARD|WAUa-^)bZn# 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%0Dmda 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 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/test/Makefile.in new file mode 100644 index 000000000..d2658e7ce --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/Makefile.in @@ -0,0 +1,82 @@ +# Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler +# Copyright 2015, Daniel Axtens, IBM Corporation +# zlib license, see zlib.h + +CC= +CFLAGS= +EXE= +SRCDIR= +SRCTOP= +LIBNAME= +TEST_LDFLAGS=-L.. ../$(LIBNAME).a + +EMU_RUN= + +all: alltests + +alltests: #set by ../configure +check_cross_dep: +ifneq (,$(findstring qemu,$(EMU_RUN))) +QEMU_VER:=$(shell command -v $(EMU_RUN) --version 2> /dev/null) +ifeq (,$(QEMU_VER)) + $(error You need QEMU to run tests on non-native platform) +endif +endif + +ALL_SRC_FILES := $(wildcard ../*) + +teststatic: check_cross_dep + @TMPST=tmpst_$$$$; \ + HELLOST=tmphellost_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${EMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${EMU_RUN} ../example$(EXE) $$TMPST; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPST $$HELLOST + +testshared: check_cross_dep + @LD_LIBRARY_PATH=`pwd`/..:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`/..:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`/..:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`/..:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$$$; \ + HELLOSH=tmphellosh_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${EMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${EMU_RUN} ../examplesh$(EXE) $$TMPSH; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPSH $$HELLOSH + +.PHONY: ghtests +ghtests: testGH-361 testGH-364 testGH-751 testGH-1235 + +.PHONY: testGH-361 +testGH-361: + $(EMU_RUN) ../minigzip$(EXE) -4 <$(SRCDIR)/GH-361/test.txt >/dev/null + +switchlevels$(EXE): $(SRCDIR)/switchlevels.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-364 +testGH-364: switchlevels$(EXE) + $(EMU_RUN) ./switchlevels$(EXE) 1 5 9 3 <$(SRCDIR)/GH-364/test.bin >/dev/null + +.PHONY: testGH-751 +testGH-751: + $(EMU_RUN) ../minigzip$(EXE) <$(SRCDIR)/GH-751/test.txt | $(EMU_RUN) ../minigzip$(EXE) -d >/dev/null + +gh1235$(EXE): $(SRCDIR)/gh1235.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-1235 +testGH-1235: gh1235$(EXE) + $(EMU_RUN) ./gh1235$(EXE) + +clean: + rm -f *.o *.gcda *.gcno *.gcov + rm -f switchlevels$(EXE) gh1235$(EXE) + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/README.md b/internal-complibs/zlib-ng-2.1.1-beta2/test/README.md new file mode 100644 index 000000000..d844ba530 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/README.md @@ -0,0 +1,37 @@ +Contents +-------- + +|Name|Description| +|-|-| +|[CVE-2003-0107](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT| +|[CVE-2002-0059](https://nvd.nist.gov/vuln/detail/CVE-2002-0059)|inflateEnd to release memory more than once| +|[CVE-2004-0797](https://nvd.nist.gov/vuln/detail/CVE-2004-0797)|Error handling in inflate and inflateBack causes crash| +|[CVE-2005-1849](https://nvd.nist.gov/vuln/detail/CVE-2005-1849)|inftrees.h bug causes crash| +|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description| +|[CVE-2018-25032](https://nvd.nist.gov/vuln/detail/CVE-2018-25032)|Memory corruption when compressing if the input has many distant matches.| +|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches| +|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels| +|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick| + +Copying +------- + +Some of the files in _test_ are licensed differently: + + - test/data/fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and + is licensed under the Creative Commons Attribution 3.0 license + (CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/ + for more information. + + - test/data/paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper + “Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA + Replication Timing in _Drosophila_†by Federico Comoglio and Renato Paro, + which is licensed under the CC-BY license. See + https://www.ploscompbiol.org/static/license for more information. + + - test/data/lcet10.txt is from Project Gutenberg. It does not have expired + copyright, but is still in the public domain according to the license information. + (https://www.gutenberg.org/ebooks/53). + + - test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri + that reproduced GH-382. It is licensed under the terms of the zlib license. diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/ignore b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/ignore new file mode 100644 index 000000000..583c92184 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/ignore @@ -0,0 +1,12 @@ +# See https://sourceware.org/libabigail/manual/libabigail-concepts.html#suppression-specifications + +[suppress_type] + name = internal_state + +[suppress_type] + name_regexp = z_stream.* + +# Size varies with version number +[suppress_variable] + name_regexp = z(|ng|libng)_(|v)string + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..c9088b86f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..48f8fb6bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..cee35ca46 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3d7ca82c1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..ad037fd6a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..5ef350b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..569d084b9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..b2a63a4bd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi @@ -0,0 +1,1281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..cfc0eddc6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1904 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..414f8a96e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..f5b3aa773 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1881 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3164f07e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1895 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..1d97902bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..613f5f2f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1886 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..82d8943b8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,2032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..a03df554a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi @@ -0,0 +1,2064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.md b/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.md new file mode 100644 index 000000000..57337f588 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.md @@ -0,0 +1,59 @@ +ABI Compatibility test +---------------------- + +abicheck.sh uses libabigail to check ABI stability. +It will abort if the current source +tree has a change that breaks binary compatibility. + +This protects against the common scenario where: +- an app is compiled against the current zlib-ng +- the system package manager updates the zlib-ng shared library +- the app now crashes because some symbol is + missing or some public structure or parameter + has changed type or size + +If run with --zlib-compat, it verifies that the +current source tree generates a library that +is ABI-compatible with the reference release +of classic zlib. This ensures that building +zlib-ng with --zlib-compat does what it says on the tin. + +abicheck.sh is not perfect, but it can catch +many common compatibility issues. + +Cached files test/abi/*.abi +--------------------------- + +Comparing to the old version of zlib (or zlib-ng) +means someone has to check out and build +the previous source tree and extract its .abi +using abidw. This can be slow. + +If you don't mind the slowness, run abicheck.sh --refresh-if, +and it will download and build the reference version +and extract the .abi on the spot if needed. +(FIXME: should this be the default?) + +On the next run, the reference .abi file will already be +present, and that step will be skipped. +It's stored in the tests/abi directory, +in a file with the architecture and git hash in the name. + +If you're running continuous integration +which clear out the source tree on each run, +and you don't want your build machines +constantly downloading and building the old +version, you can check the .abi file into git. + +To make this easier, a helper script could be written to automatically build +all the configurations tested by .github/workflows/abicheck.yml +Then they could be checked into git en masse by a maintainer +when a new platform is added or a new major version (which +intentionally breaks backwards compatibility) is being prepared. + +Further reading +--------------- + +- https://sourceware.org/libabigail/manual/ +- https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/ +- https://developers.redhat.com/blog/2020/04/02/how-to-write-an-abi-compliance-checker-using-libabigail/ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.sh b/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.sh new file mode 100755 index 000000000..1656711f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/abicheck.sh @@ -0,0 +1,163 @@ +#!/bin/sh +set -ex +TESTDIR="$(cd $(dirname "$0"); pwd)" + +usage() { + cat <<_EOF_ +Usage: $0 [--zlib-compat][--refresh][--refresh-if] + +Build shared library with -ggdb, then compare its ABI to the stable +ABI, and abort if differences found. + +Options: +--zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng. +--refresh - build the reference library and extract its ABI rather than using a stored ABI file. +--refresh-if - refresh only if ABI file not present. + +Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS. + +Requires libabigail (on Ubuntu, install package abigail-tools). +_EOF_ +} + +# Print the multiarch tuple for the current (non-cross) machine, +# or the empty string if unavailable. +detect_chost() { + dpkg-architecture -qDEB_HOST_MULTIARCH || + $CC -print-multiarch || + $CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' || + true +} + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +suffix="-ng" +CONFIGURE_ARGS_NG="$CONFIGURE_ARGS" +refresh=false +refresh_if=false +for arg +do + case "$arg" in + --zlib-compat) + suffix="" + CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat" + ;; + --refresh) + refresh=true + ;; + --refresh-if) + refresh_if=true + ;; + --help) + usage + exit 0 + ;; + *) + echo "Unknown arg '$arg'" + usage + exit 1 + ;; + esac +done + +# Choose reference repo and commit +if test "$suffix" = "" +then + # Reference is zlib 1.2.13. + ABI_GIT_REPO=https://github.com/madler/zlib.git + ABI_GIT_COMMIT=04f42ceca40f73e2978b50e93806c2a18c1281fc +else + # Reference is most recent zlib-ng develop with zlib 1.2.12 compatible api. + ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git + ABI_GIT_COMMIT=e4614ebcb9b3e5b108dc983c155e4baf80882311 +fi + +# Test compat build for ABI compatibility with zlib +if test "$CHOST" = "" +then + # Note: don't export CHOST here, as we don't want configure seeing it + # when it's just the name for the build machine. + # Leave it as a plain shell variable, not an environment variable. + CHOST=$(detect_chost) + # Support -m32 for non-cross builds. + case "$CFLAGS" in + *-m32*) M32="-m32";; + *) M32="";; + esac +fi + +# Canonicalize CHOST to work around bug in original zlib's configure +# (Don't export it if it wasn't already exported, else may cause +# default compiler detection failure and shared library link error +# when building both zlib and zlib-ng. +# See https://github.com/zlib-ng/zlib-ng/issues/1219) +CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) + +if test "$CHOST" = "" +then + echo "abicheck: SKIP, as we don't know CHOST" + exit 0 +fi + +ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" +if ! $refresh && $refresh_if && ! test -f "$ABIFILE" +then + refresh=true +fi +abidw --version + +if $refresh +then + # Check out reference source + rm -rf btmp1 + mkdir -p btmp1/src.d + cd btmp1/src.d + git init + git remote add origin $ABI_GIT_REPO + git fetch origin $ABI_GIT_COMMIT + git reset --hard FETCH_HEAD + cd .. + # Build unstripped, uninstalled, very debug shared library + CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS + make -j2 + cd .. + # Find shared library, extract its abi + dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + abidw $dylib1 > "$ABIFILE" + # Maintainers may wish to check $ABIFILE into git when a new + # target is added, or when a major release happens that is + # intended to change the ABI. Alternately, this script could + # just always rebuild the reference source, and dispense with + # caching abi files in git (but that would slow builds down). +fi + +if ! test -f "$ABIFILE" +then + echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if" + exit 1 +fi + +# Build unstripped, uninstalled, very debug shared library +rm -rf btmp2 +mkdir btmp2 +cd btmp2 +CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG +make -j2 +cd .. +# Find shared library, extract its abi +dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) +abidw $dylib2 > btmp2/zlib${suffix}-built.abi + +# Compare it to the reference +# FIXME: use --no-added-syms for now, but we probably want to be more strict. +if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi +then + echo "abicheck: PASS" +else + echo "abicheck: FAIL" + exit 1 +fi diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/CMakeLists.txt new file mode 100644 index 000000000..1b87005f7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(zlib-ng-add-subdirecory-test C) + +include(CTest) + +set(BUILD_SHARED_LIBS OFF) +set(ZLIB_ENABLE_TESTS ON CACHE BOOL "Build test binaries" FORCE) + +add_subdirectory(../.. zlib-ng) + +add_executable(app main.c) +target_link_libraries(app zlibstatic) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/main.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/main.c new file mode 100644 index 000000000..638a35b1d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/add-subdirectory-project/main.c @@ -0,0 +1,7 @@ +#include +#include "zlib-ng.h" + +int main(void) { + printf("zlib-ng: %s\n", ZLIBNG_VERSION); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/CMakeLists.txt new file mode 100644 index 000000000..475fe07ce --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/CMakeLists.txt @@ -0,0 +1,109 @@ +cmake_minimum_required(VERSION 3.12) + +include(FetchContent) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) + +enable_language(CXX) + +# Search for Google benchmark package +find_package(benchmark QUIET) +if(NOT benchmark_FOUND) + # Fetch google benchmark source code from official repository + set(BENCHMARK_ENABLE_TESTING OFF) + + # Allow specifying alternative Google benchmark repository + if(NOT DEFINED GBENCHMARK_REPOSITORY) + set(GBENCHMARK_REPOSITORY https://github.com/google/benchmark.git) + endif() + if(NOT DEFINED GBENCHMARK_TAG) + set(GBENCHMARK_TAG v1.7.1) + endif() + + FetchContent_Declare(benchmark + GIT_REPOSITORY ${GBENCHMARK_REPOSITORY} + GIT_TAG ${GBENCHMARK_TAG}) + + FetchContent_GetProperties(benchmark) + if(NOT benchmark_POPULATED) + FetchContent_Populate(benchmark) + add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() +endif() + +add_executable(benchmark_zlib + benchmark_adler32.cc + benchmark_adler32_copy.cc + benchmark_compare256.cc + benchmark_compare256_rle.cc + benchmark_crc32.cc + benchmark_main.cc + benchmark_slidehash.cc + ) + +target_compile_definitions(benchmark_zlib PRIVATE -DBENCHMARK_STATIC_DEFINE) +target_include_directories(benchmark_zlib PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + +target_link_libraries(benchmark_zlib zlibstatic benchmark::benchmark) +if(WIN32) + target_link_libraries(benchmark_zlib shlwapi) +endif() + +if(ZLIB_ENABLE_TESTS) + add_test(NAME benchmark_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +if(WITH_BENCHMARK_APPS) + option(BUILD_ALT_BENCH "Link against alternative zlib implementation" OFF) + + # Search for libpng package + find_package(PNG QUIET) + + if(NOT PNG_FOUND) + FetchContent_Declare(PNG + GIT_REPOSITORY https://github.com/glennrp/libpng.git) + + FetchContent_GetProperties(PNG) + if(NOT PNG_POPULATED) + FetchContent_Populate(PNG) + add_subdirectory(${PNG_SOURCE_DIR} ${PNG_BINARY_DIR}) + endif() + endif() + + set(BENCH_APP_SRCS + benchmark_png_encode.cc + benchmark_png_decode.cc + benchmark_main.cc + ) + + add_executable(benchmark_zlib_apps ${BENCH_APP_SRCS}) + + if(DEFINED BUILD_ALT_BENCH) + set(ZLIB_ALT_LIB "libz.a" CACHE FILEPATH "Optional alternative zlib implementation (defaults to stock zlib)") + add_executable(benchmark_zlib_apps_alt ${BENCH_APP_SRCS}) + target_link_libraries(benchmark_zlib_apps_alt libpng.a ${ZLIB_ALT_LIB} benchmark::benchmark) + target_compile_definitions(benchmark_zlib_apps_alt PRIVATE BUILD_ALT=1) + target_include_directories(benchmark_zlib_apps_alt PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + endif() + + target_include_directories(benchmark_zlib_apps PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + + # We need the static png library if we're statically linking to zlib, + # otherwise it will resolve these things in the system provided dynamic + # libraries (likely linked to stock zlib) + target_link_libraries(benchmark_zlib_apps libpng.a zlibstatic benchmark::benchmark) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/README.md b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/README.md new file mode 100644 index 000000000..5dce7f51b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/README.md @@ -0,0 +1,47 @@ +## Benchmarks +These benchmarks are written using [Google Benchmark](https://github.com/google/benchmark). + +*Repetitions* + +To increase the number of times each benchmark iteration is run use: + +``` +--benchmark_repetitions=20 +``` + +*Filters* + +To filter out which benchmarks are performed use: + +``` +--benchmark_filter="adler32*" +``` + +There are two different benchmarks, micro and macro. + +### Benchmark benchmark_zlib +These are microbenchmarks intended to test lower level subfunctions of the library. + +Benchmarks include impelementations of: + - Adler32 + - CRC + - 256 byte comparisons + - SIMD accelerated "slide hash" routine + +By default these benchmarks report things on the nanosecond scale and are small enough +to measure very minute diferences. + +### Benchmark benchmark_zlib_apps +These benchmarks measure applications of zlib as a whole. Currently the only examples +are PNG encoding and decoding. The PNG encode and decode tests leveraging procedurally +generated and highly compressible image data. + +Additionally, a test called `png_decode_realistic` that will decode any RGB 8 BPP encoded +set of PNGs in the working directory under a directory named "test_pngs" with files named +{0..1}.png. If these images do not exist, they will error out and the benchmark will move +on to the next set of benchmarks. + +*benchmark_zlib_apps_alt* + +The user can compile a comparison benchmark application linking to any zlib-compatible +implementation of his or her choosing. diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32.cc new file mode 100644 index 000000000..5b0b65d67 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32.cc @@ -0,0 +1,89 @@ +/* benchmark_adler32.cc -- benchmark adler32 variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class adler32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_func adler32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_ADLER32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32, name)->Range(2048, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32(c, adler32_c, 1); + +#ifdef ARM_NEON +BENCHMARK_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +BENCHMARK_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +BENCHMARK_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSSE3 +BENCHMARK_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32_copy.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32_copy.cc new file mode 100644 index 000000000..cbee780b7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_adler32_copy.cc @@ -0,0 +1,118 @@ +/* benchmark_adler32_copy.cc -- benchmark adler32 (elided copy) variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +typedef uint32_t (*adler32_cpy_func)(uint32_t adler, unsigned char *dst, const uint8_t *buf, size_t len); + +class adler32_copy: public benchmark::Fixture { +private: + uint32_t *random_ints_src; + uint32_t *random_ints_dst; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints_src = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + random_ints_dst = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints_src != NULL); + assert(random_ints_dst != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints_src[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_cpy_func adler32_func) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32_func(hash, (unsigned char *)random_ints_dst, + (const unsigned char*)random_ints_src, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints_src); + zng_free(random_ints_dst); + } +}; + +#define BENCHMARK_ADLER32_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +#define BENCHMARK_ADLER32_BASELINE_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, [](uint32_t init_sum, unsigned char *dst, \ + const uint8_t *buf, size_t len) -> uint32_t { \ + memcpy(dst, buf, (size_t)len); \ + return fptr(init_sum, buf, len); \ + }); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32_BASELINE_COPY(c, adler32_c, 1); + +#ifdef ARM_NEON +/* If we inline this copy for neon, the function would go here */ +//BENCHMARK_ADLER32_COPY(neon, adler32_neon, test_cpu_features.arm.has_neon); +BENCHMARK_ADLER32_BASELINE_COPY(neon_copy_baseline, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +//BENCHMARK_ADLER32_COPY(vmx_inline_copy, adler32_fold_copy_vmx, test_cpu_features.power.has_altivec); +BENCHMARK_ADLER32_BASELINE_COPY(vmx_copy_baseline, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +//BENCHMARK_ADLER32_COPY(power8_inline_copy, adler32_fold_copy_power8, test_cpu_features.power.has_arch_2_07); +BENCHMARK_ADLER32_BASELINE_COPY(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSE42 +BENCHMARK_ADLER32_BASELINE_COPY(sse42_baseline, adler32_ssse3, test_cpu_features.x86.has_ssse3); +BENCHMARK_ADLER32_COPY(sse42, adler32_fold_copy_sse42, test_cpu_features.x86.has_sse42); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32_BASELINE_COPY(avx2_baseline, adler32_avx2, test_cpu_features.x86.has_avx2); +BENCHMARK_ADLER32_COPY(avx2, adler32_fold_copy_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, test_cpu_features.x86.has_avx512); +BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32_BASELINE_COPY(avx512_vnni_baseline, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +BENCHMARK_ADLER32_COPY(avx512_vnni, adler32_fold_copy_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256.cc new file mode 100644 index 000000000..3ab04d202 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256.cc @@ -0,0 +1,84 @@ +/* benchmark_compare256.cc -- benchmark compare256 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_COMPARE_SIZE (256) + +class compare256: public benchmark::Fixture { +private: + uint8_t *str1; + uint8_t *str2; + +public: + void SetUp(const ::benchmark::State& state) { + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + } + + void Bench(benchmark::State& state, compare256_func compare256) { + int32_t match_len = (int32_t)state.range(0) - 1; + uint32_t len = 0; + + str2[match_len] = 0; + for (auto _ : state) { + len = compare256((const uint8_t *)str1, (const uint8_t *)str2); + } + str2[match_len] = 'a'; + + benchmark::DoNotOptimize(len); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(str1); + zng_free(str2); + } +}; + +#define BENCHMARK_COMPARE256(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(compare256, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(compare256, name)->Range(1, MAX_COMPARE_SIZE); + +BENCHMARK_COMPARE256(c, compare256_c, 1); + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +BENCHMARK_COMPARE256(unaligned_16, compare256_unaligned_16, 1); +#ifdef HAVE_BUILTIN_CTZ +BENCHMARK_COMPARE256(unaligned_32, compare256_unaligned_32, 1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(unaligned_64, compare256_unaligned_64, 1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER9 +BENCHMARK_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00); +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256_rle.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256_rle.cc new file mode 100644 index 000000000..5a8afd694 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_compare256_rle.cc @@ -0,0 +1,73 @@ +/* benchmark_compare256_rle.cc -- benchmark compare256_rle variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "compare256_rle.h" +# include "cpu_features.h" +} + +#define MAX_COMPARE_SIZE (256) + +class compare256_rle: public benchmark::Fixture { +private: + uint8_t *str1; + uint8_t *str2; + +public: + void SetUp(const ::benchmark::State& state) { + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + } + + void Bench(benchmark::State& state, compare256_rle_func compare256_rle) { + int32_t match_len = (int32_t)state.range(0); + uint32_t len; + + str2[match_len] = 0; + for (auto _ : state) { + len = compare256_rle((const uint8_t *)str1, (const uint8_t *)str2); + } + str2[match_len] = 'a'; + + benchmark::DoNotOptimize(len); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(str1); + zng_free(str2); + } +}; + +#define BENCHMARK_COMPARE256_RLE(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(compare256_rle, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(compare256_rle, name)->Range(1, MAX_COMPARE_SIZE); + +BENCHMARK_COMPARE256_RLE(c, compare256_rle_c, 1); + +#ifdef UNALIGNED_OK +BENCHMARK_COMPARE256_RLE(unaligned_16, compare256_rle_unaligned_16, 1); +#ifdef HAVE_BUILTIN_CTZ +BENCHMARK_COMPARE256_RLE(unaligned_32, compare256_rle_unaligned_32, 1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256_RLE(unaligned_64, compare256_rle_unaligned_64, 1); +#endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_crc32.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_crc32.cc new file mode 100644 index 000000000..b2b9673d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_crc32.cc @@ -0,0 +1,69 @@ +/* benchmark_crc32.cc -- benchmark crc32 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class crc32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, crc32_func crc32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = crc32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_CRC32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(crc32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(crc32, name)->Range(1, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_CRC32(braid, PREFIX(crc32_braid), 1); + +#ifdef ARM_ACLE +BENCHMARK_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32); +#elif defined(POWER8_VSX) +BENCHMARK_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07); +#elif defined(S390_CRC32_VX) +BENCHMARK_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx); +#elif defined(X86_PCLMULQDQ_CRC) +/* CRC32 fold does a memory copy while hashing */ +BENCHMARK_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq); +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_main.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_main.cc new file mode 100644 index 000000000..3ef2c5e87 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_main.cc @@ -0,0 +1,28 @@ +/* benchmark_main.cc -- benchmark suite main entry point + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +#ifndef BUILD_ALT +extern "C" { +# include "zbuild.h" +# include "../test_cpu_features.h" + + struct cpu_features test_cpu_features; +} +#endif + +int main(int argc, char** argv) { +#ifndef BUILD_ALT + cpu_check_features(&test_cpu_features); +#endif + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + + return EXIT_SUCCESS; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_decode.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_decode.cc new file mode 100644 index 000000000..c037976c8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_decode.cc @@ -0,0 +1,126 @@ +#include +#include +#include "benchmark_png_shared.h" +#include + +class png_decode: public benchmark::Fixture { +protected: + png_dat inpng[10]; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *output_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width*height); + } + + void SetUp(const ::benchmark::State& state) { + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + assert(output_img_buf != NULL); + init_img(output_img_buf, IMWIDTH, IMHEIGHT); + + /* First we need to author the png bytes to be decoded */ + for (int i = 0; i < 10; ++i) { + inpng[i] = {NULL, 0, 0}; + encode_png(output_img_buf, &inpng[i], i, IMWIDTH, IMHEIGHT); + } + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + int compress_lvl = state.range(0); + png_parse_dat in = { inpng[compress_lvl].buf }; + uint32_t width, height; + decode_png(&in, (png_bytepp)&output_img_buf, IMWIDTH * IMHEIGHT * 3, width, height); + } + } + + void TearDown(const ::benchmark::State &state) { + free(output_img_buf); + for (int i = 0; i < 10; ++i) { + free(inpng[i].buf); + } + } +}; + +class png_decode_realistic: public png_decode { +private: + bool test_files_found = false; + +public: + void SetUp(const ::benchmark::State &state) { + output_img_buf = NULL; + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Let's take all the images at different compression levels and jam their bytes into buffers */ + char test_fname[25]; + FILE *files[10]; + + /* Set all to NULL */ + memset(files, 0, sizeof(FILE*)); + + for (size_t i = 0; i < 10; ++i) { + sprintf(test_fname, "test_pngs/%1lu.png", i); + FILE *in_img = fopen(test_fname, "r"); + if (in_img == NULL) { + for (size_t j = 0; j < i; ++j) { + if (files[j]) + fclose(files[j]); + } + + /* For proper cleanup */ + for (size_t j = i; j < 10; ++j) { + inpng[i] = { NULL, 0, 0 }; + } + + return; + } + files[i] = in_img; + } + + test_files_found = true; + /* Now that we've established we have all the png files, let's read all of their bytes into buffers */ + for (size_t i = 0; i < 10; ++i) { + FILE *in_file = files[i]; + fseek(in_file, 0, SEEK_END); + size_t num_bytes = ftell(in_file); + rewind(in_file); + + uint8_t *raw_file = (uint8_t*)malloc(num_bytes); + if (raw_file == NULL) + abort(); + + inpng[i].buf = raw_file; + inpng[i].len = num_bytes; + inpng[i].buf_rem = 0; + + size_t bytes_read = fread(raw_file, 1, num_bytes, in_file); + if (bytes_read != num_bytes) { + fprintf(stderr, "couldn't read all of the bytes for file test_pngs/%lu.png", i); + abort(); + } + + fclose(in_file); + } + } + + void Bench(benchmark::State &state) { + if (!test_files_found) { + state.SkipWithError("Test imagery in test_pngs not found"); + } + + png_decode::Bench(state); + } +}; + +BENCHMARK_DEFINE_F(png_decode, png_decode)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode, png_decode)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); + +BENCHMARK_DEFINE_F(png_decode_realistic, png_decode_realistic)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode_realistic, png_decode_realistic)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_encode.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_encode.cc new file mode 100644 index 000000000..f1c597d36 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_encode.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include "benchmark_png_shared.h" + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +class png_encode: public benchmark::Fixture { +private: + png_dat outpng; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *input_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width * height); + } + + void SetUp(const ::benchmark::State& state) { + input_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + outpng.buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Using malloc rather than zng_alloc so that we can call realloc. + * IMWIDTH * IMHEIGHT is likely to be more than enough bytes, though, + * given that a simple run length encoding already pretty much can + * reduce to this */ + outpng.len = 0; + outpng.buf_rem = IMWIDTH * IMHEIGHT * 3; + assert(input_img_buf != NULL); + assert(outpng.buf != NULL); + init_img(input_img_buf, IMWIDTH, IMHEIGHT); + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + encode_png((png_bytep)input_img_buf, &outpng, state.range(0), IMWIDTH, IMHEIGHT); + outpng.buf_rem = outpng.len; + outpng.len = 0; + } + } + + void TearDown(const ::benchmark::State &state) { + free(input_img_buf); + free(outpng.buf); + } +}; + +BENCHMARK_DEFINE_F(png_encode, encode_compressible)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_encode, encode_compressible)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_shared.h b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_shared.h new file mode 100644 index 000000000..926b4d964 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_png_shared.h @@ -0,0 +1,146 @@ +#pragma once + +#include +#include +#include + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +extern "C" { +# include +} + +typedef struct _png_dat { + uint8_t *buf; + int64_t len; + size_t buf_rem; +} png_dat; + +typedef struct _png_parse_dat { + uint8_t *cur_pos; +} png_parse_dat; + +/* Write a customized write callback so that we write back to an in-memory buffer. + * This allows the testing to not involve disk IO */ +static void png_write_cb(png_structp pngp, png_bytep data, png_size_t len) { + png_dat *dat = (png_dat*)png_get_io_ptr(pngp); + size_t curSize = dat->len + len; + + /* realloc double the requested buffer size to prevent excessive reallocs */ + if (dat->buf_rem < len) { + dat->buf = (uint8_t*)realloc(dat->buf, dat->len + dat->buf_rem + 2 * len); + + if (!dat->buf) { + /* Pretty unlikely but we'll put it here just in case */ + fprintf(stderr, "realloc failed, exiting\n"); + exit(1); + } + + dat->buf_rem += 2 * len; + } + + memcpy(dat->buf + dat->len, data, len); + dat->len = curSize; + dat->buf_rem -= len; +} + +static void init_compressible(png_bytep buf, size_t num_pix) { + /* It doesn't actually matter what we make this, but for + * the sake of a reasonable test image, let's make this + * be a stripe of R, G, & B, with no alpha channel */ + int32_t i = 0; + int32_t red_stop = num_pix / 3; + int32_t blue_stop = 2 * num_pix / 3; + int32_t green_stop = num_pix; + + for (int32_t x = 0; i < red_stop; x += 3, ++i) { + buf[x] = 255; + buf[x + 1] = 0; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < blue_stop; x+= 3, ++i) { + buf[x] = 0; + buf[x + 1] = 255; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < green_stop; x += 3, ++i) { + buf[x] = 0; + buf[x + 1] = 0; + buf[x + 2] = 255; + } +} + +static inline void encode_png(png_bytep buf, png_dat *outpng, int32_t comp_level, uint32_t width, uint32_t height) { + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + /* Most of this error handling is _likely_ not necessary. Likewise it's likely + * a lot of this stuff can be done in the setup function to avoid measuring this + * fixed setup time, but for now we'll do it here */ + if (!png) abort(); + + png_infop info = png_create_info_struct(png); + if (!info) abort(); + + png_set_write_fn(png, outpng, png_write_cb, NULL); + png_bytep *png_row_ptrs = new png_bytep[height]; + for (int i = 0; i < IMHEIGHT; ++i) { + png_row_ptrs[i] = (png_bytep)&buf[3*i*width]; + } + + png_set_IHDR(png, info, IMWIDTH, IMHEIGHT, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png, info); + png_set_compression_level(png, comp_level); + png_set_filter(png, 0, PNG_FILTER_NONE); + png_write_image(png, (png_bytepp)png_row_ptrs); + png_write_end(png, NULL); + png_destroy_write_struct(&png, &info); + delete[] png_row_ptrs; +} + +static void read_from_pngdat(png_structp png, png_bytep out, png_size_t bytes_to_read) { + png_parse_dat *io = (png_parse_dat*)png_get_io_ptr(png); + memcpy(out, io->cur_pos, bytes_to_read); + io->cur_pos += bytes_to_read; +} + +static inline int decode_png(png_parse_dat *dat, png_bytepp out_bytes, size_t in_size, uint32_t &width, uint32_t &height) { + png_structp png = NULL; + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png) abort(); + png_infop info = NULL; + info = png_create_info_struct(png); + if (!info) abort(); + + png_set_read_fn(png, dat, read_from_pngdat); + png_read_info(png, info); + + int bit_depth = 0, color_type = -1; + png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + + size_t im_size = width * height * bit_depth/8 * 3; + if (color_type != PNG_COLOR_TYPE_RGB) { + fprintf(stderr, "expected an 8 bpp RGB image\n"); + abort(); + } + + if (im_size > in_size) { + *out_bytes = (png_bytep)realloc(*out_bytes, im_size); + } + + png_bytep *out_rows = new png_bytep[height]; + for (size_t i = 0; i < height; ++i) + out_rows[i] = *out_bytes + (width*i*3); + + png_read_rows(png, out_rows, NULL, height); + png_destroy_read_struct(&png, &info, NULL); + delete[] out_rows; + + return im_size; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_slidehash.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_slidehash.cc new file mode 100644 index 000000000..238cc1f65 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/benchmarks/benchmark_slidehash.cc @@ -0,0 +1,86 @@ +/* benchmark_slidehash.cc -- benchmark slide_hash variants + * Copyright (C) 2022 Adam Stylinski, Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "deflate.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS 32768 + +class slide_hash: public benchmark::Fixture { +private: + uint16_t *l0; + uint16_t *l1; + deflate_state *s_g; + +public: + void SetUp(const ::benchmark::State& state) { + l0 = (uint16_t *)zng_alloc(HASH_SIZE * sizeof(uint16_t)); + + for (uint32_t i = 0; i < HASH_SIZE; i++) { + l0[i] = rand(); + } + + l1 = (uint16_t *)zng_alloc(MAX_RANDOM_INTS * sizeof(uint16_t)); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + l1[i] = rand(); + } + + deflate_state *s = (deflate_state*)malloc(sizeof(deflate_state)); + s->head = l0; + s->prev = l1; + s_g = s; + } + + void Bench(benchmark::State& state, slide_hash_func slide_hash) { + s_g->w_size = (uint32_t)state.range(0); + + for (auto _ : state) { + slide_hash(s_g); + benchmark::DoNotOptimize(s_g); + } + } + + void TearDown(const ::benchmark::State& state) { + zng_free(l0); + zng_free(l1); + } +}; + +#define BENCHMARK_SLIDEHASH(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(slide_hash, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(slide_hash, name)->RangeMultiplier(2)->Range(1024, MAX_RANDOM_INTS); + +BENCHMARK_SLIDEHASH(c, slide_hash_c, 1); + +#ifdef ARM_NEON +BENCHMARK_SLIDEHASH(neon, slide_hash_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER8_VSX +BENCHMARK_SLIDEHASH(power8, slide_hash_power8, test_cpu_features.power.has_arch_2_07); +#endif +#ifdef PPC_VMX +BENCHMARK_SLIDEHASH(vmx, slide_hash_vmx, test_cpu_features.power.has_altivec); +#endif + +#ifdef X86_SSE2 +BENCHMARK_SLIDEHASH(sse2, slide_hash_sse2, test_cpu_features.x86.has_sse2); +#endif +#ifdef X86_AVX2 +BENCHMARK_SLIDEHASH(avx2, slide_hash_avx2, test_cpu_features.x86.has_avx2); +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/compress-and-verify.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/compress-and-verify.cmake new file mode 100644 index 000000000..fa6977390 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/compress-and-verify.cmake @@ -0,0 +1,286 @@ +# compress-and-verify.cmake -- Runs a test against an input file to make sure that the specified +# targets are able to to compress and then decompress successfully. Optionally verify +# the results with gzip. Output files are generated with unique names to prevent parallel +# tests from corrupting one another. Default target arguments are compatible with minigzip. + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# that test a specific input file for compression or decompression. + +# Required Variables +# INPUT - Input file to test +# TARGET or - Command to run for both compress and decompress +# COMPRESS_TARGET and - Command to run to compress input file +# DECOMPRESS_TARGET - Command to run to decompress output file + +# Optional Variables +# TEST_NAME - Name of test to use when constructing output file paths +# COMPRESS_ARGS - Arguments to pass for compress command (default: -c -k) +# DECOMPRESS_ARGS - Arguments to pass to decompress command (default: -d -c) + +# GZIP_VERIFY - Verify that gzip can decompress the COMPRESS_TARGET output and +# verify that DECOMPRESS_TARGET can decompress gzip output of INPUT +# COMPARE - Verify decompressed output is the same as input +# FILEMODE - Pass data to/from (de)compressor using files instead of stdin/stdout +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +if(TARGET) + set(COMPRESS_TARGET ${TARGET}) + set(DECOMPRESS_TARGET ${TARGET}) +endif() + +if(NOT DEFINED INPUT OR NOT DEFINED COMPRESS_TARGET OR NOT DEFINED DECOMPRESS_TARGET) + message(FATAL_ERROR "Compress test arguments missing") +endif() + +# Set default values +if(NOT DEFINED COMPARE) + set(COMPARE ON) +endif() +if(NOT DEFINED FILEMODE) + set(FILEMODE OFF) +endif() +if(NOT DEFINED COMPRESS_ARGS) + set(COMPRESS_ARGS -3 -k) + if(NOT FILEMODE) + list(APPEND COMPRESS_ARGS -c) + endif() +endif() +if(NOT DEFINED DECOMPRESS_ARGS) + set(DECOMPRESS_ARGS -d -k) + if(NOT FILEMODE) + list(APPEND DECOMPRESS_ARGS -c) + endif() +endif() +if(NOT DEFINED GZIP_VERIFY) + set(GZIP_VERIFY ON) +endif() +if(NOT DEFINED SUCCESS_EXIT) + set(SUCCESS_EXIT 0) +endif() + +# Use test name from input file name +if(NOT DEFINED TEST_NAME) + get_filename_component(TEST_NAME "${INPUT}" NAME) +endif() + +# Generate unique output path so multiple tests can be executed at the same time +string(RANDOM LENGTH 6 UNIQUE_ID) +string(REPLACE "." "-" TEST_NAME "${TEST_NAME}") +set(OUTPUT_BASE "${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${TEST_NAME}-${UNIQUE_ID}") + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT_BASE}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +# Cleanup temporary files +macro(cleanup_always) + file(GLOB TEMP_FILES ${OUTPUT_BASE}*) + file(REMOVE ${TEMP_FILES}) +endmacro() +# Clean up temporary files if not on CI +macro(cleanup) + if(NOT DEFINED ENV{CI}) + cleanup_always() + endif() +endmacro() + +# Show differences between two files +macro(diff src1 src2) + find_program(XXD xxd) + if(XXD) + find_program(DIFF diff) + if(DIFF) + set(XXD_COMMAND ${XXD} ${src1} ${src1}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + set(XXD_COMMAND ${XXD} ${src2} ${src2}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + + set(DIFF_COMMAND ${DIFF} -u ${src1}.hex ${src2}.hex) + execute_process(COMMAND ${DIFF_COMMAND} + OUTPUT_FILE ${src2}.diff) + + file(READ ${src2}.diff DIFF_OUTPUT) + message(STATUS "Diff:\n${DIFF_OUTPUT}") + + if(NOT DEFINED ENV{CI}) + file(REMOVE ${src1}.hex ${src2}.hex ${src2}.diff) + endif() + endif() + endif() +endmacro() + + +macro(exec_streams tcmd tsrc tdst) + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${tcmd}" + -DINPUT=${tsrc} + -DOUTPUT=${tdst} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT + COMMAND_ECHO STDOUT) +endmacro() + +macro(exec_files tcmd tsrc) + execute_process(COMMAND + ${tcmd} ${tsrc} + RESULT_VARIABLE CMD_RESULT + COMMAND_ECHO STDOUT) +endmacro() + +# Compress input file +if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find compress input: ${INPUT}") +endif() + +set(COMPRESS_COMMAND ${COMPRESS_TARGET} ${COMPRESS_ARGS}) + +set(INPUT_FILE ${OUTPUT_BASE}) + +# Make CMake copy and rename file in one operation +configure_file(${INPUT} ${INPUT_FILE} COPYONLY) + +message(STATUS "Compress ${COMPRESS_COMMAND}") +message(STATUS " Source file: ${INPUT}") +message(STATUS " Compression input file: ${INPUT_FILE}") +message(STATUS " Output: ${OUTPUT_BASE}.gz") + +if(FILEMODE) + exec_files("${COMPRESS_COMMAND}" "${INPUT_FILE}") +else() + exec_streams("${COMPRESS_COMMAND}" "${INPUT_FILE}" "${OUTPUT_BASE}.gz") +endif() + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Compress failed: ${CMD_RESULT}") +endif() + +# Decompress output +if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress input: ${OUTPUT_BASE}.gz") +endif() + +set(DECOMPRESS_COMMAND ${DECOMPRESS_TARGET} ${DECOMPRESS_ARGS}) + +message(STATUS "Decompress ${DECOMPRESS_COMMAND}") +message(STATUS " Input: ${OUTPUT_BASE}.gz") +message(STATUS " Output: ${OUTPUT_BASE}") + +if(FILEMODE) + exec_files("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz") +else() + exec_streams("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz" "${OUTPUT_BASE}") +endif() + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress failed: ${CMD_RESULT}") +endif() + +if(COMPARE) + message(STATUS "Diff comparison") + message(STATUS " Input: ${INPUT}") + message(STATUS " Output: ${OUTPUT_BASE}") + + # Compare decompressed output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE} + RESULT_VARIABLE CMD_RESULT + COMMAND_ECHO STDOUT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}) + cleanup() + message(FATAL_ERROR "Compare decompress failed: ${CMD_RESULT}") + endif() +endif() + +if(GZIP_VERIFY AND NOT "${COMPRESS_ARGS}" MATCHES "-T") + # Transparent writing does not use gzip format + find_program(GZIP gzip) + if(GZIP) + if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find gzip decompress input: ${OUTPUT_BASE}.gz") + endif() + + # Check gzip can decompress our compressed output + set(GZ_DECOMPRESS_COMMAND ${GZIP} -d) + + message(STATUS "Gzip decompress ${GZ_DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}.gz") + message(STATUS " Output: ${OUTPUT_BASE}-ungzip") + + exec_streams("${GZ_DECOMPRESS_COMMAND}" "${OUTPUT_BASE}.gz" "${OUTPUT_BASE}-ungzip") + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compare gzip output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-ungzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-ungzip) + cleanup() + message(FATAL_ERROR "Compare gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compress input file with gzip + set(GZ_COMPRESS_COMMAND ${GZIP} --stdout) + + message(STATUS "Gzip compress ${GZ_COMPRESS_COMMAND}") + message(STATUS " Input: ${INPUT}") + message(STATUS " Output: ${OUTPUT_BASE}-gzip.gz") + + exec_streams("${GZ_COMPRESS_COMMAND}" "${INPUT}" "${OUTPUT_BASE}-gzip.gz") + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip compress failed: ${CMD_RESULT}") + endif() + + if(NOT EXISTS ${OUTPUT_BASE}-gzip.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress gzip input: ${OUTPUT_BASE}-gzip.gz") + endif() + + message(STATUS "Decompress gzip ${DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}-gzip.gz") + message(STATUS " Output: ${OUTPUT_BASE}-gzip") + + # Check decompress target can handle gzip compressed output + if(FILEMODE) + exec_files("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}-gzip.gz") + else() + exec_streams("${DECOMPRESS_COMMAND}" "${OUTPUT_BASE}-gzip.gz" "${OUTPUT_BASE}-gzip") + endif() + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress gzip failed: ${CMD_RESULT}") + endif() + + if(COMPARE) + # Compare original input file with gzip decompressed output + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-gzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-gzip) + cleanup() + message(FATAL_ERROR "Compare decompress gzip failed: ${CMD_RESULT}") + endif() + endif() + endif() +endif() + +cleanup_always() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-compare.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-compare.cmake new file mode 100644 index 000000000..eb2218dcb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-compare.cmake @@ -0,0 +1,72 @@ +# run-and-compare.cmake -- Runs a command and compares its output to an expected value + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Required Variables +# COMMAND - Command to run +# OUTPUT - Standard output +# COMPARE - String to compare output against + +# Optional Variables +# INPUT - Standard input +# IGNORE_LINE_ENDINGS - Ignore line endings when comparing output + +if(NOT DEFINED OUTPUT OR NOT DEFINED COMPARE OR NOT DEFINED COMMAND) + message(FATAL_ERROR "Run and compare arguments missing") +endif() + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +if(INPUT) + # Run command with stdin input and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DINPUT=${INPUT} + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +else() + # Run command and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run before compare failed: ${CMD_RESULT}") +endif() + +# Use configure_file to normalize line-endings +if(IGNORE_LINE_ENDINGS) + # Rewrite files with normalized line endings to temporary directory + get_filename_component(COMPARE_NAME ${COMPARE} NAME) + set(COMPARE_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${COMPARE_NAME}.cmp) + configure_file(${COMPARE} ${COMPARE_TEMP} NEWLINE_STYLE LF) + set(COMPARE ${COMPARE_TEMP}) + + get_filename_component(OUTPUT_NAME ${OUTPUT} NAME) + set(OUTPUT_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${OUTPUT_NAME}.cmp) + configure_file(${OUTPUT} ${OUTPUT_TEMP} NEWLINE_STYLE LF) + set(OUTPUT ${OUTPUT_TEMP}) +endif() + +# Compare that output is equal to specified file +execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${COMPARE} ${OUTPUT} + RESULT_VARIABLE CMD_RESULT) + +# Delete temporary files used to normalize line-endings +if(IGNORE_LINE_ENDINGS) + file(REMOVE ${COMPARE} ${OUTPUT}) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run compare failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-redirect.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-redirect.cmake new file mode 100644 index 000000000..6651d1a30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/run-and-redirect.cmake @@ -0,0 +1,54 @@ +# run-and-redirect.cmake -- Runs a command and validates exit code + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Normally ctest will always fail with non-zero exit code, but we have tests +# that need to check specific exit codes. + +# Required Variables +# COMMAND - Command to run + +# Optional Variables +# INPUT - Standard input +# OUTPUT - Standard output (default: /dev/null) +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +# If no output is specified, discard output +if(NOT DEFINED OUTPUT) + if(WIN32) + set(OUTPUT NUL) + else() + set(OUTPUT /dev/null) + endif() +endif() + +if(INPUT) + # Check to see that input file exists + if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find input: ${INPUT}") + endif() + # Execute with both stdin and stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + INPUT_FILE ${INPUT} + OUTPUT_FILE ${OUTPUT}) +else() + # Execute with only stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + OUTPUT_FILE ${OUTPUT}) +endif() + +# Check if exit code is in list of successful exit codes +if(SUCCESS_EXIT) + list(FIND SUCCESS_EXIT ${CMD_RESULT} _INDEX) + if (${_INDEX} GREATER -1) + set(CMD_RESULT 0) + endif() +endif() + +# Check to see if successful +if(CMD_RESULT) + message(FATAL_ERROR "${COMMAND} failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-cves.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-cves.cmake new file mode 100644 index 000000000..4a0860403 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-cves.cmake @@ -0,0 +1,33 @@ +# test-cves.cmake -- Tests targeting common vulnerabilities and exposures + +set(CVES CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096) +foreach(cve ${CVES}) + set(CVE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ -d) + add_test(NAME ${cve} + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${CVE_COMMAND}" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${cve}/test.gz + "-DSUCCESS_EXIT=0;1" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) +endforeach() + +set(CVE_COMPRESS_LEVELS 6 1 2) +foreach(cve_compress_level ${CVE_COMPRESS_LEVELS}) + add_test(NAME CVE-2018-25032-fixed-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-F;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/fixed.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + + add_test(NAME CVE-2018-25032-default-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/default.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-data.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-data.cmake new file mode 100644 index 000000000..e60c356e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-data.cmake @@ -0,0 +1,68 @@ +# test-data.cmake - Tests targeting data files in the data directory + +# Test compress and verify test against data file using extra args +macro(test_minigzip name path) + # Construct compression arguments for minigzip + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id minigzip-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + endif() +endmacro() + +# List of arg combinations to use during compression +set(TEST_CONFIGS + -R # Z_RLE + -h # Z_HUFFMAN_ONLY + -T # Direct store + -0 # No compression + -1 # Deflate quick + -2 # Deflate fast + -4 # Deflate medium (lazy matches) + "-5;-F" # Deflate medium (Z_FIXED) + -6 # Deflate medium + -9 # Deflate slow + "-9;-f" # Deflate slow (Z_FILTERED) +) + +# Enumerate all files in data directory to run tests against +file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) + +# For all files in the data directory, run tests against them +foreach(test_file_path ${TEST_FILE_PATHS}) + if("${test_file_path}" MATCHES ".gz$" OR "${test_file_path}" MATCHES ".out$" OR + "${test_file_path}" MATCHES "/.git/" OR "${test_file_path}" MATCHES ".md$") + continue() + endif() + foreach(test_config ${TEST_CONFIGS}) + get_filename_component(test_name ${test_file_path} NAME) + if (test_name STREQUAL "") + continue() + endif() + test_minigzip(${test_name} ${test_file_path} ${test_config}) + endforeach() +endforeach() + +# Additional tests to verify with automatic data type detection arg +test_minigzip("detect-text" "data/lcet10.txt" -A) +test_minigzip("detect-binary" "data/paper-100k.pdf" -A) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-issues.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-issues.cmake new file mode 100644 index 000000000..1ffb3abda --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-issues.cmake @@ -0,0 +1,68 @@ +# test-issues.cmake -- Tests targeting specific GitHub issues + +add_test(NAME GH-361 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-4" + -DTEST_NAME=GH-361-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-361/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-364 + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=1;5;9;3" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-364-test-bin + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-364/test.bin + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-382 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-m;1;-w;-15;-1;-s;4" + "-DDECOMPRESS_ARGS=-c;-d;-m;1;-w;-15" + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-382-defneg3-dat + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-382/defneg3.dat + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-segfault + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;9744;1;91207" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-segfault-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-incomplete-read + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;88933;1;195840;2;45761" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-incomplete-read-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-zero-stored-block + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;15248;1;1050;2;25217" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-zero-stored-block-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-751 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-751-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-751/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-tools.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-tools.cmake new file mode 100644 index 000000000..c2a683fbd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/cmake/test-tools.cmake @@ -0,0 +1,80 @@ +# test-tools.cmake -- Tests targeting tool coverage + +# Compress and decompress using file_compress/file_decompress, optionally also testing MMAP +add_test(NAME minigzip-file_compress + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + -DFILEMODE=ON + -DGZIP_VERIFY=ON + -DTEST_NAME=minigzip-file_compress + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/paper-100k.pdf + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME minideflate-file_compress + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + -DFILEMODE=ON + -DGZIP_VERIFY=OFF + -DTEST_NAME=minideflate-file_compress + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/paper-100k.pdf + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +# Test --help and invalid parameters for our tools +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--help") +add_test(NAME minigzip-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--invalid") +add_test(NAME minigzip-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--help") +add_test(NAME minideflate-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--invalid") +add_test(NAME minideflate-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${SWITCHLEVELS_COMMAND} "--help") +add_test(NAME switchlevels-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +# Test generated crc32 tables match tables in source directory +add_test(NAME makecrct + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKECRCT_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/crc32_braid_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/crc32_braid_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated inflate tables match tables in source directory +add_test(NAME makefixed + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKEFIXED_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/inffixed_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/inffixed_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated tree tables match tables in source directory +add_test(NAME maketrees + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKETREES_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/trees_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/trees_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/data/fireworks.jpg b/internal-complibs/zlib-ng-2.1.1-beta2/test/data/fireworks.jpg new file mode 100644 index 0000000000000000000000000000000000000000..078cf1755dc0853e97ad30fc7af4d6af0b67047e GIT binary patch literal 123093 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
    ma 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

    ha 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�rRb`0y|*v1_Y0K2x& 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

    3ZRBxkF?%H#_f~x|{{V*%h1A?S z%$!c+o-HK_qTxPOs>Eq#O#Hu$nu3V{bS|Ptw0Pbnte3Wxa>ks#JfgmBKY{J&Fh)2y zUp$RR;m%(~*Tng+;ukv3;s+G5%wl}QHhv>nHhR=ly{BK$ql(X^KfI6FL$JvG)3P_HCYfsyve|aFY_x6q6=k=}sf$q^@ddNu4rE zKyszZPw!HJ&3Xz4H3;eD)~rhMD*gB6^*QnBUPbP1ay!D$g{gihQ&p95N_t!m8ks;Q zNJP0hMAXQXl&2G;D0I|l2tSLGhf<~MnuMux&Yzvu>!+v7$A$5x{M%Q%jF&p=7t@p2 z`W-$Td2stY(czaaT;E2!K98gIK9>9tz90Cv1uL^2F`Dqn-?nLR49%3W3VG>7`4p>_ zMv0P)wSrQ#&X+lAN|WhYG^r&)QRB~1mo~d3IBG5ue;yfqRWH=<;lm7CY*{$2N^t)G zw~2p;^`quL68r(?yvfD9X9uFg<>8YsnP0YX>{}A5O(qkUs3x+cnwg3KA!-T=33V-6 z(1f6=#CrZ0;|=2CyGvxNcGq7{pPwVm@jnV)*N2p)zmi|6=*}!k$+;$|;Q28i&nq?&ni*U#|sP17%sQvF8dgMdDZOtl%RdHvPWEAwZGsGgq!;M4ohte@nMUCb&` zB}6$cNsmP&wmjD-Cv3@BYup&+US}HuZTc~dQ6>dixsR-3iomFW^M!epfSIU=v}%ls zN#=gBBt-UoqDXG`Ahsm8(jWroltKzO?b5@^5opzgiIUH}Q+Wsi@K0n0#do|*7 zYVk_>n2lWXsdK7jqH^XQrAh?HsfWUJxMRVJ94pDS_%o@O#&vmJ zO)5}8JraPQu#Vg@sIC-rGGuez{)b2?l6muvLxPAb*b%fgAQXCcg#$Cq+B5*{E;opT zDDuC~0x}eC8r-2wfkCWo2s1qSzyEf<-2h&oJ20GI0nWSIn#*7m$= zjV2`W>kxobz?d>t(O+UMPx6A;FfRT5;xaBmU!OQpq{tmtCE_F<;zMSbhT0H(z^S)j zec&QzF!~UOAMXa^>Ip7(XhE`eRiCUKOxZiy@QspeH;6T))aDB+lH# z0LxH^)U1hfv;>#}=?CWvVj{--z=Ukj`2e`pv9uxtx}!E_?Z|an{GqZ;wO@M}nW9PU zXb6GQA|pY4M%>^d3NP$WNQgmXg4c}^5>2BG5S1~${NW?Ya$aNq08C`e)VW7Y{9cY$ z6b~^ibJ03s9^ybr?6nB$XNMkGE{WgM`<=`(;l(+3Rr7z?@qnf`7LMabOwm&jVSZ)~ z8yhz!p;D%$X(cL2bdk6*nZ-3j7f#P;c%Q9Kc*SroA=9WW8Rmpd#2WraDIuiR%U5-% zBA|chtC!8=$neDR@#$amJ-_LDug!c9XT(~`7;5AFYk&Hd&+>m0@p1jl^G^{NIra5&Q6y@!)J{kA@d!vg>ui%HVoK&OR z^z8i3{{TGD$*aR8)UKj#J%Y_1T_!3J)s%#PSr@a{w&PV9E^GB(Un9kH?nIlBaru;gi=o7% zFqtBYp{``}k~mn(Y*{^We24)uy>M z`~K(Qi*mV+=b_RTepdE})DG@m9j^>r`IF?!LKYI4Wlu6;>J!ioWrxlZAs&fkOgfouoGW+j}bW?WK(1E{OQr{Q@t)yxC&_`@N3P?Etx zGD4D8RFun^I!RHyc>4Y-QRmJHBQsj~kaT%6LG~(g- z3c|Um9NzE?;?9eQoJYZxoVc%-G1@w6xm7ae)L_`3?HW~~*>b9dFjk@IAj~TOq%aqM zneiNg&?sB02eHf3r9bKW75x$iCmiZm2Jtco=&UibbMLrqMC5(IiyWtetf;C)eQ-J*StMULI~kE_!7jwyZlaQf}|pD~+9K2VLb$gpnFqb5a^{USs`KpQ(kLVZHtc!>izzsd!<2rsk5$r88zuvc<2ZSsVOc8QWS zrD+`CHDnax`!r;TI#}+|lQxvw2rB(=ar-sPi;M=FbFSu)Zkl0w$qEqLQ^ zeU4=vw?B7>+4Xrh5vi3i3OHUZOEV9|WT3g5A#8R#lr1Qjk^ca6wCv9vEnbJ)Ly9ln zi%oj3)mnZ`?&!7422L3-c1oY4{W+ua^TtiYat2|WhGKF&ij*Q;F-e4oV@UB^~2ie=2iCgJlClPwjA zNm8YTU>4UXiis*|o=o6>B8Qm7+?Y4X_X!Vz(M?sm%b*rxsCk<&QXS6X=K=~B1FhjS!Gryvq7tHitX#;AhVeGUiDA4TRzA?O1`X6k z45D$gBDWCQz2ZYcs97^R9mV4ytUw=UB!n?e@S-Q?PX7RC1YB(r0Z!yRNURG# zOTZ*9c|wSfOSDu%3x?VPJGz8Uq{1o6(xl0&Ql_Av;|V1WI|39wMmXarypFk}no3c| zuao??J5X5OIjG?xS-HkYR9Nj6#Ce8IuNjkvnATca{{Vd{Lm9(@zlv<65k6SxRVCHj z$Vj;&Jl#xvo_J?mzU%aSpTYhor>2*+!#zFk_m`?$uZsK+5SKBPZM(;y*2kWi`#F0w z)MeSrnIULWCZx-sB4E`jp$BxVb02V6f(QmWS+vm0w7w6MUWaoQrdanwiKd>STBpzj zCR(pDoo7;|`yb*@eaAkf#@c)``Ic1{xS`9j`134v0jIO=9jd-(Nw$VjOv$O%Nmcp8Ea+r@QV+AEckxs@G@1RLjqaxg{Vk;Dar|Nk|MKks!P%1(s(yGF7*8mcI^s^Omw#7i%$`-m1B|TOr_+RW?N(U*YO1swYiMv`Lh< z{PQL)wk(9LU&9^-w&bnt#rPi1g?r7%`gxyMJ}N#PY5a8XtA#v3%2;j^a}u)79bI3B zlO}d4_*uY|%~3wJY0}D39Ki*gM~$qUakVI|oK?PV)vITxq{rWC$D$*jg636c3)l`jZQqIY8MaynumqQri)W#400ON|kSzM*@ z-4>iik;(;t$WTt;-HtWEONQ>_QmraO+`%09OXa*B1#`K*hAPB+N> z?K;k)?b{LcfIvB{a_wdb`j#kX&h-^lIwYl`-#{FHO%|Ud7qic^Tc)|SNlK~_OILd>~CAGdUsHV$NT=-#k}w1 z7K4e(@~7i`M!_U0KAL<}5S5#7`DdV$R+K3z@2O-CN{?P146*MRMo-G%{%fhzpNxA= zoTVR>m&x)yJ)3DxB|TGQRApRTEB^pH4w3j3eB^1AK^>6Y36EC`P}*Ee*LCyX@jSf0 z%y%9a>9hQg!o=s%8hKKYhSX8i%SiJSsrr*J_0m!s>SMWyP5azQuTSoErr}9&wEcf0 z^DIwD=cBH{TXcn@+-y3ZXiyokS4W7500A8$qBK$(A_80I5fM(25U>Hx(E)1Pv_x8* zU9S-xS}6jip%Tp5azQLsvO-hb{{U#iq-s0tcePTm`cFb8&aPOtq$kRi^3*jE?h<=P z6XSdGIhO+2?soqGjnv6P6Dd6qE`Db4#cjJX+USnH8Bh4i#7bl9PzLeEno23Nmke%5 z`=Q_~{vQq>aTCKnU&k{o6-FnBAUBMqaN8SCK@tJEd z{{T1dE@#O2&xS`&m-%kd#%y02sm28`sh=`=q>>~`D^rxqPvuBG1CTlkN7CWN3~jh7 zz5XYUn>6Q2PU~-h*%Iu+I~>u$WVJ4Z z2@LRAAZPyoc+pUiV(}WFYY-wbTd?}Vh{}it21Y^LZ_*PaKx;xoo?h@!leYW9jL|qJ zbJ8Lv>C0$RHOPwq&{2aVf$#K!%~+&FinkZ^w=)R`Xeexmg@uE#zv~C6Sp)Tn3SwdE zAkI3(Oo@q>!=;2(u>&~%a8WV*yL0CV7Ru!jmP$|B7AOj}T*hpyw~Zr6)3Ff~M%*y5 zVcseZW_iGh!N7%&m;x?&z!%tnF9m@gQo2OMk_R|ZSg5p5nGtQwRn&~Vo&BM*vtH1e zAz*FvjFEGJA}04dp}wJH-tbtKpHK9J#fVLtlvHQ{g0~UUdc@NP06Ka_&@6~zF7a+$ zL`O(`#>58pipe_*g7609#9Y865>Lt$NPXgD!)^J%We|7X!|xHRAQ<(C1a|i62$Dyr zKRA*rG^Bd1aSKJv6j=L4NKYdX7$Z@BkddamX^8^^BdI#2brPhZYf(gmXh7tVsHlPS zB>dwFDK^(rPEDkrL#C5*?nG+Lh_D6i0T#Fa03ISb_-%aLD-e-YC0Zv_EKEV}3y980 zDW@0I+$Q5CBy}-QEj8*~hVmx*<$=j3_$H*u(sndKZgXB?2Ww_g*rj})=K71zp-yM6^QkNiaOY2iw3A~9i&R`9zCGpi-l z=%$rRDs@!3;L8ElvWaRARKRj2ihgfAqdf4_!<$iDyUE|nsqJav;iZ;YZ(L94tMWV# z8Lsj5*(Vo3>L99)R=HQLEysAE?r%eTjw=;*YO$ev7(-Ceov>3vUL(&TA57mC%` zRYZ^56&Q74r>B*1B6`s=il#9NDPVmdhkK9%9+dTS&!&vAz82T+zf-jhJTU5Ijr-g$ zZ|;4r@k!$QANY2BJG?q&YWm+VH|L7kS+@|TLQ_pI3&W)+O(i^;NC6V%-%v_G8jwxO zi9R#a)}A_K-@WfTZ>G!VyMHs-Q;W|$(&W9>>&{;-k-#n5rn0MF zzsIq}4m4(3A&%A5Wt>uP>^xkF--PoNgDj8~WlfYxO0=oKRlq?2GYPd>Ul0!$)#Zsf^=Ixyoo8M@wsf5n0HDttA%Xhza~tAcM^e0evxB?il*$cPl?@Eq0lec zglxkCZQc+9=I8Z-h*B6a=e#63Uuzz31(BeFSdaIFj1=luPO%k{9Jxe5o5Dl%zsdq6 z+&;nr=2F8qc)_%Fk{wL@MtKb%p@Yows*t{EQ@nL`DY!a2T6e=GNA;cX1LHj}9)2A8 zDrCZmwU`{EhE6-H(X;%FerKb>1*yr3Npt!iOX7KE;|#HU(ZTQdxx6{~`CBIE+G=n= z2{m|iLc(@RgQfms?;e+hWLkZD#*#{Zk-?Ha+egRE#P|zTJh_BCet`)eF*Brha9%l= zBQ?2|B$K>XWXo&q^Nph+`PAReDhmbyP0M(QiPl3ib$CdaJVF2%fQWarOl%Wz(hh)3 z<|IHsDt=z^q5{O)0y3dt8V*83hrB?+ouVd52K^!s*zN>dkl$6}=1CDrDZlF%Fldw3 zB!vR313mdf*)~SwalY^-X35w_hmr=2ktft`{?Q=x7qn@y4L}$yn1JAajSvmU{_vrR zk#hoNV)ll~5cLQx7ctyBlF*`EfQJ@utN@5#a$rnsm@((`jUllX9a4AEMuIhb<17+8zu9w4ps_7_K->#Q7q)_YH@V5|^8he$eX8>EWFE8fp~9WMqg3v@qr!UGDJE@C`hc`;u0xw)+#Cu z&Ef(g0!5|bDj*zkh>@XSAAe}lUBwQsRp4w(RqWS*h+K4th=(x+0N-!4Btf-BLN+EU zBC&{wonPnP7DNGY+A>5-kA2~`LKH=>*g!{8Svo`PU}SX|gUa0F3u8}m3Do0Ah_+_5 zYftNFQx=Yt#AsJ&Z@HF9I)iC=Zi>1dS0@agQ!5V3)Uv|rs%Iu-{zuJKl7f0AKXPNB z^2N87Ph@r@ALv}p^l=Lj$XUvceptn8@Tu4j?&&LNsuv<|uw7FEl0gox`vDlsrNy5c zSyGaH&c;1XOgR(7E*844sq8*6_^{6&EGsh9%=L<^FxTbUWzo}BO{I}4a^U*5!QD zz}y!l@V^{f`PFjg)@F=VXqZ<@YbzJ%lPyi9LR~r~5^DVJFUIyVTuKw~#e|~SC z$7{yi<%5bpc2aNUx8r9Gvdr2(E78#9ywb1P_=L?eaC~upnIM)-na}y962L5gU73E)(g`{4kgR!g#mEeA=|P`d5eetx#Y6sxpE>`V;k!2VXbsxVos#{{Z6G z=6jwU7wpt}N>E?!dq-as zcy##jDpyOHtkM4f)k`W*tE0)jK0YqL{3yIMT;)&yR)4vj;ui;TDN=1TP+z97}G`Spe$tTR| z8A4h;N*a#H1^)5MrO_NtFPl06PG6^J-I-{ge!bxUHa)~e)QALg{*e(2L`AejEz0o` z*QKUaLcjp1orGn&B#uJ(Z}?~NSH(XMGfrg5`D&uO2Fe(8>`xM`n6%21B21(etm;t! zsexpNQP=`w$j##LhEHWpzb=cbeut%t!*Wg>e3RLEzQ-T&Y&lqUM9B*ZPnJqgQbz9{ zraX#D(b36`#k9`Mu?3@);{aTqZxILO06YkhD7B(wXcuNXcZ{?s>V-H4?-^*?I`q>5 zRvd>Hyl~H!$21xD&;Alm6_j*28#`nSLa_*)OEDOoB(<*UN%XCU&ExZL7Mjv{gUcnf zm&0S~@ZoyB8pj{JpU~xh{6)*bIE(P%&IYDrfjbNGs;QJneR|k8ymhea;h$TL$C`d; zCLJ8`Y2@e0?0+k`gL&)d?H{P)-5(#8DLszdkJqeoql%1>Rk8U(O*1Y?jV5t{b#w>b z5+W{lF%dKGc8I7LwZ8C>4TJy8&JYk>Zej8ZL~c&) z6^RuzR#aBg*XI{PpgZ$|$h!xCgK^Ffq1Dn9$r8G}Oc`8_?GU2W6d>kih}-mwp`?K~ zg&;I;Ifz)aW%i5(02k*96o*TV_k_6t-UdVbJlsNo6~h<@kvoUDganr4dqHH0-0oT% zv3-EqjsF0oL&#IUj%Rvpgs8aU68xhF;4Gn3*ZXt7XX6zsMaxUOXSP zTKVZTGs};fN44M@2x|3_#Xd*h+>`LG;Fe3sbodosN5ZiwqL;|1shW~kHBIVJ=wE35 zcz!vpoR(i~?eEO}-W~;_Se`Bf_UA{&Z;NMvx-SHNAwOl{)qjh?v8f-AqXhct&`BOz zhiWIYmdBWAP?p>MBLa!T2y9EAQ43(mS;2{uCj|6@&>(hzgd032g+u2S!~n26+wB4Y z0f+f$LtJZxciTlFe}dF(e-19f+bNC4?jlHo3G30!60p144)%%?Oo)9pcy- z6LGXp%#fsiog*YnklCl>Hh#|84(7EjfQ_VqcDuu6M$DaP7P-5;V~cZ68*F#E zW{y=ZBx@>ACR0%-%`(saV!wqyH8;o@U@x>N;PY_-3o zNd;DOta?a&DoH$3jmjt^Ja&}Ns=o&g8Q|P1@SEbNGG%;fRy&5TCCs9wsq&39#2M-! zA!t&GNoKo|-+1veP4HxM=?1^0E1@={6%r5s$`i} z`EM=%0HrVm38^YpD~qjC0Z9k*B9dKV`uapVmBizPE|v4!@VD?WjxI8mX?py({{ZE} zz9#^&{APYNh$>{oE^O7Uh1}e`eN26Bj|4Ge*=&!N)Mb`QT%EDRaA}kjY5ky0GQyoQ zP3I}VxlizqNc_#%803aUDSNy5^fNq8D&?{G^Jo763K9~Buy-fkJ1RX{*K+8NlDFza zYLHkkD|Uv0!{xjnEaisLQ5hQ-iinaJ-<(7|?GYMELXFxMi1#0YFAVs{i(e6WYa(DW zQ98dIsuI+-t3;}4N%c&fF-FLigas)|I|P{VJZDny;kC`|yx;HT%=P>$NV8@4xh>zP z@AN*6d`mtk8Bc&d9%T4w-~~*C3zU{!@$sK-hH^e z+qU<)KmM!wSH|P>K_Wkv22-IyQZHS{{Ww%exHeufiVN7sR|ubE@P&rs>c2F zrn{}5$?f$!KF>{)?#adWd#{?`=y;}O$he+WPO6zQrqh27RV?IG(@gG}vdKaEzs@@t zbr8s{Z2LP;W}KagD-Fb?B~sK_DHBj^P@s1PJf9NqeLk`rIhQU+cSo+f?9n@-J?6N(MAx=@& z?*8%g=_SbUoSWujpFXjqWD+g7`NKrnmwtQ0UCaRhpY0PR*o!^Bu~{@qZQth_Xn`rz zOWF5`0Q$N_K-REmh!n@8#6(7=JH$joavxYx8E4uWAt0Vc7rCE61)4IMpd;4{2F1bo zM2ndy2Z^Bq@6rM#bn6k8M#FIb0Hi2ri0cCi778D4c!Uxhn2>ph+vgf3xTH5oih-Zr zD-vj$5d5Yx1V`E$DlIPkprB}2x9b|AMoLU&rVS0!1MVRbVW{RYm#Q7qF_h_AdaW6So}jj*l!Vz zRR~7y^XXo{+v0x3gYCwP+41Gs(emfwpW}j;#}^;}0B+%w3ZTMp>SWN;C1+CBgrCfP zWOY_&B~nB0jQ@pEAdt#7Pk7`54gw56hfpjMm}> zg~5dgH*j7iBl$!CN%x3}-1HHuB0E7ys13Wk1YEX>7g0{%<>C?~b%nA5T{}i^VjygL zUL->7Z5psA`oM_-kEh?1EQA;7Xcw7sFRlL2kUOd~WIoXe6&;$xrqHr0eW5bhChy7v zM9dl_MxFaYKrUb*c31R_k){0%By`kSuI&|rAFZQZ2!ON*D85lx**)zQQ7}t4 zTa-d5ECdusQ6z`9&@!`Pz&F+~XxdY7{JX^0LE<}#Wt1zn#yF;O!0+nPs)W+v)XCRA zs$fwAbrWPK{OcSMi@r8;VJwqS52YnP${(mERRh`zPqH zy>mPI%~Y}Cc(5vy<-=?HzmCtPoX7DE;^!%NbIGB9i^HmFCE@DCWKc_(om1&$sUdn2 zKlJNn3*T*(zDE`F)^y96I;C`Z4qaN1CFz@u*UJLBdyiL^kV<4H zf6MD@Y9Zh1w77F+x2dGMCHek`&T6vZ#Y;@>^>6Y$cQSdLrIjeHO1UR;ddH&(QRYru zTb%$|{o|P95Lmg0jF3UNsLM~KE?kf~`L?bM>Ck0Fo1hMPQ~Mm!qrV#$q6{`7e*>;g<8s{$d;Lg zG}Z_aka8#DW}a9Jt3-pEmF>lvept$v+o4tqgGIhm)$yKDq5L9f;SsO zR#t4^Z=K^bH?V3Xdq&bS**m0tqD!bYWD~1k{_(2pTtw}=U#BP#^F~N`(SSCyUNYBm z6LL0%CQJ|JJvu^(f^882xwCB%01P{bh+6K}h=Xr#j|~t%Kcr}YkPg?3vJxyl@up<~ z^tIkI>Le29=M57glVP+}(Iidw+8ZDNm40v&WCM}*fX^@?_WuBQg_B#XMSa9vF)-G` zEq%WG!$HiGzi5i+2mtgk6%e#SM7W47nfi8swk;%*+@hi<541vGkv{Qq0wM0kA+%e= z%&iWa*g->NPow7w1;~hD$`a;hpR`~Qq&l`}keeuRyGEZOG=#DD=@}zsWCjt&mggho zv67;uxc7~t4VY#x8%zk>{ox=X{o-I+b}$H$YrG&E7>JZQMo0+Xa$;zU>k=W-Kf@X; zB9QigED>U0M41Bb6^a+NzuqPwcf3?W-ON=$fcj7A6WEC%#`X{qJM$2sA$xR*1&*dy zv{n`ab^;+TZxs-d%;FIc965l?%Tv9n;qh^8TSl!@61&8}>5gJPLmtsr=b%OO9 z*nW|QCsiSj$|vS&9mN_1$%%U*H&N}*IHZn5dpp9$P^ipV@_s&r;Bt-yrfoRH>LtpM zs)e00hLsnXQ*~%aQ95>L^SnxY7#vfp{5qYz4k=GB8eG2<>8FLyhGq$d=G-F|;}$=L zVRI`$sZLVMG!u?5PzrUV)FnwwxWYAdI&6y%v2Dy_I z6DU|E4#4%}Hu5B+-qrM6?e_1>(Co_#c-~8|I_u=S{Oh^u?-XAe&Kz;q{Y`^q+)oz6 zztiamDW4=w!f`Aq3Ja*HGSWoZMRL=jFRTKgaj9ZE`tNC-#!*g}^z{DTOMdUM)6nqX zylt*0zZW*Vzq!EA9X}H+Z$IOC6BtEpB`mCSht;%`{{RTUN~)VCvS60vY7A;AmNsy* z@zv32=aFQ%?wVEQeED`exwVTQ4NGTl>0goQ9|2z!?Ee7ay5iWgBIhOI-x)VDj+jB^WGfD{hS^ zw@dE6zK5feTOK|%+FjG${JS&Nei*zR@h8RJC5}?$>_}JSygFhl@oalAtr&I}gUh({ zYUa)+T$zL)%7v(`zMXr=p^`ZE$?Vi+9;wn_9k%j+BdZMAN;RApRa2I5An!AT;jwOCr@VAHCSl7De7Vb?lZ4fRY)LXYq;zl~qW$-@2T zIQevw=g;Psq3U6iSz$RXqY1kB#c$Db=>Gsi<3Gd~jM%Ri_{Bvp6|bFLGcI6weiRCs zDU~%c6EdYKNMxlVs%-WE000065$ye!(?%M1kt%bPpTg;V5y@;d zqmR>wX4OGNfln%F9G5#nr?3A2T=kxD~FCV5E9|T`$R$&VcV1K14NrTiC(0;If0{g8oh^Dk(MdjV&)b} zg1su+ZgDUdwcMTJMv;{%_WD9(kLGxWjDiSwiIe)eK#&pJVqOvtv_t{M(GhRR!a=AG zP~8wab9ihl2L9247vFE|8uAbX^?&CU;2}(5>Q;#QQh7X9USLI@Gens?q+TO7FQ}8( zaSq(Thy#>HfB^ej^@u2m)L>&`8Tt-!p&@=&A83*@Km(n*Kr~GM0Os(KJ*{{wsJ7fU z$}Pr-kC=$dBy7y^p{~N96x`xu&~EL#1w;*rXwbey4(({HIf*s~<_jba*5wmo$Sb$n z0Al)JBB6lpt@R5}gPj1|yvLZ-`1?|oeB`7o& zWq=y56_VW(x!wXo7$0~+1@_%?45jTLW4CBq)pRyhUYuL1e?F_JtJ=r#)b7 zg(bO`i7>JXbNWMOfO?BRc&@;8-Qu#dX;s<=CW?Mu@FvK@lYacVMuLFu!X9E}nApYu zZtt^0dy``BJ)!1E(nb0}%^+A~XaYzB?(qS%DfE_sq$hPMa#JXzp(-b0Tqjs@-mNr&Y|8MiAv9aOl8@%1OI5CrI~xQt=gy_+rTzb_0~@u-qFlO;7C#{CyHN z;<8sYBSfh)RN|jRy*{Z)Ou|%MZD{dz8W?KwJlP$^Y?n`0-*eW|Yv-oN?6IVq-M+qu zxI7woqr~ZP3^xP7aJ<2e=DfpSE=1odrAu9PWa++{g(Q{DSp`Y;C?(lM7Gu!y9V{V^ z*3@_OncU=@z3b=bauddHhze|M;yx5uLLJ7PT2TjMTQAHj-&2Mv6j% zlI>A68HLg%k@FaHLlo3uzWe#V(R`cqN7LuQ?O@v5Z*_L{^L=`yw${!8=i2I=y^yKu z0@Y27Ql@SXSfrNxZ8XAWN}JsO0M(SCunCpa$J*&~;?y->r^aeM4%cS}uQPlrqDb=p00+D-$M}cF+_^sm zc~v-de2V1F30%hV=A~B%1-~!xFz*htQw(XvE0-YBY53%&CrJCb;EUip!F+?@n=|HK zD%MeA)3Ifv7Li+x`ILBe9;rH=YZ7KAVx*F=7j&HQ%eTh2eUC#V z);#MD2=QL;zm;Cg_h-vbh!s~Cu&yOd%XqFghgIUO+6uWuJMe&groHToYLykO=(^{!;YZK-{G7GfA4KVVHa$%_4o|-*`dHcX z@;Yiqa$Yw^OdXE!gEIEN+9E_;IO`E~AXtBRQ6T)rAtE&%zc>J_4(1}VeIs~+&(O-a z?A*1PXfYWoDW5?(6%v)rD@vUwY4L1rS)8el}c1P=W-iI5g1@ezE)LTYC`dqL_lXAFiACTF1l=~YR#ZS*D>Y-t!(^BNZg3N5LFssGIToMR z4icj*0sUeVTfXryW=*y*ZWd`hdBTlZ0N3RjM2gyXF$DsB%RmH9uXA{dkv5ZfD|15o z0S$u!+I`@n5pSGA$?eF(ks<~AMd~KGLT11VZuf|RTl9hVD<%h%L{=a_Q4nrA8{R4u zfhX+{jo)XAhz8vooFYj&M)!dkpa8%0iZVBVj@k90c?s1=W`b@->C;1Gr$RxHQ_WMkYd~fLLe?oXVe)r%Y5OXNQY=pkuBZ= z4J=?X(17e>q96(1XpIvAd&5CSfo@yC(4ABQL+&FTNXpY^+njPO$mu&PXqX7v+r>ge z-M>hhA_0d;ks1K=jImtKvMEgIZa!V(gWA)hvaq>Fi0GF>i02&VR07zJO%Wfpld8Ra5$aNzZ|IAxL?5tEJeT>c%sPTrF)JX7|Q zj}>xHmHGExN3nPTB=}2Ax>8HmO==f67yUM2TS|M6k7Jl$50*Db@fM zk3T**=(N7iOsTz>tLpl{Hg=YI>op$NQtr9**>qiz;W@iC&(7Jy5XI+>GcgK<&nS1$ z2_z(T0f)*vIB`69qmA@B*)plk%_=?fmUFT2S;IPsczWfdiuulj%BiUZ=Vc5sYHukA zX?3+S$=0Fjl_7dvE1IyM24DK@w!h&=*Qi|TObS6Ii0cx#+iTuCbEa`=CV`#Cty>7C~m6(=@Jl_rq9q@cOj65zksMm#qb zOj2$~KZ)eWnMFkP+`8H<0~(()s+l;H)U1ywN-34|A&K@MSo#hb&Kxk?%=yW<##b%Q zTl_YsW}gt8dCORI`jtt*e`-_EVcB;IY6)2FYSuiuW|RREfO(VWsmdiJ-&)WQk*$vm zmN>2{OX=qS059x%+7_MVz8IsQ{CxQ6Wvpik<5v#qX=Ua-lY!#6USFf1B_c|(Oe{;C zONmrSN^L3Cu56T~G6JO~nJpe}x7s%x3wXC~gmdj2)n zzUKybE8#yo*YV#gQsw$u{N0f8dh<$&_;KEK8JWX&jd zWQDp?OO{K#bn?khPZdx8B|lys-M8v`xVWRJlfGEfRojjK0F(LG&&pj^KUTHsQszuj zlvG@m66O2c$JgkhqXiU?lh#gB$tg+R=ZnoqO3RDKr5ClHe38&u?;NHKvFz~?mM3=h zgaO#Z4G<15v`Gka-M&$I2@z;QiGXJi6F^IQKomC@J47Jv2pdF1EMY=v^>X)x5N!Od z0T!Yl1_scFsjV#bg&H#7I2jT2!bDDjXD(V`U{{Y5~5MQ0(A_bx&I*XgaL`Wn;*HR}RH~}CEWfRY&D4H&Jii(Vq@irrI zV9=lqU59vy30L%sZbSiAh>Lr*-~>S~Zq|fEmK>oFv$Jn_&6#Y2H(0hs$by)3gp(p( z!{?HK;(K07w-V!ag->eowOP1OYBKBtbLDVS9j;k}qSkalT>A)uN`^gw`XS_ zcNIo;>QlG(j&!y<@^v&$zr zz27sdO*|!O*@elB$zE|VnJ@)RP$WwP{$e+@cj2h0HkGt>C#SrLJ(E6`{5>-6S@3)C+~Svr>}G1lW2}=? zkT`CI4GX8Ns*+P(R)qfm-kCEGuaHx2&EiWlgL0bp1sl1r6`f+AxHBhkVA_&BXJ&-CyOd@$1CC6 z(fOWpj$BgWoLW-leNps>;Sb~6Hh3@L4q>R_)(?l`6ER#<530;H1Ql1|@}$m7$x?aJ zOhH)IERw%b1SUKUR;yWuP?Dt|#V&u`_B8k~X2Vlk{%`lO^<(1g!zzsV@Ui?h3?||z z$Fmg7UWm+@sY{bT%$+P16TX!tJMSDCm+UmK%D23YuQb-*L$#)FHhhq+E~zh50aykTG_E7z2LM2T=vnc+zHw*->mn z&jAxS+WW-FQp7+&;U{Q_iFAtyh`VnQ2wQG9+99$kzR>^@bnSRZfh6q#0W3PaBt*uU z3tr#t86YM3LuiWN7>KmAR7CbRh=G{7&?ltc*x8^AUS*ccg-1)@xvB^Tv* zMF|{@?GTeXqM))b2?Dox&zYBEcO1!ufjzm!VwsRZcjo|;Ta~`?Qz14lyTU|WtrHSw z(|h%A4EbcV$OLpMViKtS)fgi6;C z5i8UgnWAKoX|=81FF^#UhqOqEn`=A_g{}>RBoBXRfJ>W?)*%CXn42N`7J`6)-u8>s zi&L9z3t|8ljPqn`PLXIx&+##dGO^fgv?Mxpx9ipb0yaCskq+kO;xYtwg_?09MLv7abh7KK4jY7{M5WIu^9?05 zv2v8S)U6=0Z0aC5caJ|b<%0v3IPpuO?%(f!BfqA^vu07rDvwv$bvhaQF;V7x(^pr9 z&?gGQ)U6a$VS3Fpl-UVVzlm*iDTbvL77o#^9x39)qmo=w>ifUbw~%XdLndb|N}~94b?JQn0DTfYUlf)-G}e+^)j52&UoGEe z+53JLxPQYMoVzbGOU-qv%F<>_m5Jc^<`+$j(_o62rUGn|uQ4)|qC#iOD0cxxDX zUJQ+J6Z2T@;hDWkxMRh zYO>;Ls_?0j$CC|Pe^6q!=^o*nXK5WbylAr!wlqAYpbfrv@t+d?pX6^g^(nzJP7Pc_XlgN9%881y zT4tJQGNvU6a0yX28A}HrPpKWGDbR#PEbj!=6u}o8Uc- zL2yRz%07k;)uY3bY12ANI=*qUCP`~TMatHN5C$Y#+eAc5J-(3v9{jq+%s|-g81{%6 zZeOej6Cz)$#*GuQpz0k+3trF(Y^ZvLink%f;b=>jIGRKOPuc?&xmwq8383e+6htl3 z&=nJ(Xh=zbMZF;P5YZWTS7^x=pH2Qy(Gxc)fRrJjA9&FMgP&;406(aM0wPIxP*{@9 zv_oaEBViH*$PSihyNS4GW{5}RYh!`E>5$0B(?U1B1WCPqe1|(gFwQ?OC%5F8KDhYdzehJ+(bx){o*u!#Rf{Q#PIc0 z$(5}M1ou!K1a+sZ#|dyr?sl>0^3E=CTOW|LX)Jf<4=C&%Qz^7WX}}%fB1q}H436fK zZ;}+J^%10Yc*L)vs4c-NW4lKkcRNd!BVuV#0>T{C&GD;1naQ$@mDV^7gb=xC1NsWRf=SVO)^rjrGx`wtst}6 z9sW;o<~TC=&EGJ}cPzP`T|%+fH)_?1k`iIeLo=S)db)Kp50 zw5apx8Pnr>d=Z3U$u2{!lymB3l370Ue9`Z}3O*h2c|2CZ*Te23@aHjO6{ORgJrk;v z_^C=Cyp=jtO)?U>WiO}~OI({gdEO-0WyHQ^}oU!uXr)e@ed(zX16Y zf;=Y6*yb}!h04V0Wk{HuGY+UTFv(M<5M_x>-gwsG3m}36y1)xPKM&IBvP1a2RINIt z^j>b?!_{tfyh~S}86KNU8fxxccHQ|ZT>AH?vB`ccV|AIEBj#K;DB=k@iw2gGWy??+ zm8VgX_hM1f;FQO;;yERs225I6d+_boynbI=JZ}!g969mj)x+GK^Z6-!&y>C{JZfPT znRZ4KpYd!?U1e&ONl8s6uuEE%tIL?Gi8BznD$s1Cl(}%AN>v{YlycX#_n&9`?c3&k zeA>X=VEAkB_#Y-dARJ)fc5a)9<&2$z%D_=eT`>bOQq;^{K41venMG0*rG6jMrG7#N zr7=Q44fOsSr;_*U;rXM(*J>4T^?gnfd|Z z^HYOQbMxPue507-GB*T>0>s(vcvymrG(gsU+AYAjmL3PBao!$=hUOq(N3>0q2rcu9$by;J zKwA?%jhZAD4X0>%5(Oo>#L+TI^z(Dl1jvB2X%M#M!HdkSfCqS}TLEM35+YG>>`Y7; z3m<4X6^Yz^o*OGA799PcWke4B;Y7vlv?5N?Fta$gk(`}I>Jp0G5)aym+>@IMYiJc5RtirYPkn6{NO7d zQ_4;ojcRAs|?PXh;dtSdzzh z%QDcU*qd4uXg3`i5;QFUBxHy7iHDH2`CcI*VYEa7;w3^Srtb(7Gi?$iK!1iaTah$s zii@9Ugqq)I%kDr1t^J`yBr)Y^2(DfvfPk=g(3Ol00G**C1{lXpI2D<1CHLI#K{@U*`oHT+Ja~mJJw^ zIpZTq3>weMGq}khJz6yrhDalxv#fzOHCIWOSXh?G7P@X1_TtX>_A<5Oo;VYzz%{6JWlH7HM+Rb3<( zRVsC$B2vbg>jWqiOHfzG_|$Uh^Q{IYQC{?<)%qoT-&fHt_I-zf%NCDMEq+OR&uFCS zzU}s3Uqk7)g3pVG5%_WN{{Z6O5_2A5nV7N4>~2TkRarC4nId})b7d0YCR@rWVWfGV zm5WD5Q-dxQ{5}T#>U;CGz4<>gk{Pk&Yf+jim8x8+s;^HY-Jb>@i(l=mlbUf{)rl^; zvZppvimCMkCSuW5D9Z{{7P62OeV~q}ejhlfb9Ue7=hxICi- zk`9$2K!qhi!AS%bB0k$g7)}aNc8`3w-AvOh>FRaw^$k?(!$Xs6eWkw zAoT)u9hxIRk!TVjNYZ(j&^sgV$|0fw;$jTl9Kl2^#9Ltr5Ch&I^#FZe+9DkcLHjfm zWeu9#xkiluWAf_(4)3$XA*H?I0wbT#XoNX5K*+K8fDo2Y?+BsN@X(M+4X}*RSSdSn ziiDkp_J)XxK>o1<5CMLX6_HB_S^{Q1&<%+MjiMqcVP-K1X#_+ z0TC8!LPXA&v_wHHf22T7eVPgqV)r}3L|pO#;vl=gLPLAP41#qK>|zp#h=NAK4?-pn zv?N3gm_!DcJ-Nk1jIr$ymo1{ABV&EyBG@&r5fCh|@Ihe5jMUacC%rf}Twi*ogth>lF|u)OLc1>PtvhA#LJxMhSBb6^cs%XN)v$Na}*b zxN*ueM>3U>ERWZ;Nf?oUtyi-~&J$p^z;wJ+L|12Tlno7?L=vftF8e$VJxMdWqMtEK zM5KC_wK72JZMV`mWr<%A%^Z^2C%xtI-hL6mY-1s!X&7mrJhD{bb458xJ;7BhpYfx_ z$);~r?V`JUto2@g9X|r=%>3^STyChzSZ-*-#x8K-iO{B^l`P_>rb#J8y-(>rT-oI& z?xdwQa7RL>4R9Pad6O0Y z08L^e@fd~-s)ZUk7@`K5lhZF?rGoA@O7!xMw}bdbJb5P>t<$yIx_o@i_@9Z+SfeO9 zQdIsOJvyG7#ap_m?j}FVOY6i3tJAN2rf5#>#H7q6LOFXd2uohpE|sgh;u$i6Sj8 zvosVy#FmDLn3L8nfF!u(2@&NHD& zHAFXz>gfRy z4bYf~k@7H+ZvCPTrKQ=T+*sdYA|waYeWGB)y9R(!HMZU=Dl|HVgqalmyKNN^F=n&= zu`*&GRib3b2KmCDKt-{Dt8q=ic&yQE zSbbt5-(z7B0W4YKB5(kHLLwC07>v+ArT$S3foHTrYj}+FA{(4SnE>If5P&Zb2us=o zAOpJq!Vt0_nc}e#aDP~t6Y_X~H&vP-vKKdqMBMi25Rn?j;y$-Xah$Xo%|5Ni{Rlgojd#3-gRlYAcDFj9i+EKYuoG z&k@QvOp4l+%JOHH1uF!D+(((C@oXBYIAi9H{>4AC)}R}_Rzi~NyTpim#yp*^-Udf| zfmRv}MqNN>k^9u!nr=Sv#hTn&Mx^{PG7&Gv?nhDxOnUg;gD1-u2F(8J0*rbv4ju(kX zBFMS&eupy3<&EQ$+nV)1E=@}5<|1^Zu2k6y3QE$V6qN$tgUE)Cio_j+Bvu!I8C}5V5EHNh5naTW z8?(eFc>@tqp>*=JKxDJC##$0*Oe93uM96~!5f|}xhRAMh-XbDH@9zLu3#3FeKr=V? zih_t-JV>?>Ue5?!0Wb4_QzmzaNEhi4SnBk<_Jl!SXb8zJe@GiMW`R0MHncmDDfKiK zDUc4Pg$)5=->f!6(`&>OL(-Rh;s6S>n1!Mqp%93)MtXrw;AqiYmg@-+y0 zh>`^zkIEt)UYE2&Any<|3>&;Gfhj*o3WsQf9GHkri*ks7rstRu0FPHY#8iL(+4)gF AYXATM literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/data/lcet10.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/data/lcet10.txt new file mode 100644 index 000000000..1dbdfc56e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/data/lcet10.txt @@ -0,0 +1,7519 @@ + + +The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC TEXTS + + + + + WORKSHOP ON ELECTRONIC TEXTS + + PROCEEDINGS + + + + Edited by James Daly + + + + + + + + 9-10 June 1992 + + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + + *** *** *** ****** *** *** *** + + + TABLE OF CONTENTS + + +Acknowledgements + +Introduction + +Proceedings + Welcome + Prosser Gifford and Carl Fleischhauer + + Session I. Content in a New Form: Who Will Use It and What Will They Do? + James Daly (Moderator) + Avra Michelson, Overview + Susan H. Veccia, User Evaluation + Joanne Freeman, Beyond the Scholar + Discussion + + Session II. Show and Tell + Jacqueline Hess (Moderator) + Elli Mylonas, Perseus Project + Discussion + Eric M. Calaluca, Patrologia Latina Database + Carl Fleischhauer and Ricky Erway, American Memory + Discussion + Dorothy Twohig, The Papers of George Washington + Discussion + Maria L. Lebron, The Online Journal of Current Clinical Trials + Discussion + Lynne K. Personius, Cornell mathematics books + Discussion + + Session III. Distribution, Networks, and Networking: + Options for Dissemination + Robert G. Zich (Moderator) + Clifford A. Lynch + Discussion + Howard Besser + Discussion + Ronald L. Larsen + Edwin B. Brownrigg + Discussion + + Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats + William L. Hooton (Moderator) + A) Principal Methods for Image Capture of Text: + direct scanning, use of microform + Anne R. Kenney + Pamela Q.J. Andre + Judith A. Zidar + Donald J. Waters + Discussion + B) Special Problems: bound volumes, conservation, + reproducing printed halftones + George Thoma + Carl Fleischhauer + Discussion + C) Image Standards and Implications for Preservation + Jean Baronas + Patricia Battin + Discussion + D) Text Conversion: OCR vs. rekeying, standards of accuracy + and use of imperfect texts, service bureaus + Michael Lesk + Ricky Erway + Judith A. Zidar + Discussion + + Session V. Approaches to Preparing Electronic Texts + Susan Hockey (Moderator) + Stuart Weibel + Discussion + C.M. Sperberg-McQueen + Discussion + Eric M. Calaluca + Discussion + + Session VI. Copyright Issues + Marybeth Peters + + Session VII. Conclusion + Prosser Gifford (Moderator) + General discussion + +Appendix I: Program + +Appendix II: Abstracts + +Appendix III: Directory of Participants + + + *** *** *** ****** *** *** *** + + + Acknowledgements + +I would like to thank Carl Fleischhauer and Prosser Gifford for the +opportunity to learn about areas of human activity unknown to me a scant +ten months ago, and the David and Lucile Packard Foundation for +supporting that opportunity. The help given by others is acknowledged on +a separate page. + + 19 October 1992 + + + *** *** *** ****** *** *** *** + + + INTRODUCTION + +The Workshop on Electronic Texts (1) drew together representatives of +various projects and interest groups to compare ideas, beliefs, +experiences, and, in particular, methods of placing and presenting +historical textual materials in computerized form. Most attendees gained +much in insight and outlook from the event. But the assembly did not +form a new nation, or, to put it another way, the diversity of projects +and interests was too great to draw the representatives into a cohesive, +action-oriented body.(2) + +Everyone attending the Workshop shared an interest in preserving and +providing access to historical texts. But within this broad field the +attendees represented a variety of formal, informal, figurative, and +literal groups, with many individuals belonging to more than one. These +groups may be defined roughly according to the following topics or +activities: + +* Imaging +* Searchable coded texts +* National and international computer networks +* CD-ROM production and dissemination +* Methods and technology for converting older paper materials into +electronic form +* Study of the use of digital materials by scholars and others + +This summary is arranged thematically and does not follow the actual +sequence of presentations. + +NOTES: + (1) In this document, the phrase electronic text is used to mean + any computerized reproduction or version of a document, book, + article, or manuscript (including images), and not merely a machine- + readable or machine-searchable text. + + (2) The Workshop was held at the Library of Congress on 9-10 June + 1992, with funding from the David and Lucile Packard Foundation. + The document that follows represents a summary of the presentations + made at the Workshop and was compiled by James DALY. This + introduction was written by DALY and Carl FLEISCHHAUER. + + +PRESERVATION AND IMAGING + +Preservation, as that term is used by archivists,(3) was most explicitly +discussed in the context of imaging. Anne KENNEY and Lynne PERSONIUS +explained how the concept of a faithful copy and the user-friendliness of +the traditional book have guided their project at Cornell University.(4) +Although interested in computerized dissemination, participants in the +Cornell project are creating digital image sets of older books in the +public domain as a source for a fresh paper facsimile or, in a future +phase, microfilm. The books returned to the library shelves are +high-quality and useful replacements on acid-free paper that should last +a long time. To date, the Cornell project has placed little or no +emphasis on creating searchable texts; one would not be surprised to find +that the project participants view such texts as new editions, and thus +not as faithful reproductions. + +In her talk on preservation, Patricia BATTIN struck an ecumenical and +flexible note as she endorsed the creation and dissemination of a variety +of types of digital copies. Do not be too narrow in defining what counts +as a preservation element, BATTIN counseled; for the present, at least, +digital copies made with preservation in mind cannot be as narrowly +standardized as, say, microfilm copies with the same objective. Setting +standards precipitously can inhibit creativity, but delay can result in +chaos, she advised. + +In part, BATTIN's position reflected the unsettled nature of image-format +standards, and attendees could hear echoes of this unsettledness in the +comments of various speakers. For example, Jean BARONAS reviewed the +status of several formal standards moving through committees of experts; +and Clifford LYNCH encouraged the use of a new guideline for transmitting +document images on Internet. Testimony from participants in the National +Agricultural Library's (NAL) Text Digitization Program and LC's American +Memory project highlighted some of the challenges to the actual creation +or interchange of images, including difficulties in converting +preservation microfilm to digital form. Donald WATERS reported on the +progress of a master plan for a project at Yale University to convert +books on microfilm to digital image sets, Project Open Book (POB). + +The Workshop offered rather less of an imaging practicum than planned, +but "how-to" hints emerge at various points, for example, throughout +KENNEY's presentation and in the discussion of arcana such as +thresholding and dithering offered by George THOMA and FLEISCHHAUER. + +NOTES: + (3) Although there is a sense in which any reproductions of + historical materials preserve the human record, specialists in the + field have developed particular guidelines for the creation of + acceptable preservation copies. + + (4) Titles and affiliations of presenters are given at the + beginning of their respective talks and in the Directory of + Participants (Appendix III). + + +THE MACHINE-READABLE TEXT: MARKUP AND USE + +The sections of the Workshop that dealt with machine-readable text tended +to be more concerned with access and use than with preservation, at least +in the narrow technical sense. Michael SPERBERG-McQUEEN made a forceful +presentation on the Text Encoding Initiative's (TEI) implementation of +the Standard Generalized Markup Language (SGML). His ideas were echoed +by Susan HOCKEY, Elli MYLONAS, and Stuart WEIBEL. While the +presentations made by the TEI advocates contained no practicum, their +discussion focused on the value of the finished product, what the +European Community calls reusability, but what may also be termed +durability. They argued that marking up--that is, coding--a text in a +well-conceived way will permit it to be moved from one computer +environment to another, as well as to be used by various users. Two +kinds of markup were distinguished: 1) procedural markup, which +describes the features of a text (e.g., dots on a page), and 2) +descriptive markup, which describes the structure or elements of a +document (e.g., chapters, paragraphs, and front matter). + +The TEI proponents emphasized the importance of texts to scholarship. +They explained how heavily coded (and thus analyzed and annotated) texts +can underlie research, play a role in scholarly communication, and +facilitate classroom teaching. SPERBERG-McQUEEN reminded listeners that +a written or printed item (e.g., a particular edition of a book) is +merely a representation of the abstraction we call a text. To concern +ourselves with faithfully reproducing a printed instance of the text, +SPERBERG-McQUEEN argued, is to concern ourselves with the representation +of a representation ("images as simulacra for the text"). The TEI proponents' +interest in images tends to focus on corollary materials for use in teaching, +for example, photographs of the Acropolis to accompany a Greek text. + +By the end of the Workshop, SPERBERG-McQUEEN confessed to having been +converted to a limited extent to the view that electronic images +constitute a promising alternative to microfilming; indeed, an +alternative probably superior to microfilming. But he was not convinced +that electronic images constitute a serious attempt to represent text in +electronic form. HOCKEY and MYLONAS also conceded that their experience +at the Pierce Symposium the previous week at Georgetown University and +the present conference at the Library of Congress had compelled them to +reevaluate their perspective on the usefulness of text as images. +Attendees could see that the text and image advocates were in +constructive tension, so to say. + +Three nonTEI presentations described approaches to preparing +machine-readable text that are less rigorous and thus less expensive. In +the case of the Papers of George Washington, Dorothy TWOHIG explained +that the digital version will provide a not-quite-perfect rendering of +the transcribed text--some 135,000 documents, available for research +during the decades while the perfect or print version is completed. +Members of the American Memory team and the staff of NAL's Text +Digitization Program (see below) also outlined a middle ground concerning +searchable texts. In the case of American Memory, contractors produce +texts with about 99-percent accuracy that serve as "browse" or +"reference" versions of written or printed originals. End users who need +faithful copies or perfect renditions must refer to accompanying sets of +digital facsimile images or consult copies of the originals in a nearby +library or archive. American Memory staff argued that the high cost of +producing 100-percent accurate copies would prevent LC from offering +access to large parts of its collections. + + +THE MACHINE-READABLE TEXT: METHODS OF CONVERSION + +Although the Workshop did not include a systematic examination of the +methods for converting texts from paper (or from facsimile images) into +machine-readable form, nevertheless, various speakers touched upon this +matter. For example, WEIBEL reported that OCLC has experimented with a +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000. + +Pamela ANDRE presented an overview of NAL's Text Digitization Program and +Judith ZIDAR discussed the technical details. ZIDAR explained how NAL +purchased hardware and software capable of performing optical character +recognition (OCR) and text conversion and used its own staff to convert +texts. The process, ZIDAR said, required extensive editing and project +staff found themselves considering alternatives, including rekeying +and/or creating abstracts or summaries of texts. NAL reckoned costs at +$7 per page. By way of contrast, Ricky ERWAY explained that American +Memory had decided from the start to contract out conversion to external +service bureaus. The criteria used to select these contractors were cost +and quality of results, as opposed to methods of conversion. ERWAY noted +that historical documents or books often do not lend themselves to OCR. +Bound materials represent a special problem. In her experience, quality +control--inspecting incoming materials, counting errors in samples--posed +the most time-consuming aspect of contracting out conversion. ERWAY +reckoned American Memory's costs at $4 per page, but cautioned that fewer +cost-elements had been included than in NAL's figure. + + +OPTIONS FOR DISSEMINATION + +The topic of dissemination proper emerged at various points during the +Workshop. At the session devoted to national and international computer +networks, LYNCH, Howard BESSER, Ronald LARSEN, and Edwin BROWNRIGG +highlighted the virtues of Internet today and of the network that will +evolve from Internet. Listeners could discern in these narratives a +vision of an information democracy in which millions of citizens freely +find and use what they need. LYNCH noted that a lack of standards +inhibits disseminating multimedia on the network, a topic also discussed +by BESSER. LARSEN addressed the issues of network scalability and +modularity and commented upon the difficulty of anticipating the effects +of growth in orders of magnitude. BROWNRIGG talked about the ability of +packet radio to provide certain links in a network without the need for +wiring. However, the presenters also called attention to the +shortcomings and incongruities of present-day computer networks. For +example: 1) Network use is growing dramatically, but much network +traffic consists of personal communication (E-mail). 2) Large bodies of +information are available, but a user's ability to search across their +entirety is limited. 3) There are significant resources for science and +technology, but few network sources provide content in the humanities. +4) Machine-readable texts are commonplace, but the capability of the +system to deal with images (let alone other media formats) lags behind. +A glimpse of a multimedia future for networks, however, was provided by +Maria LEBRON in her overview of the Online Journal of Current Clinical +Trials (OJCCT), and the process of scholarly publishing on-line. + +The contrasting form of the CD-ROM disk was never systematically +analyzed, but attendees could glean an impression from several of the +show-and-tell presentations. The Perseus and American Memory examples +demonstrated recently published disks, while the descriptions of the +IBYCUS version of the Papers of George Washington and Chadwyck-Healey's +Patrologia Latina Database (PLD) told of disks to come. According to +Eric CALALUCA, PLD's principal focus has been on converting Jacques-Paul +Migne's definitive collection of Latin texts to machine-readable form. +Although everyone could share the network advocates' enthusiasm for an +on-line future, the possibility of rolling up one's sleeves for a session +with a CD-ROM containing both textual materials and a powerful retrieval +engine made the disk seem an appealing vessel indeed. The overall +discussion suggested that the transition from CD-ROM to on-line networked +access may prove far slower and more difficult than has been anticipated. + + +WHO ARE THE USERS AND WHAT DO THEY DO? + +Although concerned with the technicalities of production, the Workshop +never lost sight of the purposes and uses of electronic versions of +textual materials. As noted above, those interested in imaging discussed +the problematical matter of digital preservation, while the TEI proponents +described how machine-readable texts can be used in research. This latter +topic received thorough treatment in the paper read by Avra MICHELSON. +She placed the phenomenon of electronic texts within the context of +broader trends in information technology and scholarly communication. + +Among other things, MICHELSON described on-line conferences that +represent a vigorous and important intellectual forum for certain +disciplines. Internet now carries more than 700 conferences, with about +80 percent of these devoted to topics in the social sciences and the +humanities. Other scholars use on-line networks for "distance learning." +Meanwhile, there has been a tremendous growth in end-user computing; +professors today are less likely than their predecessors to ask the +campus computer center to process their data. Electronic texts are one +key to these sophisticated applications, MICHELSON reported, and more and +more scholars in the humanities now work in an on-line environment. +Toward the end of the Workshop, Michael LESK presented a corollary to +MICHELSON's talk, reporting the results of an experiment that compared +the work of one group of chemistry students using traditional printed +texts and two groups using electronic sources. The experiment +demonstrated that in the event one does not know what to read, one needs +the electronic systems; the electronic systems hold no advantage at the +moment if one knows what to read, but neither do they impose a penalty. + +DALY provided an anecdotal account of the revolutionizing impact of the +new technology on his previous methods of research in the field of classics. +His account, by extrapolation, served to illustrate in part the arguments +made by MICHELSON concerning the positive effects of the sudden and radical +transformation being wrought in the ways scholars work. + +Susan VECCIA and Joanne FREEMAN delineated the use of electronic +materials outside the university. The most interesting aspect of their +use, FREEMAN said, could be seen as a paradox: teachers in elementary +and secondary schools requested access to primary source materials but, +at the same time, found that "primariness" itself made these materials +difficult for their students to use. + + +OTHER TOPICS + +Marybeth PETERS reviewed copyright law in the United States and offered +advice during a lively discussion of this subject. But uncertainty +remains concerning the price of copyright in a digital medium, because a +solution remains to be worked out concerning management and synthesis of +copyrighted and out-of-copyright pieces of a database. + +As moderator of the final session of the Workshop, Prosser GIFFORD directed +discussion to future courses of action and the potential role of LC in +advancing them. Among the recommendations that emerged were the following: + + * Workshop participants should 1) begin to think about working + with image material, but structure and digitize it in such a + way that at a later stage it can be interpreted into text, and + 2) find a common way to build text and images together so that + they can be used jointly at some stage in the future, with + appropriate network support, because that is how users will want + to access these materials. The Library might encourage attempts + to bring together people who are working on texts and images. + + * A network version of American Memory should be developed or + consideration should be given to making the data in it + available to people interested in doing network multimedia. + Given the current dearth of digital data that is appealing and + unencumbered by extremely complex rights problems, developing a + network version of American Memory could do much to help make + network multimedia a reality. + + * Concerning the thorny issue of electronic deposit, LC should + initiate a catalytic process in terms of distributed + responsibility, that is, bring together the distributed + organizations and set up a study group to look at all the + issues related to electronic deposit and see where we as a + nation should move. For example, LC might attempt to persuade + one major library in each state to deal with its state + equivalent publisher, which might produce a cooperative project + that would be equitably distributed around the country, and one + in which LC would be dealing with a minimal number of publishers + and minimal copyright problems. LC must also deal with the + concept of on-line publishing, determining, among other things, + how serials such as OJCCT might be deposited for copyright. + + * Since a number of projects are planning to carry out + preservation by creating digital images that will end up in + on-line or near-line storage at some institution, LC might play + a helpful role, at least in the near term, by accelerating how + to catalog that information into the Research Library Information + Network (RLIN) and then into OCLC, so that it would be accessible. + This would reduce the possibility of multiple institutions digitizing + the same work. + + +CONCLUSION + +The Workshop was valuable because it brought together partisans from +various groups and provided an occasion to compare goals and methods. +The more committed partisans frequently communicate with others in their +groups, but less often across group boundaries. The Workshop was also +valuable to attendees--including those involved with American Memory--who +came less committed to particular approaches or concepts. These +attendees learned a great deal, and plan to select and employ elements of +imaging, text-coding, and networked distribution that suit their +respective projects and purposes. + +Still, reality rears its ugly head: no breakthrough has been achieved. +On the imaging side, one confronts a proliferation of competing +data-interchange standards and a lack of consensus on the role of digital +facsimiles in preservation. In the realm of machine-readable texts, one +encounters a reasonably mature standard but methodological difficulties +and high costs. These latter problems, of course, represent a special +impediment to the desire, as it is sometimes expressed in the popular +press, "to put the [contents of the] Library of Congress on line." In +the words of one participant, there was "no solution to the economic +problems--the projects that are out there are surviving, but it is going +to be a lot of work to transform the information industry, and so far the +investment to do that is not forthcoming" (LESK, per litteras). + + + *** *** *** ****** *** *** *** + + + PROCEEDINGS + + +WELCOME + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GIFFORD * Origin of Workshop in current Librarian's desire to make LC's +collections more widely available * Desiderata arising from the prospect +of greater interconnectedness * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +After welcoming participants on behalf of the Library of Congress, +American Memory (AM), and the National Demonstration Lab, Prosser +GIFFORD, director for scholarly programs, Library of Congress, located +the origin of the Workshop on Electronic Texts in a conversation he had +had considerably more than a year ago with Carl FLEISCHHAUER concerning +some of the issues faced by AM. On the assumption that numerous other +people were asking the same questions, the decision was made to bring +together as many of these people as possible to ask the same questions +together. In a deeper sense, GIFFORD said, the origin of the Workshop +lay in the desire of the current Librarian of Congress, James H. +Billington, to make the collections of the Library, especially those +offering unique or unusual testimony on aspects of the American +experience, available to a much wider circle of users than those few +people who can come to Washington to use them. This meant that the +emphasis of AM, from the outset, has been on archival collections of the +basic material, and on making these collections themselves available, +rather than selected or heavily edited products. + +From AM's emphasis followed the questions with which the Workshop began: +who will use these materials, and in what form will they wish to use +them. But an even larger issue deserving mention, in GIFFORD's view, was +the phenomenal growth in Internet connectivity. He expressed the hope +that the prospect of greater interconnectedness than ever before would +lead to: 1) much more cooperative and mutually supportive endeavors; 2) +development of systems of shared and distributed responsibilities to +avoid duplication and to ensure accuracy and preservation of unique +materials; and 3) agreement on the necessary standards and development of +the appropriate directories and indices to make navigation +straightforward among the varied resources that are, and increasingly +will be, available. In this connection, GIFFORD requested that +participants reflect from the outset upon the sorts of outcomes they +thought the Workshop might have. Did those present constitute a group +with sufficient common interests to propose a next step or next steps, +and if so, what might those be? They would return to these questions the +following afternoon. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * Core of Workshop concerns preparation and production of +materials * Special challenge in conversion of textual materials * +Quality versus quantity * Do the several groups represented share common +interests? * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +emphasized that he would attempt to represent the people who perform some +of the work of converting or preparing materials and that the core of +the Workshop had to do with preparation and production. FLEISCHHAUER +then drew a distinction between the long term, when many things would be +available and connected in the ways that GIFFORD described, and the short +term, in which AM not only has wrestled with the issue of what is the +best course to pursue but also has faced a variety of technical +challenges. + +FLEISCHHAUER remarked AM's endeavors to deal with a wide range of library +formats, such as motion picture collections, sound-recording collections, +and pictorial collections of various sorts, especially collections of +photographs. In the course of these efforts, AM kept coming back to +textual materials--manuscripts or rare printed matter, bound materials, +etc. Text posed the greatest conversion challenge of all. Thus, the +genesis of the Workshop, which reflects the problems faced by AM. These +problems include physical problems. For example, those in the library +and archive business deal with collections made up of fragile and rare +manuscript items, bound materials, especially the notoriously brittle +bound materials of the late nineteenth century. These are precious +cultural artifacts, however, as well as interesting sources of +information, and LC desires to retain and conserve them. AM needs to +handle things without damaging them. Guillotining a book to run it +through a sheet feeder must be avoided at all costs. + +Beyond physical problems, issues pertaining to quality arose. For +example, the desire to provide users with a searchable text is affected +by the question of acceptable level of accuracy. One hundred percent +accuracy is tremendously expensive. On the other hand, the output of +optical character recognition (OCR) can be tremendously inaccurate. +Although AM has attempted to find a middle ground, uncertainty persists +as to whether or not it has discovered the right solution. + +Questions of quality arose concerning images as well. FLEISCHHAUER +contrasted the extremely high level of quality of the digital images in +the Cornell Xerox Project with AM's efforts to provide a browse-quality +or access-quality image, as opposed to an archival or preservation image. +FLEISCHHAUER therefore welcomed the opportunity to compare notes. + +FLEISCHHAUER observed in passing that conversations he had had about +networks have begun to signal that for various forms of media a +determination may be made that there is a browse-quality item, or a +distribution-and-access-quality item that may coexist in some systems +with a higher quality archival item that would be inconvenient to send +through the network because of its size. FLEISCHHAUER referred, of +course, to images more than to searchable text. + +As AM considered those questions, several conceptual issues arose: ought +AM occasionally to reproduce materials entirely through an image set, at +other times, entirely through a text set, and in some cases, a mix? +There probably would be times when the historical authenticity of an +artifact would require that its image be used. An image might be +desirable as a recourse for users if one could not provide 100-percent +accurate text. Again, AM wondered, as a practical matter, if a +distinction could be drawn between rare printed matter that might exist +in multiple collections--that is, in ten or fifteen libraries. In such +cases, the need for perfect reproduction would be less than for unique +items. Implicit in his remarks, FLEISCHHAUER conceded, was the admission +that AM has been tilting strongly towards quantity and drawing back a +little from perfect quality. That is, it seemed to AM that society would +be better served if more things were distributed by LC--even if they were +not quite perfect--than if fewer things, perfectly represented, were +distributed. This was stated as a proposition to be tested, with +responses to be gathered from users. + +In thinking about issues related to reproduction of materials and seeing +other people engaged in parallel activities, AM deemed it useful to +convene a conference. Hence, the Workshop. FLEISCHHAUER thereupon +surveyed the several groups represented: 1) the world of images (image +users and image makers); 2) the world of text and scholarship and, within +this group, those concerned with language--FLEISCHHAUER confessed to finding +delightful irony in the fact that some of the most advanced thinkers on +computerized texts are those dealing with ancient Greek and Roman materials; +3) the network world; and 4) the general world of library science, which +includes people interested in preservation and cataloging. + +FLEISCHHAUER concluded his remarks with special thanks to the David and +Lucile Packard Foundation for its support of the meeting, the American +Memory group, the Office for Scholarly Programs, the National +Demonstration Lab, and the Office of Special Events. He expressed the +hope that David Woodley Packard might be able to attend, noting that +Packard's work and the work of the foundation had sponsored a number of +projects in the text area. + + ****** + +SESSION I. CONTENT IN A NEW FORM: WHO WILL USE IT AND WHAT WILL THEY DO? + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DALY * Acknowledgements * A new Latin authors disk * Effects of the new +technology on previous methods of research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Serving as moderator, James DALY acknowledged the generosity of all the +presenters for giving of their time, counsel, and patience in planning +the Workshop, as well as of members of the American Memory project and +other Library of Congress staff, and the David and Lucile Packard +Foundation and its executive director, Colburn S. Wilbur. + +DALY then recounted his visit in March to the Center for Electronic Texts +in the Humanities (CETH) and the Department of Classics at Rutgers +University, where an old friend, Lowell Edmunds, introduced him to the +department's IBYCUS scholarly personal computer, and, in particular, the +new Latin CD-ROM, containing, among other things, almost all classical +Latin literary texts through A.D. 200. Packard Humanities Institute +(PHI), Los Altos, California, released this disk late in 1991, with a +nominal triennial licensing fee. + +Playing with the disk for an hour or so at Rutgers brought home to DALY +at once the revolutionizing impact of the new technology on his previous +methods of research. Had this disk been available two or three years +earlier, DALY contended, when he was engaged in preparing a commentary on +Book 10 of Virgil's Aeneid for Cambridge University Press, he would not +have required a forty-eight-square-foot table on which to spread the +numerous, most frequently consulted items, including some ten or twelve +concordances to key Latin authors, an almost equal number of lexica to +authors who lacked concordances, and where either lexica or concordances +were lacking, numerous editions of authors antedating and postdating Virgil. + +Nor, when checking each of the average six to seven words contained in +the Virgilian hexameter for its usage elsewhere in Virgil's works or +other Latin authors, would DALY have had to maintain the laborious +mechanical process of flipping through these concordances, lexica, and +editions each time. Nor would he have had to frequent as often the +Milton S. Eisenhower Library at the Johns Hopkins University to consult +the Thesaurus Linguae Latinae. Instead of devoting countless hours, or +the bulk of his research time, to gathering data concerning Virgil's use +of words, DALY--now freed by PHI's Latin authors disk from the +tyrannical, yet in some ways paradoxically happy scholarly drudgery-- +would have been able to devote that same bulk of time to analyzing and +interpreting Virgilian verbal usage. + +Citing Theodore Brunner, Gregory Crane, Elli MYLONAS, and Avra MICHELSON, +DALY argued that this reversal in his style of work, made possible by the +new technology, would perhaps have resulted in better, more productive +research. Indeed, even in the course of his browsing the Latin authors +disk at Rutgers, its powerful search, retrieval, and highlighting +capabilities suggested to him several new avenues of research into +Virgil's use of sound effects. This anecdotal account, DALY maintained, +may serve to illustrate in part the sudden and radical transformation +being wrought in the ways scholars work. + + ****** + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MICHELSON * Elements related to scholarship and technology * Electronic +texts within the context of broader trends within information technology +and scholarly communication * Evaluation of the prospects for the use of +electronic texts * Relationship of electronic texts to processes of +scholarly communication in humanities research * New exchange formats +created by scholars * Projects initiated to increase scholarly access to +converted text * Trend toward making electronic resources available +through research and education networks * Changes taking place in +scholarly communication among humanities scholars * Network-mediated +scholarship transforming traditional scholarly practices * Key +information technology trends affecting the conduct of scholarly +communication over the next decade * The trend toward end-user computing +* The trend toward greater connectivity * Effects of these trends * Key +transformations taking place * Summary of principal arguments * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Avra MICHELSON, Archival Research and Evaluation Staff, National Archives +and Records Administration (NARA), argued that establishing who will use +electronic texts and what they will use them for involves a consideration +of both information technology and scholarship trends. This +consideration includes several elements related to scholarship and +technology: 1) the key trends in information technology that are most +relevant to scholarship; 2) the key trends in the use of currently +available technology by scholars in the nonscientific community; and 3) +the relationship between these two very distinct but interrelated trends. +The investment in understanding this relationship being made by +information providers, technologists, and public policy developers, as +well as by scholars themselves, seems to be pervasive and growing, +MICHELSON contended. She drew on collaborative work with Jeff Rothenberg +on the scholarly use of technology. + +MICHELSON sought to place the phenomenon of electronic texts within the +context of broader trends within information technology and scholarly +communication. She argued that electronic texts are of most use to +researchers to the extent that the researchers' working context (i.e., +their relevant bibliographic sources, collegial feedback, analytic tools, +notes, drafts, etc.), along with their field's primary and secondary +sources, also is accessible in electronic form and can be integrated in +ways that are unique to the on-line environment. + +Evaluation of the prospects for the use of electronic texts includes two +elements: 1) an examination of the ways in which researchers currently +are using electronic texts along with other electronic resources, and 2) +an analysis of key information technology trends that are affecting the +long-term conduct of scholarly communication. MICHELSON limited her +discussion of the use of electronic texts to the practices of humanists +and noted that the scientific community was outside the panel's overview. + +MICHELSON examined the nature of the current relationship of electronic +texts in particular, and electronic resources in general, to what she +maintained were, essentially, five processes of scholarly communication +in humanities research. Researchers 1) identify sources, 2) communicate +with their colleagues, 3) interpret and analyze data, 4) disseminate +their research findings, and 5) prepare curricula to instruct the next +generation of scholars and students. This examination would produce a +clearer understanding of the synergy among these five processes that +fuels the tendency of the use of electronic resources for one process to +stimulate its use for other processes of scholarly communication. + +For the first process of scholarly communication, the identification of +sources, MICHELSON remarked the opportunity scholars now enjoy to +supplement traditional word-of-mouth searches for sources among their +colleagues with new forms of electronic searching. So, for example, +instead of having to visit the library, researchers are able to explore +descriptions of holdings in their offices. Furthermore, if their own +institutions' holdings prove insufficient, scholars can access more than +200 major American library catalogues over Internet, including the +universities of California, Michigan, Pennsylvania, and Wisconsin. +Direct access to the bibliographic databases offers intellectual +empowerment to scholars by presenting a comprehensive means of browsing +through libraries from their homes and offices at their convenience. + +The second process of communication involves communication among +scholars. Beyond the most common methods of communication, scholars are +using E-mail and a variety of new electronic communications formats +derived from it for further academic interchange. E-mail exchanges are +growing at an astonishing rate, reportedly 15 percent a month. They +currently constitute approximately half the traffic on research and +education networks. Moreover, the global spread of E-mail has been so +rapid that it is now possible for American scholars to use it to +communicate with colleagues in close to 140 other countries. + +Other new exchange formats created by scholars and operating on Internet +include more than 700 conferences, with about 80 percent of these devoted +to topics in the social sciences and humanities. The rate of growth of +these scholarly electronic conferences also is astonishing. From l990 to +l991, 200 new conferences were identified on Internet. From October 1991 +to June 1992, an additional 150 conferences in the social sciences and +humanities were added to this directory of listings. Scholars have +established conferences in virtually every field, within every different +discipline. For example, there are currently close to 600 active social +science and humanities conferences on topics such as art and +architecture, ethnomusicology, folklore, Japanese culture, medical +education, and gifted and talented education. The appeal to scholars of +communicating through these conferences is that, unlike any other medium, +electronic conferences today provide a forum for global communication +with peers at the front end of the research process. + +Interpretation and analysis of sources constitutes the third process of +scholarly communication that MICHELSON discussed in terms of texts and +textual resources. The methods used to analyze sources fall somewhere on +a continuum from quantitative analysis to qualitative analysis. +Typically, evidence is culled and evaluated using methods drawn from both +ends of this continuum. At one end, quantitative analysis involves the +use of mathematical processes such as a count of frequencies and +distributions of occurrences or, on a higher level, regression analysis. +At the other end of the continuum, qualitative analysis typically +involves nonmathematical processes oriented toward language +interpretation or the building of theory. Aspects of this work involve +the processing--either manual or computational--of large and sometimes +massive amounts of textual sources, although the use of nontextual +sources as evidence, such as photographs, sound recordings, film footage, +and artifacts, is significant as well. + +Scholars have discovered that many of the methods of interpretation and +analysis that are related to both quantitative and qualitative methods +are processes that can be performed by computers. For example, computers +can count. They can count brush strokes used in a Rembrandt painting or +perform regression analysis for understanding cause and effect. By means +of advanced technologies, computers can recognize patterns, analyze text, +and model concepts. Furthermore, computers can complete these processes +faster with more sources and with greater precision than scholars who +must rely on manual interpretation of data. But if scholars are to use +computers for these processes, source materials must be in a form +amenable to computer-assisted analysis. For this reason many scholars, +once they have identified the sources that are key to their research, are +converting them to machine-readable form. Thus, a representative example +of the numerous textual conversion projects organized by scholars around +the world in recent years to support computational text analysis is the +TLG, the Thesaurus Linguae Graecae. This project is devoted to +converting the extant ancient texts of classical Greece. (Editor's note: +according to the TLG Newsletter of May l992, TLG was in use in thirty-two +different countries. This figure updates MICHELSON's previous count by one.) + +The scholars performing these conversions have been asked to recognize +that the electronic sources they are converting for one use possess value +for other research purposes as well. As a result, during the past few +years, humanities scholars have initiated a number of projects to +increase scholarly access to converted text. So, for example, the Text +Encoding Initiative (TEI), about which more is said later in the program, +was established as an effort by scholars to determine standard elements +and methods for encoding machine-readable text for electronic exchange. +In a second effort to facilitate the sharing of converted text, scholars +have created a new institution, the Center for Electronic Texts in the +Humanities (CETH). The center estimates that there are 8,000 series of +source texts in the humanities that have been converted to +machine-readable form worldwide. CETH is undertaking an international +search for converted text in the humanities, compiling it into an +electronic library, and preparing bibliographic descriptions of the +sources for the Research Libraries Information Network's (RLIN) +machine-readable data file. The library profession has begun to initiate +large conversion projects as well, such as American Memory. + +While scholars have been making converted text available to one another, +typically on disk or on CD-ROM, the clear trend is toward making these +resources available through research and education networks. Thus, the +American and French Research on the Treasury of the French Language +(ARTFL) and the Dante Project are already available on Internet. +MICHELSON summarized this section on interpretation and analysis by +noting that: 1) increasing numbers of humanities scholars in the library +community are recognizing the importance to the advancement of +scholarship of retrospective conversion of source materials in the arts +and humanities; and 2) there is a growing realization that making the +sources available on research and education networks maximizes their +usefulness for the analysis performed by humanities scholars. + +The fourth process of scholarly communication is dissemination of +research findings, that is, publication. Scholars are using existing +research and education networks to engineer a new type of publication: +scholarly-controlled journals that are electronically produced and +disseminated. Although such journals are still emerging as a +communication format, their number has grown, from approximately twelve +to thirty-six during the past year (July 1991 to June 1992). Most of +these electronic scholarly journals are devoted to topics in the +humanities. As with network conferences, scholarly enthusiasm for these +electronic journals stems from the medium's unique ability to advance +scholarship in a way that no other medium can do by supporting global +feedback and interchange, practically in real time, early in the research +process. Beyond scholarly journals, MICHELSON remarked the delivery of +commercial full-text products, such as articles in professional journals, +newsletters, magazines, wire services, and reference sources. These are +being delivered via on-line local library catalogues, especially through +CD-ROMs. Furthermore, according to MICHELSON, there is general optimism +that the copyright and fees issues impeding the delivery of full text on +existing research and education networks soon will be resolved. + +The final process of scholarly communication is curriculum development +and instruction, and this involves the use of computer information +technologies in two areas. The first is the development of +computer-oriented instructional tools, which includes simulations, +multimedia applications, and computer tools that are used to assist in +the analysis of sources in the classroom, etc. The Perseus Project, a +database that provides a multimedia curriculum on classical Greek +civilization, is a good example of the way in which entire curricula are +being recast using information technologies. It is anticipated that the +current difficulty in exchanging electronically computer-based +instructional software, which in turn makes it difficult for one scholar +to build upon the work of others, will be resolved before too long. +Stand-alone curricular applications that involve electronic text will be +shareable through networks, reinforcing their significance as intellectual +products as well as instructional tools. + +The second aspect of electronic learning involves the use of research and +education networks for distance education programs. Such programs +interactively link teachers with students in geographically scattered +locations and rely on the availability of electronic instructional +resources. Distance education programs are gaining wide appeal among +state departments of education because of their demonstrated capacity to +bring advanced specialized course work and an array of experts to many +classrooms. A recent report found that at least 32 states operated at +least one statewide network for education in 1991, with networks under +development in many of the remaining states. + +MICHELSON summarized this section by noting two striking changes taking +place in scholarly communication among humanities scholars. First is the +extent to which electronic text in particular, and electronic resources +in general, are being infused into each of the five processes described +above. As mentioned earlier, there is a certain synergy at work here. +The use of electronic resources for one process tends to stimulate its +use for other processes, because the chief course of movement is toward a +comprehensive on-line working context for humanities scholars that +includes on-line availability of key bibliographies, scholarly feedback, +sources, analytical tools, and publications. MICHELSON noted further +that the movement toward a comprehensive on-line working context for +humanities scholars is not new. In fact, it has been underway for more +than forty years in the humanities, since Father Roberto Busa began +developing an electronic concordance of the works of Saint Thomas Aquinas +in 1949. What we are witnessing today, MICHELSON contended, is not the +beginning of this on-line transition but, for at least some humanities +scholars, the turning point in the transition from a print to an +electronic working context. Coinciding with the on-line transition, the +second striking change is the extent to which research and education +networks are becoming the new medium of scholarly communication. The +existing Internet and the pending National Education and Research Network +(NREN) represent the new meeting ground where scholars are going for +bibliographic information, scholarly dialogue and feedback, the most +current publications in their field, and high-level educational +offerings. Traditional scholarly practices are undergoing tremendous +transformations as a result of the emergence and growing prominence of +what is called network-mediated scholarship. + +MICHELSON next turned to the second element of the framework she proposed +at the outset of her talk for evaluating the prospects for electronic +text, namely the key information technology trends affecting the conduct +of scholarly communication over the next decade: 1) end-user computing +and 2) connectivity. + +End-user computing means that the person touching the keyboard, or +performing computations, is the same as the person who initiates or +consumes the computation. The emergence of personal computers, along +with a host of other forces, such as ubiquitous computing, advances in +interface design, and the on-line transition, is prompting the consumers +of computation to do their own computing, and is thus rendering obsolete +the traditional distinction between end users and ultimate users. + +The trend toward end-user computing is significant to consideration of +the prospects for electronic texts because it means that researchers are +becoming more adept at doing their own computations and, thus, more +competent in the use of electronic media. By avoiding programmer +intermediaries, computation is becoming central to the researcher's +thought process. This direct involvement in computing is changing the +researcher's perspective on the nature of research itself, that is, the +kinds of questions that can be posed, the analytical methodologies that +can be used, the types and amount of sources that are appropriate for +analyses, and the form in which findings are presented. The trend toward +end-user computing means that, increasingly, electronic media and +computation are being infused into all processes of humanities +scholarship, inspiring remarkable transformations in scholarly +communication. + +The trend toward greater connectivity suggests that researchers are using +computation increasingly in network environments. Connectivity is +important to scholarship because it erases the distance that separates +students from teachers and scholars from their colleagues, while allowing +users to access remote databases, share information in many different +media, connect to their working context wherever they are, and +collaborate in all phases of research. + +The combination of the trend toward end-user computing and the trend +toward connectivity suggests that the scholarly use of electronic +resources, already evident among some researchers, will soon become an +established feature of scholarship. The effects of these trends, along +with ongoing changes in scholarly practices, point to a future in which +humanities researchers will use computation and electronic communication +to help them formulate ideas, access sources, perform research, +collaborate with colleagues, seek peer review, publish and disseminate +results, and engage in many other professional and educational activities. + +In summary, MICHELSON emphasized four points: 1) A portion of humanities +scholars already consider electronic texts the preferred format for +analysis and dissemination. 2) Scholars are using these electronic +texts, in conjunction with other electronic resources, in all the +processes of scholarly communication. 3) The humanities scholars' +working context is in the process of changing from print technology to +electronic technology, in many ways mirroring transformations that have +occurred or are occurring within the scientific community. 4) These +changes are occurring in conjunction with the development of a new +communication medium: research and education networks that are +characterized by their capacity to advance scholarship in a wholly unique +way. + +MICHELSON also reiterated her three principal arguments: l) Electronic +texts are best understood in terms of the relationship to other +electronic resources and the growing prominence of network-mediated +scholarship. 2) The prospects for electronic texts lie in their capacity +to be integrated into the on-line network of electronic resources that +comprise the new working context for scholars. 3) Retrospective conversion +of portions of the scholarly record should be a key strategy as information +providers respond to changes in scholarly communication practices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +VECCIA * AM's evaluation project and public users of electronic resources +* AM and its design * Site selection and evaluating the Macintosh +implementation of AM * Characteristics of the six public libraries +selected * Characteristics of AM's users in these libraries * Principal +ways AM is being used * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan VECCIA, team leader, and Joanne FREEMAN, associate coordinator, +American Memory, Library of Congress, gave a joint presentation. First, +by way of introduction, VECCIA explained her and FREEMAN's roles in +American Memory (AM). Serving principally as an observer, VECCIA has +assisted with the evaluation project of AM, placing AM collections in a +variety of different sites around the country and helping to organize and +implement that project. FREEMAN has been an associate coordinator of AM +and has been involved principally with the interpretative materials, +preparing some of the electronic exhibits and printed historical +information that accompanies AM and that is requested by users. VECCIA +and FREEMAN shared anecdotal observations concerning AM with public users +of electronic resources. Notwithstanding a fairly structured evaluation +in progress, both VECCIA and FREEMAN chose not to report on specifics in +terms of numbers, etc., because they felt it was too early in the +evaluation project to do so. + +AM is an electronic archive of primary source materials from the Library +of Congress, selected collections representing a variety of formats-- +photographs, graphic arts, recorded sound, motion pictures, broadsides, +and soon, pamphlets and books. In terms of the design of this system, +the interpretative exhibits have been kept separate from the primary +resources, with good reason. Accompanying this collection are printed +documentation and user guides, as well as guides that FREEMAN prepared for +teachers so that they may begin using the content of the system at once. + +VECCIA described the evaluation project before talking about the public +users of AM, limiting her remarks to public libraries, because FREEMAN +would talk more specifically about schools from kindergarten to twelfth +grade (K-12). Having started in spring 1991, the evaluation currently +involves testing of the Macintosh implementation of AM. Since the +primary goal of this evaluation is to determine the most appropriate +audience or audiences for AM, very different sites were selected. This +makes evaluation difficult because of the varying degrees of technology +literacy among the sites. AM is situated in forty-four locations, of +which six are public libraries and sixteen are schools. Represented +among the schools are elementary, junior high, and high schools. +District offices also are involved in the evaluation, which will +conclude in summer 1993. + +VECCIA focused the remainder of her talk on the six public libraries, one +of which doubles as a state library. They represent a range of +geographic areas and a range of demographic characteristics. For +example, three are located in urban settings, two in rural settings, and +one in a suburban setting. A range of technical expertise is to be found +among these facilities as well. For example, one is an "Apple library of +the future," while two others are rural one-room libraries--in one, AM +sits at the front desk next to a tractor manual. + +All public libraries have been extremely enthusiastic, supportive, and +appreciative of the work that AM has been doing. VECCIA characterized +various users: Most users in public libraries describe themselves as +general readers; of the students who use AM in the public libraries, +those in fourth grade and above seem most interested. Public libraries +in rural sites tend to attract retired people, who have been highly +receptive to AM. Users tend to fall into two additional categories: +people interested in the content and historical connotations of these +primary resources, and those fascinated by the technology. The format +receiving the most comments has been motion pictures. The adult users in +public libraries are more comfortable with IBM computers, whereas young +people seem comfortable with either IBM or Macintosh, although most of +them seem to come from a Macintosh background. This same tendency is +found in the schools. + +What kinds of things do users do with AM? In a public library there are +two main goals or ways that AM is being used: as an individual learning +tool, and as a leisure activity. Adult learning was one area that VECCIA +would highlight as a possible application for a tool such as AM. She +described a patron of a rural public library who comes in every day on +his lunch hour and literally reads AM, methodically going through the +collection image by image. At the end of his hour he makes an electronic +bookmark, puts it in his pocket, and returns to work. The next day he +comes in and resumes where he left off. Interestingly, this man had +never been in the library before he used AM. In another small, rural +library, the coordinator reports that AM is a popular activity for some +of the older, retired people in the community, who ordinarily would not +use "those things,"--computers. Another example of adult learning in +public libraries is book groups, one of which, in particular, is using AM +as part of its reading on industrialization, integration, and urbanization +in the early 1900s. + +One library reports that a family is using AM to help educate their +children. In another instance, individuals from a local museum came in +to use AM to prepare an exhibit on toys of the past. These two examples +emphasize the mission of the public library as a cultural institution, +reaching out to people who do not have the same resources available to +those who live in a metropolitan area or have access to a major library. +One rural library reports that junior high school students in large +numbers came in one afternoon to use AM for entertainment. A number of +public libraries reported great interest among postcard collectors in the +Detroit collection, which was essentially a collection of images used on +postcards around the turn of the century. Train buffs are similarly +interested because that was a time of great interest in railroading. +People, it was found, relate to things that they know of firsthand. For +example, in both rural public libraries where AM was made available, +observers reported that the older people with personal remembrances of +the turn of the century were gravitating to the Detroit collection. +These examples served to underscore MICHELSON's observation re the +integration of electronic tools and ideas--that people learn best when +the material relates to something they know. + +VECCIA made the final point that in many cases AM serves as a +public-relations tool for the public libraries that are testing it. In +one case, AM is being used as a vehicle to secure additional funding for +the library. In another case, AM has served as an inspiration to the +staff of a major local public library in the South to think about ways to +make its own collection of photographs more accessible to the public. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FREEMAN * AM and archival electronic resources in a school environment * +Questions concerning context * Questions concerning the electronic format +itself * Computer anxiety * Access and availability of the system * +Hardware * Strengths gained through the use of archival resources in +schools * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Reiterating an observation made by VECCIA, that AM is an archival +resource made up of primary materials with very little interpretation, +FREEMAN stated that the project has attempted to bridge the gap between +these bare primary materials and a school environment, and in that cause +has created guided introductions to AM collections. Loud demand from the +educational community, chiefly from teachers working with the upper +grades of elementary school through high school, greeted the announcement +that AM would be tested around the country. + +FREEMAN reported not only on what was learned about AM in a school +environment, but also on several universal questions that were raised +concerning archival electronic resources in schools. She discussed +several strengths of this type of material in a school environment as +opposed to a highly structured resource that offers a limited number of +paths to follow. + +FREEMAN first raised several questions about using AM in a school +environment. There is often some difficulty in developing a sense of +what the system contains. Many students sit down at a computer resource +and assume that, because AM comes from the Library of Congress, all of +American history is now at their fingertips. As a result of that sort of +mistaken judgment, some students are known to conclude that AM contains +nothing of use to them when they look for one or two things and do not +find them. It is difficult to discover that middle ground where one has +a sense of what the system contains. Some students grope toward the idea +of an archive, a new idea to them, since they have not previously +experienced what it means to have access to a vast body of somewhat +random information. + +Other questions raised by FREEMAN concerned the electronic format itself. +For instance, in a school environment it is often difficult both for +teachers and students to gain a sense of what it is they are viewing. +They understand that it is a visual image, but they do not necessarily +know that it is a postcard from the turn of the century, a panoramic +photograph, or even machine-readable text of an eighteenth-century +broadside, a twentieth-century printed book, or a nineteenth-century +diary. That distinction is often difficult for people in a school +environment to grasp. Because of that, it occasionally becomes difficult +to draw conclusions from what one is viewing. + +FREEMAN also noted the obvious fear of the computer, which constitutes a +difficulty in using an electronic resource. Though students in general +did not suffer from this anxiety, several older students feared that they +were computer-illiterate, an assumption that became self-fulfilling when +they searched for something but failed to find it. FREEMAN said she +believed that some teachers also fear computer resources, because they +believe they lack complete control. FREEMAN related the example of +teachers shooing away students because it was not their time to use the +system. This was a case in which the situation had to be extremely +structured so that the teachers would not feel that they had lost their +grasp on what the system contained. + +A final question raised by FREEMAN concerned access and availability of +the system. She noted the occasional existence of a gap in communication +between school librarians and teachers. Often AM sits in a school +library and the librarian is the person responsible for monitoring the +system. Teachers do not always take into their world new library +resources about which the librarian is excited. Indeed, at the sites +where AM had been used most effectively within a library, the librarian +was required to go to specific teachers and instruct them in its use. As +a result, several AM sites will have in-service sessions over a summer, +in the hope that perhaps, with a more individualized link, teachers will +be more likely to use the resource. + +A related issue in the school context concerned the number of +workstations available at any one location. Centralization of equipment +at the district level, with teachers invited to download things and walk +away with them, proved unsuccessful because the hours these offices were +open were also school hours. + +Another issue was hardware. As VECCIA observed, a range of sites exists, +some technologically advanced and others essentially acquiring their +first computer for the primary purpose of using it in conjunction with +AM's testing. Users at technologically sophisticated sites want even +more sophisticated hardware, so that they can perform even more +sophisticated tasks with the materials in AM. But once they acquire a +newer piece of hardware, they must learn how to use that also; at an +unsophisticated site it takes an extremely long time simply to become +accustomed to the computer, not to mention the program offered with the +computer. All of these small issues raise one large question, namely, +are systems like AM truly rewarding in a school environment, or do they +simply act as innovative toys that do little more than spark interest? + +FREEMAN contended that the evaluation project has revealed several strengths +that were gained through the use of archival resources in schools, including: + + * Psychic rewards from using AM as a vast, rich database, with + teachers assigning various projects to students--oral presentations, + written reports, a documentary, a turn-of-the-century newspaper-- + projects that start with the materials in AM but are completed using + other resources; AM thus is used as a research tool in conjunction + with other electronic resources, as well as with books and items in + the library where the system is set up. + + * Students are acquiring computer literacy in a humanities context. + + * This sort of system is overcoming the isolation between disciplines + that often exists in schools. For example, many English teachers are + requiring their students to write papers on historical topics + represented in AM. Numerous teachers have reported that their + students are learning critical thinking skills using the system. + + * On a broader level, AM is introducing primary materials, not only + to students but also to teachers, in an environment where often + simply none exist--an exciting thing for the students because it + helps them learn to conduct research, to interpret, and to draw + their own conclusions. In learning to conduct research and what it + means, students are motivated to seek knowledge. That relates to + another positive outcome--a high level of personal involvement of + students with the materials in this system and greater motivation to + conduct their own research and draw their own conclusions. + + * Perhaps the most ironic strength of these kinds of archival + electronic resources is that many of the teachers AM interviewed + were desperate, it is no exaggeration to say, not only for primary + materials but for unstructured primary materials. These would, they + thought, foster personally motivated research, exploration, and + excitement in their students. Indeed, these materials have done + just that. Ironically, however, this lack of structure produces + some of the confusion to which the newness of these kinds of + resources may also contribute. The key to effective use of archival + products in a school environment is a clear, effective introduction + to the system and to what it contains. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Nothing known, quantitatively, about the number of +humanities scholars who must see the original versus those who would +settle for an edited transcript, or about the ways in which humanities +scholars are using information technology * Firm conclusions concerning +the manner and extent of the use of supporting materials in print +provided by AM to await completion of evaluative study * A listener's +reflections on additional applications of electronic texts * Role of +electronic resources in teaching elementary research skills to students * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed the presentations by MICHELSON, +VECCIA, and FREEMAN, additional points emerged. + +LESK asked if MICHELSON could give any quantitative estimate of the +number of humanities scholars who must see or want to see the original, +or the best possible version of the material, versus those who typically +would settle for an edited transcript. While unable to provide a figure, +she offered her impressions as an archivist who has done some reference +work and has discussed this issue with other archivists who perform +reference, that those who use archives and those who use primary sources +for what would be considered very high-level scholarly research, as +opposed to, say, undergraduate papers, were few in number, especially +given the public interest in using primary sources to conduct +genealogical or avocational research and the kind of professional +research done by people in private industry or the federal government. +More important in MICHELSON's view was that, quantitatively, nothing is +known about the ways in which, for example, humanities scholars are using +information technology. No studies exist to offer guidance in creating +strategies. The most recent study was conducted in 1985 by the American +Council of Learned Societies (ACLS), and what it showed was that 50 +percent of humanities scholars at that time were using computers. That +constitutes the extent of our knowledge. + +Concerning AM's strategy for orienting people toward the scope of +electronic resources, FREEMAN could offer no hard conclusions at this +point, because she and her colleagues were still waiting to see, +particularly in the schools, what has been made of their efforts. Within +the system, however, AM has provided what are called electronic exhibits- +-such as introductions to time periods and materials--and these are +intended to offer a student user a sense of what a broadside is and what +it might tell her or him. But FREEMAN conceded that the project staff +would have to talk with students next year, after teachers have had a +summer to use the materials, and attempt to discover what the students +were learning from the materials. In addition, FREEMAN described +supporting materials in print provided by AM at the request of local +teachers during a meeting held at LC. These included time lines, +bibliographies, and other materials that could be reproduced on a +photocopier in a classroom. Teachers could walk away with and use these, +and in this way gain a better understanding of the contents. But again, +reaching firm conclusions concerning the manner and extent of their use +would have to wait until next year. + +As to the changes she saw occurring at the National Archives and Records +Administration (NARA) as a result of the increasing emphasis on +technology in scholarly research, MICHELSON stated that NARA at this +point was absorbing the report by her and Jeff Rothenberg addressing +strategies for the archival profession in general, although not for the +National Archives specifically. NARA is just beginning to establish its +role and what it can do. In terms of changes and initiatives that NARA +can take, no clear response could be given at this time. + +GREENFIELD remarked two trends mentioned in the session. Reflecting on +DALY's opening comments on how he could have used a Latin collection of +text in an electronic form, he said that at first he thought most scholars +would be unwilling to do that. But as he thought of that in terms of the +original meaning of research--that is, having already mastered these texts, +researching them for critical and comparative purposes--for the first time, +the electronic format made a lot of sense. GREENFIELD could envision +growing numbers of scholars learning the new technologies for that very +aspect of their scholarship and for convenience's sake. + +Listening to VECCIA and FREEMAN, GREENFIELD thought of an additional +application of electronic texts. He realized that AM could be used as a +guide to lead someone to original sources. Students cannot be expected +to have mastered these sources, things they have never known about +before. Thus, AM is leading them, in theory, to a vast body of +information and giving them a superficial overview of it, enabling them +to select parts of it. GREENFIELD asked if any evidence exists that this +resource will indeed teach the new user, the K-12 students, how to do +research. Scholars already know how to do research and are applying +these new tools. But he wondered why students would go beyond picking +out things that were most exciting to them. + +FREEMAN conceded the correctness of GREENFIELD's observation as applied +to a school environment. The risk is that a student would sit down at a +system, play with it, find some things of interest, and then walk away. +But in the relatively controlled situation of a school library, much will +depend on the instructions a teacher or a librarian gives a student. She +viewed the situation not as one of fine-tuning research skills but of +involving students at a personal level in understanding and researching +things. Given the guidance one can receive at school, it then becomes +possible to teach elementary research skills to students, which in fact +one particular librarian said she was teaching her fifth graders. +FREEMAN concluded that introducing the idea of following one's own path +of inquiry, which is essentially what research entails, involves more +than teaching specific skills. To these comments VECCIA added the +observation that the individual teacher and the use of a creative +resource, rather than AM itself, seemed to make the key difference. +Some schools and some teachers are making excellent use of the nature +of critical thinking and teaching skills, she said. + +Concurring with these remarks, DALY closed the session with the thought that +the more that producers produced for teachers and for scholars to use with +their students, the more successful their electronic products would prove. + + ****** + +SESSION II. SHOW AND TELL + +Jacqueline HESS, director, National Demonstration Laboratory, served as +moderator of the "show-and-tell" session. She noted that a +question-and-answer period would follow each presentation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MYLONAS * Overview and content of Perseus * Perseus' primary materials +exist in a system-independent, archival form * A concession * Textual +aspects of Perseus * Tools to use with the Greek text * Prepared indices +and full-text searches in Perseus * English-Greek word search leads to +close study of words and concepts * Navigating Perseus by tracing down +indices * Using the iconography to perform research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Elli MYLONAS, managing editor, Perseus Project, Harvard University, first +gave an overview of Perseus, a large, collaborative effort based at +Harvard University but with contributors and collaborators located at +numerous universities and colleges in the United States (e.g., Bowdoin, +Maryland, Pomona, Chicago, Virginia). Funded primarily by the +Annenberg/CPB Project, with additional funding from Apple, Harvard, and +the Packard Humanities Institute, among others, Perseus is a multimedia, +hypertextual database for teaching and research on classical Greek +civilization, which was released in February 1992 in version 1.0 and +distributed by Yale University Press. + +Consisting entirely of primary materials, Perseus includes ancient Greek +texts and translations of those texts; catalog entries--that is, museum +catalog entries, not library catalog entries--on vases, sites, coins, +sculpture, and archaeological objects; maps; and a dictionary, among +other sources. The number of objects and the objects for which catalog +entries exist are accompanied by thousands of color images, which +constitute a major feature of the database. Perseus contains +approximately 30 megabytes of text, an amount that will double in +subsequent versions. In addition to these primary materials, the Perseus +Project has been building tools for using them, making access and +navigation easier, the goal being to build part of the electronic +environment discussed earlier in the morning in which students or +scholars can work with their sources. + +The demonstration of Perseus will show only a fraction of the real work +that has gone into it, because the project had to face the dilemma of +what to enter when putting something into machine-readable form: should +one aim for very high quality or make concessions in order to get the +material in? Since Perseus decided to opt for very high quality, all of +its primary materials exist in a system-independent--insofar as it is +possible to be system-independent--archival form. Deciding what that +archival form would be and attaining it required much work and thought. +For example, all the texts are marked up in SGML, which will be made +compatible with the guidelines of the Text Encoding Initiative (TEI) when +they are issued. + +Drawings are postscript files, not meeting international standards, but +at least designed to go across platforms. Images, or rather the real +archival forms, consist of the best available slides, which are being +digitized. Much of the catalog material exists in database form--a form +that the average user could use, manipulate, and display on a personal +computer, but only at great cost. Thus, this is where the concession +comes in: All of this rich, well-marked-up information is stripped of +much of its content; the images are converted into bit-maps and the text +into small formatted chunks. All this information can then be imported +into HyperCard and run on a mid-range Macintosh, which is what Perseus +users have. This fact has made it possible for Perseus to attain wide +use fairly rapidly. Without those archival forms the HyperCard version +being demonstrated could not be made easily, and the project could not +have the potential to move to other forms and machines and software as +they appear, none of which information is in Perseus on the CD. + +Of the numerous multimedia aspects of Perseus, MYLONAS focused on the +textual. Part of what makes Perseus such a pleasure to use, MYLONAS +said, is this effort at seamless integration and the ability to move +around both visual and textual material. Perseus also made the decision +not to attempt to interpret its material any more than one interprets by +selecting. But, MYLONAS emphasized, Perseus is not courseware: No +syllabus exists. There is no effort to define how one teaches a topic +using Perseus, although the project may eventually collect papers by +people who have used it to teach. Rather, Perseus aims to provide +primary material in a kind of electronic library, an electronic sandbox, +so to say, in which students and scholars who are working on this +material can explore by themselves. With that, MYLONAS demonstrated +Perseus, beginning with the Perseus gateway, the first thing one sees +upon opening Perseus--an effort in part to solve the contextualizing +problem--which tells the user what the system contains. + +MYLONAS demonstrated only a very small portion, beginning with primary +texts and running off the CD-ROM. Having selected Aeschylus' Prometheus +Bound, which was viewable in Greek and English pretty much in the same +segments together, MYLONAS demonstrated tools to use with the Greek text, +something not possible with a book: looking up the dictionary entry form +of an unfamiliar word in Greek after subjecting it to Perseus' +morphological analysis for all the texts. After finding out about a +word, a user may then decide to see if it is used anywhere else in Greek. +Because vast amounts of indexing support all of the primary material, one +can find out where else all forms of a particular Greek word appear-- +often not a trivial matter because Greek is highly inflected. Further, +since the story of Prometheus has to do with the origins of sacrifice, a +user may wish to study and explore sacrifice in Greek literature; by +typing sacrifice into a small window, a user goes to the English-Greek +word list--something one cannot do without the computer (Perseus has +indexed the definitions of its dictionary)--the string sacrifice appears +in the definitions of these sixty-five words. One may then find out +where any of those words is used in the work(s) of a particular author. +The English definitions are not lemmatized. + +All of the indices driving this kind of usage were originally devised for +speed, MYLONAS observed; in other words, all that kind of information-- +all forms of all words, where they exist, the dictionary form they belong +to--were collected into databases, which will expedite searching. Then +it was discovered that one can do things searching in these databases +that could not be done searching in the full texts. Thus, although there +are full-text searches in Perseus, much of the work is done behind the +scenes, using prepared indices. Re the indexing that is done behind the +scenes, MYLONAS pointed out that without the SGML forms of the text, it +could not be done effectively. Much of this indexing is based on the +structures that are made explicit by the SGML tagging. + +It was found that one of the things many of Perseus' non-Greek-reading +users do is start from the dictionary and then move into the close study +of words and concepts via this kind of English-Greek word search, by which +means they might select a concept. This exercise has been assigned to +students in core courses at Harvard--to study a concept by looking for the +English word in the dictionary, finding the Greek words, and then finding +the words in the Greek but, of course, reading across in the English. +That tells them a great deal about what a translation means as well. + +Should one also wish to see images that have to do with sacrifice, that +person would go to the object key word search, which allows one to +perform a similar kind of index retrieval on the database of +archaeological objects. Without words, pictures are useless; Perseus has +not reached the point where it can do much with images that are not +cataloged. Thus, although it is possible in Perseus with text and images +to navigate by knowing where one wants to end up--for example, a +red-figure vase from the Boston Museum of Fine Arts--one can perform this +kind of navigation very easily by tracing down indices. MYLONAS +illustrated several generic scenes of sacrifice on vases. The features +demonstrated derived from Perseus 1.0; version 2.0 will implement even +better means of retrieval. + +MYLONAS closed by looking at one of the pictures and noting again that +one can do a great deal of research using the iconography as well as the +texts. For instance, students in a core course at Harvard this year were +highly interested in Greek concepts of foreigners and representations of +non-Greeks. So they performed a great deal of research, both with texts +(e.g., Herodotus) and with iconography on vases and coins, on how the +Greeks portrayed non-Greeks. At the same time, art historians who study +iconography were also interested, and were able to use this material. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Indexing and searchability of all English words in Perseus * +Several features of Perseus 1.0 * Several levels of customization +possible * Perseus used for general education * Perseus' effects on +education * Contextual information in Perseus * Main challenge and +emphasis of Perseus * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Several points emerged in the discussion that followed MYLONAS's presentation. + +Although MYLONAS had not demonstrated Perseus' ability to cross-search +documents, she confirmed that all English words in Perseus are indexed +and can be searched. So, for example, sacrifice could have been searched +in all texts, the historical essay, and all the catalogue entries with +their descriptions--in short, in all of Perseus. + +Boolean logic is not in Perseus 1.0 but will be added to the next +version, although an effort is being made not to restrict Perseus to a +database in which one just performs searching, Boolean or otherwise. It +is possible to move laterally through the documents by selecting a word +one is interested in and selecting an area of information one is +interested in and trying to look that word up in that area. + +Since Perseus was developed in HyperCard, several levels of customization +are possible. Simple authoring tools exist that allow one to create +annotated paths through the information, which are useful for note-taking +and for guided tours for teaching purposes and for expository writing. +With a little more ingenuity it is possible to begin to add or substitute +material in Perseus. + +Perseus has not been used so much for classics education as for general +education, where it seemed to have an impact on the students in the core +course at Harvard (a general required course that students must take in +certain areas). Students were able to use primary material much more. + +The Perseus Project has an evaluation team at the University of Maryland +that has been documenting Perseus' effects on education. Perseus is very +popular, and anecdotal evidence indicates that it is having an effect at +places other than Harvard, for example, test sites at Ball State +University, Drury College, and numerous small places where opportunities +to use vast amounts of primary data may not exist. One documented effect +is that archaeological, anthropological, and philological research is +being done by the same person instead of by three different people. + +The contextual information in Perseus includes an overview essay, a +fairly linear historical essay on the fifth century B.C. that provides +links into the primary material (e.g., Herodotus, Thucydides, and +Plutarch), via small gray underscoring (on the screen) of linked +passages. These are handmade links into other material. + +To different extents, most of the production work was done at Harvard, +where the people and the equipment are located. Much of the +collaborative activity involved data collection and structuring, because +the main challenge and the emphasis of Perseus is the gathering of +primary material, that is, building a useful environment for studying +classical Greece, collecting data, and making it useful. +Systems-building is definitely not the main concern. Thus, much of the +work has involved writing essays, collecting information, rewriting it, +and tagging it. That can be done off site. The creative link for the +overview essay as well as for both systems and data was collaborative, +and was forged via E-mail and paper mail with professors at Pomona and +Bowdoin. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * PLD's principal focus and contribution to scholarship * +Various questions preparatory to beginning the project * Basis for +project * Basic rule in converting PLD * Concerning the images in PLD * +Running PLD under a variety of retrieval software * Encoding the +database a hard-fought issue * Various features demonstrated * Importance +of user documentation * Limitations of the CD-ROM version * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Eric CALALUCA, vice president, Chadwyck-Healey, Inc., demonstrated a +software interpretation of the Patrologia Latina Database (PLD). PLD's +principal focus from the beginning of the project about three-and-a-half +years ago was on converting Migne's Latin series, and in the end, +CALALUCA suggested, conversion of the text will be the major contribution +to scholarship. CALALUCA stressed that, as possibly the only private +publishing organization at the Workshop, Chadwyck-Healey had sought no +federal funds or national foundation support before embarking upon the +project, but instead had relied upon a great deal of homework and +marketing to accomplish the task of conversion. + +Ever since the possibilities of computer-searching have emerged, scholars +in the field of late ancient and early medieval studies (philosophers, +theologians, classicists, and those studying the history of natural law +and the history of the legal development of Western civilization) have +been longing for a fully searchable version of Western literature, for +example, all the texts of Augustine and Bernard of Clairvaux and +Boethius, not to mention all the secondary and tertiary authors. + +Various questions arose, CALALUCA said. Should one convert Migne? +Should the database be encoded? Is it necessary to do that? How should +it be delivered? What about CD-ROM? Since this is a transitional +medium, why even bother to create software to run on a CD-ROM? Since +everybody knows people will be networking information, why go to the +trouble--which is far greater with CD-ROM than with the production of +magnetic data? Finally, how does one make the data available? Can many +of the hurdles to using electronic information that some publishers have +imposed upon databases be eliminated? + +The PLD project was based on the principle that computer-searching of +texts is most effective when it is done with a large database. Because +PLD represented a collection that serves so many disciplines across so +many periods, it was irresistible. + +The basic rule in converting PLD was to do no harm, to avoid the sins of +intrusion in such a database: no introduction of newer editions, no +on-the-spot changes, no eradicating of all possible falsehoods from an +edition. Thus, PLD is not the final act in electronic publishing for +this discipline, but simply the beginning. The conversion of PLD has +evoked numerous unanticipated questions: How will information be used? +What about networking? Can the rights of a database be protected? +Should one protect the rights of a database? How can it be made +available? + +Those converting PLD also tried to avoid the sins of omission, that is, +excluding portions of the collections or whole sections. What about the +images? PLD is full of images, some are extremely pious +nineteenth-century representations of the Fathers, while others contain +highly interesting elements. The goal was to cover all the text of Migne +(including notes, in Greek and in Hebrew, the latter of which, in +particular, causes problems in creating a search structure), all the +indices, and even the images, which are being scanned in separately +searchable files. + +Several North American institutions that have placed acquisition requests +for the PLD database have requested it in magnetic form without software, +which means they are already running it without software, without +anything demonstrated at the Workshop. + +What cannot practically be done is go back and reconvert and re-encode +data, a time-consuming and extremely costly enterprise. CALALUCA sees +PLD as a database that can, and should, be run under a variety of +retrieval software. This will permit the widest possible searches. +Consequently, the need to produce a CD-ROM of PLD, as well as to develop +software that could handle some 1.3 gigabyte of heavily encoded text, +developed out of conversations with collection development and reference +librarians who wanted software both compassionate enough for the +pedestrian but also capable of incorporating the most detailed +lexicographical studies that a user desires to conduct. In the end, the +encoding and conversion of the data will prove the most enduring +testament to the value of the project. + +The encoding of the database was also a hard-fought issue: Did the +database need to be encoded? Were there normative structures for encoding +humanist texts? Should it be SGML? What about the TEI--will it last, +will it prove useful? CALALUCA expressed some minor doubts as to whether +a data bank can be fully TEI-conformant. Every effort can be made, but +in the end to be TEI-conformant means to accept the need to make some +firm encoding decisions that can, indeed, be disputed. The TEI points +the publisher in a proper direction but does not presume to make all the +decisions for him or her. Essentially, the goal of encoding was to +eliminate, as much as possible, the hindrances to information-networking, +so that if an institution acquires a database, everybody associated with +the institution can have access to it. + +CALALUCA demonstrated a portion of Volume 160, because it had the most +anomalies in it. The software was created by Electronic Book +Technologies of Providence, RI, and is called Dynatext. The software +works only with SGML-coded data. + +Viewing a table of contents on the screen, the audience saw how Dynatext +treats each element as a book and attempts to simplify movement through a +volume. Familiarity with the Patrologia in print (i.e., the text, its +source, and the editions) will make the machine-readable versions highly +useful. (Software with a Windows application was sought for PLD, +CALALUCA said, because this was the main trend for scholarly use.) + +CALALUCA also demonstrated how a user can perform a variety of searches +and quickly move to any part of a volume; the look-up screen provides +some basic, simple word-searching. + +CALALUCA argued that one of the major difficulties is not the software. +Rather, in creating a product that will be used by scholars representing +a broad spectrum of computer sophistication, user documentation proves +to be the most important service one can provide. + +CALALUCA next illustrated a truncated search under mysterium within ten +words of virtus and how one would be able to find its contents throughout +the entire database. He said that the exciting thing about PLD is that +many of the applications in the retrieval software being written for it +will exceed the capabilities of the software employed now for the CD-ROM +version. The CD-ROM faces genuine limitations, in terms of speed and +comprehensiveness, in the creation of a retrieval software to run it. +CALALUCA said he hoped that individual scholars will download the data, +if they wish, to their personal computers, and have ready access to +important texts on a constant basis, which they will be able to use in +their research and from which they might even be able to publish. + +(CALALUCA explained that the blue numbers represented Migne's column numbers, +which are the standard scholarly references. Pulling up a note, he stated +that these texts were heavily edited and the image files would appear simply +as a note as well, so that one could quickly access an image.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER/ERWAY * Several problems with which AM is still wrestling * +Various search and retrieval capabilities * Illustration of automatic +stemming and a truncated search * AM's attempt to find ways to connect +cataloging to the texts * AM's gravitation towards SGML * Striking a +balance between quantity and quality * How AM furnishes users recourse to +images * Conducting a search in a full-text environment * Macintosh and +IBM prototypes of AM * Multimedia aspects of AM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A demonstration of American Memory by its coordinator, Carl FLEISCHHAUER, +and Ricky ERWAY, associate coordinator, Library of Congress, concluded +the morning session. Beginning with a collection of broadsides from the +Continental Congress and the Constitutional Convention, the only text +collection in a presentable form at the time of the Workshop, FLEISCHHAUER +highlighted several of the problems with which AM is still wrestling. +(In its final form, the disk will contain two collections, not only the +broadsides but also the full text with illustrations of a set of +approximately 300 African-American pamphlets from the period 1870 to 1910.) + +As FREEMAN had explained earlier, AM has attempted to use a small amount +of interpretation to introduce collections. In the present case, the +contractor, a company named Quick Source, in Silver Spring, MD., used +software called Toolbook and put together a modestly interactive +introduction to the collection. Like the two preceding speakers, +FLEISCHHAUER argued that the real asset was the underlying collection. + +FLEISCHHAUER proceeded to describe various search and retrieval +capabilities while ERWAY worked the computer. In this particular package +the "go to" pull-down allowed the user in effect to jump out of Toolbook, +where the interactive program was located, and enter the third-party +software used by AM for this text collection, which is called Personal +Librarian. This was the Windows version of Personal Librarian, a +software application put together by a company in Rockville, Md. + +Since the broadsides came from the Revolutionary War period, a search was +conducted using the words British or war, with the default operator reset +as or. FLEISCHHAUER demonstrated both automatic stemming (which finds +other forms of the same root) and a truncated search. One of Personal +Librarian's strongest features, the relevance ranking, was represented by +a chart that indicated how often words being sought appeared in +documents, with the one receiving the most "hits" obtaining the highest +score. The "hit list" that is supplied takes the relevance ranking into +account, making the first hit, in effect, the one the software has +selected as the most relevant example. + +While in the text of one of the broadside documents, FLEISCHHAUER +remarked AM's attempt to find ways to connect cataloging to the texts, +which it does in different ways in different manifestations. In the case +shown, the cataloging was pasted on: AM took MARC records that were +written as on-line records right into one of the Library's mainframe +retrieval programs, pulled them out, and handed them off to the contractor, +who massaged them somewhat to display them in the manner shown. One of +AM's questions is, Does the cataloguing normally performed in the mainframe +work in this context, or had AM ought to think through adjustments? + +FLEISCHHAUER made the additional point that, as far as the text goes, AM +has gravitated towards SGML (he pointed to the boldface in the upper part +of the screen). Although extremely limited in its ability to translate +or interpret SGML, Personal Librarian will furnish both bold and italics +on screen; a fairly easy thing to do, but it is one of the ways in which +SGML is useful. + +Striking a balance between quantity and quality has been a major concern +of AM, with accuracy being one of the places where project staff have +felt that less than 100-percent accuracy was not unacceptable. +FLEISCHHAUER cited the example of the standard of the rekeying industry, +namely 99.95 percent; as one service bureau informed him, to go from +99.95 to 100 percent would double the cost. + +FLEISCHHAUER next demonstrated how AM furnishes users recourse to images, +and at the same time recalled LESK's pointed question concerning the +number of people who would look at those images and the number who would +work only with the text. If the implication of LESK's question was +sound, FLEISCHHAUER said, it raised the stakes for text accuracy and +reduced the value of the strategy for images. + +Contending that preservation is always a bugaboo, FLEISCHHAUER +demonstrated several images derived from a scan of a preservation +microfilm that AM had made. He awarded a grade of C at best, perhaps a +C minus or a C plus, for how well it worked out. Indeed, the matter of +learning if other people had better ideas about scanning in general, and, +in particular, scanning from microfilm, was one of the factors that drove +AM to attempt to think through the agenda for the Workshop. Skew, for +example, was one of the issues that AM in its ignorance had not reckoned +would prove so difficult. + +Further, the handling of images of the sort shown, in a desktop computer +environment, involved a considerable amount of zooming and scrolling. +Ultimately, AM staff feel that perhaps the paper copy that is printed out +might be the most useful one, but they remain uncertain as to how much +on-screen reading users will do. + +Returning to the text, FLEISCHHAUER asked viewers to imagine a person who +might be conducting a search in a full-text environment. With this +scenario, he proceeded to illustrate other features of Personal Librarian +that he considered helpful; for example, it provides the ability to +notice words as one reads. Clicking the "include" button on the bottom +of the search window pops the words that have been highlighted into the +search. Thus, a user can refine the search as he or she reads, +re-executing the search and continuing to find things in the quest for +materials. This software not only contains relevance ranking, Boolean +operators, and truncation, it also permits one to perform word algebra, +so to say, where one puts two or three words in parentheses and links +them with one Boolean operator and then a couple of words in another set +of parentheses and asks for things within so many words of others. + +Until they became acquainted recently with some of the work being done in +classics, the AM staff had not realized that a large number of the +projects that involve electronic texts were being done by people with a +profound interest in language and linguistics. Their search strategies +and thinking are oriented to those fields, as is shown in particular by +the Perseus example. As amateur historians, the AM staff were thinking +more of searching for concepts and ideas than for particular words. +Obviously, FLEISCHHAUER conceded, searching for concepts and ideas and +searching for words may be two rather closely related things. + +While displaying several images, FLEISCHHAUER observed that the Macintosh +prototype built by AM contains a greater diversity of formats. Echoing a +previous speaker, he said that it was easier to stitch things together in +the Macintosh, though it tended to be a little more anemic in search and +retrieval. AM, therefore, increasingly has been investigating +sophisticated retrieval engines in the IBM format. + +FLEISCHHAUER demonstrated several additional examples of the prototype +interfaces: One was AM's metaphor for the network future, in which a +kind of reading-room graphic suggests how one would be able to go around +to different materials. AM contains a large number of photographs in +analog video form worked up from a videodisc, which enable users to make +copies to print or incorporate in digital documents. A frame-grabber is +built into the system, making it possible to bring an image into a window +and digitize or print it out. + +FLEISCHHAUER next demonstrated sound recording, which included texts. +Recycled from a previous project, the collection included sixty 78-rpm +phonograph records of political speeches that were made during and +immediately after World War I. These constituted approximately three +hours of audio, as AM has digitized it, which occupy 150 megabytes on a +CD. Thus, they are considerably compressed. From the catalogue card, +FLEISCHHAUER proceeded to a transcript of a speech with the audio +available and with highlighted text following it as it played. +A photograph has been added and a transcription made. + +Considerable value has been added beyond what the Library of Congress +normally would do in cataloguing a sound recording, which raises several +questions for AM concerning where to draw lines about how much value it can +afford to add and at what point, perhaps, this becomes more than AM could +reasonably do or reasonably wish to do. FLEISCHHAUER also demonstrated +a motion picture. As FREEMAN had reported earlier, the motion picture +materials have proved the most popular, not surprisingly. This says more +about the medium, he thought, than about AM's presentation of it. + +Because AM's goal was to bring together things that could be used by +historians or by people who were curious about history, +turn-of-the-century footage seemed to represent the most appropriate +collections from the Library of Congress in motion pictures. These were +the very first films made by Thomas Edison's company and some others at +that time. The particular example illustrated was a Biograph film, +brought in with a frame-grabber into a window. A single videodisc +contains about fifty titles and pieces of film from that period, all of +New York City. Taken together, AM believes, they provide an interesting +documentary resource. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Using the frame-grabber in AM * Volume of material processed +and to be processed * Purpose of AM within LC * Cataloguing and the +nature of AM's material * SGML coding and the question of quality versus +quantity * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed FLEISCHHAUER's +presentation, several clarifications were made. + +AM is bringing in motion pictures from a videodisc. The frame-grabber +devices create a window on a computer screen, which permits users to +digitize a single frame of the movie or one of the photographs. It +produces a crude, rough-and-ready image that high school students can +incorporate into papers, and that has worked very nicely in this way. + +Commenting on FLEISCHHAUER's assertion that AM was looking more at +searching ideas than words, MYLONAS argued that without words an idea +does not exist. FLEISCHHAUER conceded that he ought to have articulated +his point more clearly. MYLONAS stated that they were in fact both +talking about the same thing. By searching for words and by forcing +people to focus on the word, the Perseus Project felt that they would get +them to the idea. The way one reviews results is tailored more to one +kind of user than another. + +Concerning the total volume of material that has been processed in this +way, AM at this point has in retrievable form seven or eight collections, +all of them photographic. In the Macintosh environment, for example, +there probably are 35,000-40,000 photographs. The sound recordings +number sixty items. The broadsides number about 300 items. There are +500 political cartoons in the form of drawings. The motion pictures, as +individual items, number sixty to seventy. + +AM also has a manuscript collection, the life history portion of one of +the federal project series, which will contain 2,900 individual +documents, all first-person narratives. AM has in process about 350 +African-American pamphlets, or about 12,000 printed pages for the period +1870-1910. Also in the works are some 4,000 panoramic photographs. AM +has recycled a fair amount of the work done by LC's Prints and +Photographs Division during the Library's optical disk pilot project in +the 1980s. For example, a special division of LC has tooled up and +thought through all the ramifications of electronic presentation of +photographs. Indeed, they are wheeling them out in great barrel loads. +The purpose of AM within the Library, it is hoped, is to catalyze several +of the other special collection divisions which have no particular +experience with, in some cases, mixed feelings about, an activity such as +AM. Moreover, in many cases the divisions may be characterized as not +only lacking experience in "electronifying" things but also in automated +cataloguing. MARC cataloguing as practiced in the United States is +heavily weighted toward the description of monograph and serial +materials, but is much thinner when one enters the world of manuscripts +and things that are held in the Library's music collection and other +units. In response to a comment by LESK, that AM's material is very +heavily photographic, and is so primarily because individual records have +been made for each photograph, FLEISCHHAUER observed that an item-level +catalog record exists, for example, for each photograph in the Detroit +Publishing collection of 25,000 pictures. In the case of the Federal +Writers Project, for which nearly 3,000 documents exist, representing +information from twenty-six different states, AM with the assistance of +Karen STUART of the Manuscript Division will attempt to find some way not +only to have a collection-level record but perhaps a MARC record for each +state, which will then serve as an umbrella for the 100-200 documents +that come under it. But that drama remains to be enacted. The AM staff +is conservative and clings to cataloguing, though of course visitors tout +artificial intelligence and neural networks in a manner that suggests that +perhaps one need not have cataloguing or that much of it could be put aside. + +The matter of SGML coding, FLEISCHHAUER conceded, returned the discussion +to the earlier treated question of quality versus quantity in the Library +of Congress. Of course, text conversion can be done with 100-percent +accuracy, but it means that when one's holdings are as vast as LC's only +a tiny amount will be exposed, whereas permitting lower levels of +accuracy can lead to exposing or sharing larger amounts, but with the +quality correspondingly impaired. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TWOHIG * A contrary experience concerning electronic options * Volume of +material in the Washington papers and a suggestion of David Packard * +Implications of Packard's suggestion * Transcribing the documents for the +CD-ROM * Accuracy of transcriptions * The CD-ROM edition of the Founding +Fathers documents * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Finding encouragement in a comment of MICHELSON's from the morning +session--that numerous people in the humanities were choosing electronic +options to do their work--Dorothy TWOHIG, editor, The Papers of George +Washington, opened her illustrated talk by noting that her experience +with literary scholars and numerous people in editing was contrary to +MICHELSON's. TWOHIG emphasized literary scholars' complete ignorance of +the technological options available to them or their reluctance or, in +some cases, their downright hostility toward these options. + +After providing an overview of the five Founding Fathers projects +(Jefferson at Princeton, Franklin at Yale, John Adams at the +Massachusetts Historical Society, and Madison down the hall from her at +the University of Virginia), TWOHIG observed that the Washington papers, +like all of the projects, include both sides of the Washington +correspondence and deal with some 135,000 documents to be published with +extensive annotation in eighty to eighty-five volumes, a project that +will not be completed until well into the next century. Thus, it was +with considerable enthusiasm several years ago that the Washington Papers +Project (WPP) greeted David Packard's suggestion that the papers of the +Founding Fathers could be published easily and inexpensively, and to the +great benefit of American scholarship, via CD-ROM. + +In pragmatic terms, funding from the Packard Foundation would expedite +the transcription of thousands of documents waiting to be put on disk in +the WPP offices. Further, since the costs of collecting, editing, and +converting the Founding Fathers documents into letterpress editions were +running into the millions of dollars, and the considerable staffs +involved in all of these projects were devoting their careers to +producing the work, the Packard Foundation's suggestion had a +revolutionary aspect: Transcriptions of the entire corpus of the +Founding Fathers papers would be available on CD-ROM to public and +college libraries, even high schools, at a fraction of the cost-- +$100-$150 for the annual license fee--to produce a limited university +press run of 1,000 of each volume of the published papers at $45-$150 per +printed volume. Given the current budget crunch in educational systems +and the corresponding constraints on librarians in smaller institutions +who wish to add these volumes to their collections, producing the +documents on CD-ROM would likely open a greatly expanded audience for the +papers. TWOHIG stressed, however, that development of the Founding +Fathers CD-ROM is still in its infancy. Serious software problems remain +to be resolved before the material can be put into readable form. + +Funding from the Packard Foundation resulted in a major push to +transcribe the 75,000 or so documents of the Washington papers remaining +to be transcribed onto computer disks. Slides illustrated several of the +problems encountered, for example, the present inability of CD-ROM to +indicate the cross-outs (deleted material) in eighteenth century +documents. TWOHIG next described documents from various periods in the +eighteenth century that have been transcribed in chronological order and +delivered to the Packard offices in California, where they are converted +to the CD-ROM, a process that is expected to consume five years to +complete (that is, reckoning from David Packard's suggestion made several +years ago, until about July 1994). TWOHIG found an encouraging +indication of the project's benefits in the ongoing use made by scholars +of the search functions of the CD-ROM, particularly in reducing the time +spent in manually turning the pages of the Washington papers. + +TWOHIG next furnished details concerning the accuracy of transcriptions. +For instance, the insertion of thousands of documents on the CD-ROM +currently does not permit each document to be verified against the +original manuscript several times as in the case of documents that appear +in the published edition. However, the transcriptions receive a cursory +check for obvious typos, the misspellings of proper names, and other +errors from the WPP CD-ROM editor. Eventually, all documents that appear +in the electronic version will be checked by project editors. Although +this process has met with opposition from some of the editors on the +grounds that imperfect work may leave their offices, the advantages in +making this material available as a research tool outweigh fears about the +misspelling of proper names and other relatively minor editorial matters. + +Completion of all five Founding Fathers projects (i.e., retrievability +and searchability of all of the documents by proper names, alternate +spellings, or varieties of subjects) will provide one of the richest +sources of this size for the history of the United States in the latter +part of the eighteenth century. Further, publication on CD-ROM will +allow editors to include even minutiae, such as laundry lists, not +included in the printed volumes. + +It seems possible that the extensive annotation provided in the printed +volumes eventually will be added to the CD-ROM edition, pending +negotiations with the publishers of the papers. At the moment, the +Founding Fathers CD-ROM is accessible only on the IBYCUS, a computer +developed out of the Thesaurus Linguae Graecae project and designed for +the use of classical scholars. There are perhaps 400 IBYCUS computers in +the country, most of which are in university classics departments. +Ultimately, it is anticipated that the CD-ROM edition of the Founding +Fathers documents will run on any IBM-compatible or Macintosh computer +with a CD-ROM drive. Numerous changes in the software will also occur +before the project is completed. (Editor's note: an IBYCUS was +unavailable to demonstrate the CD-ROM.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Several additional features of WPP clarified * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Discussion following TWOHIG's presentation served to clarify several +additional features, including (1) that the project's primary +intellectual product consists in the electronic transcription of the +material; (2) that the text transmitted to the CD-ROM people is not +marked up; (3) that cataloging and subject-indexing of the material +remain to be worked out (though at this point material can be retrieved +by name); and (4) that because all the searching is done in the hardware, +the IBYCUS is designed to read a CD-ROM which contains only sequential +text files. Technically, it then becomes very easy to read the material +off and put it on another device. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LEBRON * Overview of the history of the joint project between AAAS and +OCLC * Several practices the on-line environment shares with traditional +publishing on hard copy * Several technical and behavioral barriers to +electronic publishing * How AAAS and OCLC arrived at the subject of +clinical trials * Advantages of the electronic format and other features +of OJCCT * An illustrated tour of the journal * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Maria LEBRON, managing editor, The Online Journal of Current Clinical +Trials (OJCCT), presented an illustrated overview of the history of the +joint project between the American Association for the Advancement of +Science (AAAS) and the Online Computer Library Center, Inc. (OCLC). The +joint venture between AAAS and OCLC owes its beginning to a +reorganization launched by the new chief executive officer at OCLC about +three years ago and combines the strengths of these two disparate +organizations. In short, OJCCT represents the process of scholarly +publishing on line. + +LEBRON next discussed several practices the on-line environment shares +with traditional publishing on hard copy--for example, peer review of +manuscripts--that are highly important in the academic world. LEBRON +noted in particular the implications of citation counts for tenure +committees and grants committees. In the traditional hard-copy +environment, citation counts are readily demonstrable, whereas the +on-line environment represents an ethereal medium to most academics. + +LEBRON remarked several technical and behavioral barriers to electronic +publishing, for instance, the problems in transmission created by special +characters or by complex graphics and halftones. In addition, she noted +economic limitations such as the storage costs of maintaining back issues +and market or audience education. + +Manuscripts cannot be uploaded to OJCCT, LEBRON explained, because it is +not a bulletin board or E-mail, forms of electronic transmission of +information that have created an ambience clouding people's understanding +of what the journal is attempting to do. OJCCT, which publishes +peer-reviewed medical articles dealing with the subject of clinical +trials, includes text, tabular material, and graphics, although at this +time it can transmit only line illustrations. + +Next, LEBRON described how AAAS and OCLC arrived at the subject of +clinical trials: It is 1) a highly statistical discipline that 2) does +not require halftones but can satisfy the needs of its audience with line +illustrations and graphic material, and 3) there is a need for the speedy +dissemination of high-quality research results. Clinical trials are +research activities that involve the administration of a test treatment +to some experimental unit in order to test its usefulness before it is +made available to the general population. LEBRON proceeded to give +additional information on OJCCT concerning its editor-in-chief, editorial +board, editorial content, and the types of articles it publishes +(including peer-reviewed research reports and reviews), as well as +features shared by other traditional hard-copy journals. + +Among the advantages of the electronic format are faster dissemination of +information, including raw data, and the absence of space constraints +because pages do not exist. (This latter fact creates an interesting +situation when it comes to citations.) Nor are there any issues. AAAS's +capacity to download materials directly from the journal to a +subscriber's printer, hard drive, or floppy disk helps ensure highly +accurate transcription. Other features of OJCCT include on-screen alerts +that allow linkage of subsequently published documents to the original +documents; on-line searching by subject, author, title, etc.; indexing of +every single word that appears in an article; viewing access to an +article by component (abstract, full text, or graphs); numbered +paragraphs to replace page counts; publication in Science every thirty +days of indexing of all articles published in the journal; +typeset-quality screens; and Hypertext links that enable subscribers to +bring up Medline abstracts directly without leaving the journal. + +After detailing the two primary ways to gain access to the journal, +through the OCLC network and Compuserv if one desires graphics or through +the Internet if just an ASCII file is desired, LEBRON illustrated the +speedy editorial process and the coding of the document using SGML tags +after it has been accepted for publication. She also gave an illustrated +tour of the journal, its search-and-retrieval capabilities in particular, +but also including problems associated with scanning in illustrations, +and the importance of on-screen alerts to the medical profession re +retractions or corrections, or more frequently, editorials, letters to +the editors, or follow-up reports. She closed by inviting the audience +to join AAAS on 1 July, when OJCCT was scheduled to go on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional features of OJCCT * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the lengthy discussion that followed LEBRON's presentation, these +points emerged: + + * The SGML text can be tailored as users wish. + + * All these articles have a fairly simple document definition. + + * Document-type definitions (DTDs) were developed and given to OJCCT + for coding. + + * No articles will be removed from the journal. (Because there are + no back issues, there are no lost issues either. Once a subscriber + logs onto the journal he or she has access not only to the currently + published materials, but retrospectively to everything that has been + published in it. Thus the table of contents grows bigger. The date + of publication serves to distinguish between currently published + materials and older materials.) + + * The pricing system for the journal resembles that for most medical + journals: for 1992, $95 for a year, plus telecommunications charges + (there are no connect time charges); for 1993, $110 for the + entire year for single users, though the journal can be put on a + local area network (LAN). However, only one person can access the + journal at a time. Site licenses may come in the future. + + * AAAS is working closely with colleagues at OCLC to display + mathematical equations on screen. + + * Without compromising any steps in the editorial process, the + technology has reduced the time lag between when a manuscript is + originally submitted and the time it is accepted; the review process + does not differ greatly from the standard six-to-eight weeks + employed by many of the hard-copy journals. The process still + depends on people. + + * As far as a preservation copy is concerned, articles will be + maintained on the computer permanently and subscribers, as part of + their subscription, will receive a microfiche-quality archival copy + of everything published during that year; in addition, reprints can + be purchased in much the same way as in a hard-copy environment. + Hard copies are prepared but are not the primary medium for the + dissemination of the information. + + * Because OJCCT is not yet on line, it is difficult to know how many + people would simply browse through the journal on the screen as + opposed to downloading the whole thing and printing it out; a mix of + both types of users likely will result. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PERSONIUS * Developments in technology over the past decade * The CLASS +Project * Advantages for technology and for the CLASS Project * +Developing a network application an underlying assumption of the project +* Details of the scanning process * Print-on-demand copies of books * +Future plans include development of a browsing tool * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Lynne PERSONIUS, assistant director, Cornell Information Technologies for +Scholarly Information Services, Cornell University, first commented on +the tremendous impact that developments in technology over the past ten +years--networking, in particular--have had on the way information is +handled, and how, in her own case, these developments have counterbalanced +Cornell's relative geographical isolation. Other significant technologies +include scanners, which are much more sophisticated than they were ten years +ago; mass storage and the dramatic savings that result from it in terms of +both space and money relative to twenty or thirty years ago; new and +improved printing technologies, which have greatly affected the distribution +of information; and, of course, digital technologies, whose applicability to +library preservation remains at issue. + +Given that context, PERSONIUS described the College Library Access and +Storage System (CLASS) Project, a library preservation project, +primarily, and what has been accomplished. Directly funded by the +Commission on Preservation and Access and by the Xerox Corporation, which +has provided a significant amount of hardware, the CLASS Project has been +working with a development team at Xerox to develop a software +application tailored to library preservation requirements. Within +Cornell, participants in the project have been working jointly with both +library and information technologies. The focus of the project has been +on reformatting and saving books that are in brittle condition. +PERSONIUS showed Workshop participants a brittle book, and described how +such books were the result of developments in papermaking around the +beginning of the Industrial Revolution. The papermaking process was +changed so that a significant amount of acid was introduced into the +actual paper itself, which deteriorates as it sits on library shelves. + +One of the advantages for technology and for the CLASS Project is that +the information in brittle books is mostly out of copyright and thus +offers an opportunity to work with material that requires library +preservation, and to create and work on an infrastructure to save the +material. Acknowledging the familiarity of those working in preservation +with this information, PERSONIUS noted that several things are being +done: the primary preservation technology used today is photocopying of +brittle material. Saving the intellectual content of the material is the +main goal. With microfilm copy, the intellectual content is preserved on +the assumption that in the future the image can be reformatted in any +other way that then exists. + +An underlying assumption of the CLASS Project from the beginning was +that it would develop a network application. Project staff scan books +at a workstation located in the library, near the brittle material. +An image-server filing system is located at a distance from that +workstation, and a printer is located in another building. All of the +materials digitized and stored on the image-filing system are cataloged +in the on-line catalogue. In fact, a record for each of these electronic +books is stored in the RLIN database so that a record exists of what is +in the digital library throughout standard catalogue procedures. In the +future, researchers working from their own workstations in their offices, +or their networks, will have access--wherever they might be--through a +request server being built into the new digital library. A second +assumption is that the preferred means of finding the material will be by +looking through a catalogue. PERSONIUS described the scanning process, +which uses a prototype scanner being developed by Xerox and which scans a +very high resolution image at great speed. Another significant feature, +because this is a preservation application, is the placing of the pages +that fall apart one for one on the platen. Ordinarily, a scanner could +be used with some sort of a document feeder, but because of this +application that is not feasible. Further, because CLASS is a +preservation application, after the paper replacement is made there, a +very careful quality control check is performed. An original book is +compared to the printed copy and verification is made, before proceeding, +that all of the image, all of the information, has been captured. Then, +a new library book is produced: The printed images are rebound by a +commercial binder and a new book is returned to the shelf. +Significantly, the books returned to the library shelves are beautiful +and useful replacements on acid-free paper that should last a long time, +in effect, the equivalent of preservation photocopies. Thus, the project +has a library of digital books. In essence, CLASS is scanning and +storing books as 600 dot-per-inch bit-mapped images, compressed using +Group 4 CCITT (i.e., the French acronym for International Consultative +Committee for Telegraph and Telephone) compression. They are stored as +TIFF files on an optical filing system that is composed of a database +used for searching and locating the books and an optical jukebox that +stores 64 twelve-inch platters. A very-high-resolution printed copy of +these books at 600 dots per inch is created, using a Xerox DocuTech +printer to make the paper replacements on acid-free paper. + +PERSONIUS maintained that the CLASS Project presents an opportunity to +introduce people to books as digital images by using a paper medium. +Books are returned to the shelves while people are also given the ability +to print on demand--to make their own copies of books. (PERSONIUS +distributed copies of an engineering journal published by engineering +students at Cornell around 1900 as an example of what a print-on-demand +copy of material might be like. This very cheap copy would be available +to people to use for their own research purposes and would bridge the gap +between an electronic work and the paper that readers like to have.) +PERSONIUS then attempted to illustrate a very early prototype of +networked access to this digital library. Xerox Corporation has +developed a prototype of a view station that can send images across the +network to be viewed. + +The particular library brought down for demonstration contained two +mathematics books. CLASS is developing and will spend the next year +developing an application that allows people at workstations to browse +the books. Thus, CLASS is developing a browsing tool, on the assumption +that users do not want to read an entire book from a workstation, but +would prefer to be able to look through and decide if they would like to +have a printed copy of it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Re retrieval software * "Digital file copyright" * Scanning +rate during production * Autosegmentation * Criteria employed in +selecting books for scanning * Compression and decompression of images * +OCR not precluded * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed her presentation, +PERSONIUS made these additional points: + + * Re retrieval software, Cornell is developing a Unix-based server + as well as clients for the server that support multiple platforms + (Macintosh, IBM and Sun workstations), in the hope that people from + any of those platforms will retrieve books; a further operating + assumption is that standard interfaces will be used as much as + possible, where standards can be put in place, because CLASS + considers this retrieval software a library application and would + like to be able to look at material not only at Cornell but at other + institutions. + + * The phrase "digital file copyright by Cornell University" was + added at the advice of Cornell's legal staff with the caveat that it + probably would not hold up in court. Cornell does not want people + to copy its books and sell them but would like to keep them + available for use in a library environment for library purposes. + + * In production the scanner can scan about 300 pages per hour, + capturing 600 dots per inch. + + * The Xerox software has filters to scan halftone material and avoid + the moire patterns that occur when halftone material is scanned. + Xerox has been working on hardware and software that would enable + the scanner itself to recognize this situation and deal with it + appropriately--a kind of autosegmentation that would enable the + scanner to handle halftone material as well as text on a single page. + + * The books subjected to the elaborate process described above were + selected because CLASS is a preservation project, with the first 500 + books selected coming from Cornell's mathematics collection, because + they were still being heavily used and because, although they were + in need of preservation, the mathematics library and the mathematics + faculty were uncomfortable having them microfilmed. (They wanted a + printed copy.) Thus, these books became a logical choice for this + project. Other books were chosen by the project's selection committees + for experiments with the technology, as well as to meet a demand or need. + + * Images will be decompressed before they are sent over the line; at + this time they are compressed and sent to the image filing system + and then sent to the printer as compressed images; they are returned + to the workstation as compressed 600-dpi images and the workstation + decompresses and scales them for display--an inefficient way to + access the material though it works quite well for printing and + other purposes. + + * CLASS is also decompressing on Macintosh and IBM, a slow process + right now. Eventually, compression and decompression will take + place on an image conversion server. Trade-offs will be made, based + on future performance testing, concerning where the file is + compressed and what resolution image is sent. + + * OCR has not been precluded; images are being stored that have been + scanned at a high resolution, which presumably would suit them well + to an OCR process. Because the material being scanned is about 100 + years old and was printed with less-than-ideal technologies, very + early and preliminary tests have not produced good results. But the + project is capturing an image that is of sufficient resolution to be + subjected to OCR in the future. Moreover, the system architecture + and the system plan have a logical place to store an OCR image if it + has been captured. But that is not being done now. + + ****** + +SESSION III. DISTRIBUTION, NETWORKS, AND NETWORKING: OPTIONS FOR +DISSEMINATION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZICH * Issues pertaining to CD-ROMs * Options for publishing in CD-ROM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Robert ZICH, special assistant to the associate librarian for special +projects, Library of Congress, and moderator of this session, first noted +the blessed but somewhat awkward circumstance of having four very +distinguished people representing networks and networking or at least +leaning in that direction, while lacking anyone to speak from the +strongest possible background in CD-ROMs. ZICH expressed the hope that +members of the audience would join the discussion. He stressed the +subtitle of this particular session, "Options for Dissemination," and, +concerning CD-ROMs, the importance of determining when it would be wise +to consider dissemination in CD-ROM versus networks. A shopping list of +issues pertaining to CD-ROMs included: the grounds for selecting +commercial publishers, and in-house publication where possible versus +nonprofit or government publication. A similar list for networks +included: determining when one should consider dissemination through a +network, identifying the mechanisms or entities that exist to place items +on networks, identifying the pool of existing networks, determining how a +producer would choose between networks, and identifying the elements of +a business arrangement in a network. + +Options for publishing in CD-ROM: an outside publisher versus +self-publication. If an outside publisher is used, it can be nonprofit, +such as the Government Printing Office (GPO) or the National Technical +Information Service (NTIS), in the case of government. The pros and cons +associated with employing an outside publisher are obvious. Among the +pros, there is no trouble getting accepted. One pays the bill and, in +effect, goes one's way. Among the cons, when one pays an outside +publisher to perform the work, that publisher will perform the work it is +obliged to do, but perhaps without the production expertise and skill in +marketing and dissemination that some would seek. There is the body of +commercial publishers that do possess that kind of expertise in +distribution and marketing but that obviously are selective. In +self-publication, one exercises full control, but then one must handle +matters such as distribution and marketing. Such are some of the options +for publishing in the case of CD-ROM. + +In the case of technical and design issues, which are also important, +there are many matters which many at the Workshop already knew a good +deal about: retrieval system requirements and costs, what to do about +images, the various capabilities and platforms, the trade-offs between +cost and performance, concerns about local-area networkability, +interoperability, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LYNCH * Creating networked information is different from using networks +as an access or dissemination vehicle * Networked multimedia on a large +scale does not yet work * Typical CD-ROM publication model a two-edged +sword * Publishing information on a CD-ROM in the present world of +immature standards * Contrast between CD-ROM and network pricing * +Examples demonstrated earlier in the day as a set of insular information +gems * Paramount need to link databases * Layering to become increasingly +necessary * Project NEEDS and the issues of information reuse and active +versus passive use * X-Windows as a way of differentiating between +network access and networked information * Barriers to the distribution +of networked multimedia information * Need for good, real-time delivery +protocols * The question of presentation integrity in client-server +computing in the academic world * Recommendations for producing multimedia ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Clifford LYNCH, director, Library Automation, University of California, +opened his talk with the general observation that networked information +constituted a difficult and elusive topic because it is something just +starting to develop and not yet fully understood. LYNCH contended that +creating genuinely networked information was different from using +networks as an access or dissemination vehicle and was more sophisticated +and more subtle. He invited the members of the audience to extrapolate, +from what they heard about the preceding demonstration projects, to what +sort of a world of electronics information--scholarly, archival, +cultural, etc.--they wished to end up with ten or fifteen years from now. +LYNCH suggested that to extrapolate directly from these projects would +produce unpleasant results. + +Putting the issue of CD-ROM in perspective before getting into +generalities on networked information, LYNCH observed that those engaged +in multimedia today who wish to ship a product, so to say, probably do +not have much choice except to use CD-ROM: networked multimedia on a +large scale basically does not yet work because the technology does not +exist. For example, anybody who has tried moving images around over the +Internet knows that this is an exciting touch-and-go process, a +fascinating and fertile area for experimentation, research, and +development, but not something that one can become deeply enthusiastic +about committing to production systems at this time. + +This situation will change, LYNCH said. He differentiated CD-ROM from +the practices that have been followed up to now in distributing data on +CD-ROM. For LYNCH the problem with CD-ROM is not its portability or its +slowness but the two-edged sword of having the retrieval application and +the user interface inextricably bound up with the data, which is the +typical CD-ROM publication model. It is not a case of publishing data +but of distributing a typically stand-alone, typically closed system, +all--software, user interface, and data--on a little disk. Hence, all +the between-disk navigational issues as well as the impossibility in most +cases of integrating data on one disk with that on another. Most CD-ROM +retrieval software does not network very gracefully at present. However, +in the present world of immature standards and lack of understanding of +what network information is or what the ground rules are for creating or +using it, publishing information on a CD-ROM does add value in a very +real sense. + +LYNCH drew a contrast between CD-ROM and network pricing and in doing so +highlighted something bizarre in information pricing. A large +institution such as the University of California has vendors who will +offer to sell information on CD-ROM for a price per year in four digits, +but for the same data (e.g., an abstracting and indexing database) on +magnetic tape, regardless of how many people may use it concurrently, +will quote a price in six digits. + +What is packaged with the CD-ROM in one sense adds value--a complete +access system, not just raw, unrefined information--although it is not +generally perceived that way. This is because the access software, +although it adds value, is viewed by some people, particularly in the +university environment where there is a very heavy commitment to +networking, as being developed in the wrong direction. + +Given that context, LYNCH described the examples demonstrated as a set of +insular information gems--Perseus, for example, offers nicely linked +information, but would be very difficult to integrate with other +databases, that is, to link together seamlessly with other source files +from other sources. It resembles an island, and in this respect is +similar to numerous stand-alone projects that are based on videodiscs, +that is, on the single-workstation concept. + +As scholarship evolves in a network environment, the paramount need will +be to link databases. We must link personal databases to public +databases, to group databases, in fairly seamless ways--which is +extremely difficult in the environments under discussion with copies of +databases proliferating all over the place. + +The notion of layering also struck LYNCH as lurking in several of the +projects demonstrated. Several databases in a sense constitute +information archives without a significant amount of navigation built in. +Educators, critics, and others will want a layered structure--one that +defines or links paths through the layers to allow users to reach +specific points. In LYNCH's view, layering will become increasingly +necessary, and not just within a single resource but across resources +(e.g., tracing mythology and cultural themes across several classics +databases as well as a database of Renaissance culture). This ability to +organize resources, to build things out of multiple other things on the +network or select pieces of it, represented for LYNCH one of the key +aspects of network information. + +Contending that information reuse constituted another significant issue, +LYNCH commended to the audience's attention Project NEEDS (i.e., National +Engineering Education Delivery System). This project's objective is to +produce a database of engineering courseware as well as the components +that can be used to develop new courseware. In a number of the existing +applications, LYNCH said, the issue of reuse (how much one can take apart +and reuse in other applications) was not being well considered. He also +raised the issue of active versus passive use, one aspect of which is +how much information will be manipulated locally by users. Most people, +he argued, may do a little browsing and then will wish to print. LYNCH +was uncertain how these resources would be used by the vast majority of +users in the network environment. + +LYNCH next said a few words about X-Windows as a way of differentiating +between network access and networked information. A number of the +applications demonstrated at the Workshop could be rewritten to use X +across the network, so that one could run them from any X-capable device- +-a workstation, an X terminal--and transact with a database across the +network. Although this opens up access a little, assuming one has enough +network to handle it, it does not provide an interface to develop a +program that conveniently integrates information from multiple databases. +X is a viewing technology that has limits. In a real sense, it is just a +graphical version of remote log-in across the network. X-type applications +represent only one step in the progression towards real access. + +LYNCH next discussed barriers to the distribution of networked multimedia +information. The heart of the problem is a lack of standards to provide +the ability for computers to talk to each other, retrieve information, +and shuffle it around fairly casually. At the moment, little progress is +being made on standards for networked information; for example, present +standards do not cover images, digital voice, and digital video. A +useful tool kit of exchange formats for basic texts is only now being +assembled. The synchronization of content streams (i.e., synchronizing a +voice track to a video track, establishing temporal relations between +different components in a multimedia object) constitutes another issue +for networked multimedia that is just beginning to receive attention. + +Underlying network protocols also need some work; good, real-time +delivery protocols on the Internet do not yet exist. In LYNCH's view, +highly important in this context is the notion of networked digital +object IDs, the ability of one object on the network to point to another +object (or component thereof) on the network. Serious bandwidth issues +also exist. LYNCH was uncertain if billion-bit-per-second networks would +prove sufficient if numerous people ran video in parallel. + +LYNCH concluded by offering an issue for database creators to consider, +as well as several comments about what might constitute good trial +multimedia experiments. In a networked information world the database +builder or service builder (publisher) does not exercise the same +extensive control over the integrity of the presentation; strange +programs "munge" with one's data before the user sees it. Serious +thought must be given to what guarantees integrity of presentation. Part +of that is related to where one draws the boundaries around a networked +information service. This question of presentation integrity in +client-server computing has not been stressed enough in the academic +world, LYNCH argued, though commercial service providers deal with it +regularly. + +Concerning multimedia, LYNCH observed that good multimedia at the moment +is hideously expensive to produce. He recommended producing multimedia +with either very high sale value, or multimedia with a very long life +span, or multimedia that will have a very broad usage base and whose +costs therefore can be amortized among large numbers of users. In this +connection, historical and humanistically oriented material may be a good +place to start, because it tends to have a longer life span than much of +the scientific material, as well as a wider user base. LYNCH noted, for +example, that American Memory fits many of the criteria outlined. He +remarked the extensive discussion about bringing the Internet or the +National Research and Education Network (NREN) into the K-12 environment +as a way of helping the American educational system. + +LYNCH closed by noting that the kinds of applications demonstrated struck +him as excellent justifications of broad-scale networking for K-12, but +that at this time no "killer" application exists to mobilize the K-12 +community to obtain connectivity. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Dearth of genuinely interesting applications on the network +a slow-changing situation * The issue of the integrity of presentation in +a networked environment * Several reasons why CD-ROM software does not +network * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period that followed LYNCH's presentation, several +additional points were made. + +LYNCH reiterated even more strongly his contention that, historically, +once one goes outside high-end science and the group of those who need +access to supercomputers, there is a great dearth of genuinely +interesting applications on the network. He saw this situation changing +slowly, with some of the scientific databases and scholarly discussion +groups and electronic journals coming on as well as with the availability +of Wide Area Information Servers (WAIS) and some of the databases that +are being mounted there. However, many of those things do not seem to +have piqued great popular interest. For instance, most high school +students of LYNCH's acquaintance would not qualify as devotees of serious +molecular biology. + +Concerning the issue of the integrity of presentation, LYNCH believed +that a couple of information providers have laid down the law at least on +certain things. For example, his recollection was that the National +Library of Medicine feels strongly that one needs to employ the +identifier field if he or she is to mount a database commercially. The +problem with a real networked environment is that one does not know who +is reformatting and reprocessing one's data when one enters a client +server mode. It becomes anybody's guess, for example, if the network +uses a Z39.50 server, or what clients are doing with one's data. A data +provider can say that his contract will only permit clients to have +access to his data after he vets them and their presentation and makes +certain it suits him. But LYNCH held out little expectation that the +network marketplace would evolve in that way, because it required too +much prior negotiation. + +CD-ROM software does not network for a variety of reasons, LYNCH said. +He speculated that CD-ROM publishers are not eager to have their products +really hook into wide area networks, because they fear it will make their +data suppliers nervous. Moreover, until relatively recently, one had to +be rather adroit to run a full TCP/IP stack plus applications on a +PC-size machine, whereas nowadays it is becoming easier as PCs grow +bigger and faster. LYNCH also speculated that software providers had not +heard from their customers until the last year or so, or had not heard +from enough of their customers. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BESSER * Implications of disseminating images on the network; planning +the distribution of multimedia documents poses two critical +implementation problems * Layered approach represents the way to deal +with users' capabilities * Problems in platform design; file size and its +implications for networking * Transmission of megabyte size images +impractical * Compression and decompression at the user's end * Promising +trends for compression * A disadvantage of using X-Windows * A project at +the Smithsonian that mounts images on several networks * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Howard BESSER, School of Library and Information Science, University of +Pittsburgh, spoke primarily about multimedia, focusing on images and the +broad implications of disseminating them on the network. He argued that +planning the distribution of multimedia documents posed two critical +implementation problems, which he framed in the form of two questions: +1) What platform will one use and what hardware and software will users +have for viewing of the material? and 2) How can one deliver a +sufficiently robust set of information in an accessible format in a +reasonable amount of time? Depending on whether network or CD-ROM is the +medium used, this question raises different issues of storage, +compression, and transmission. + +Concerning the design of platforms (e.g., sound, gray scale, simple +color, etc.) and the various capabilities users may have, BESSER +maintained that a layered approach was the way to deal with users' +capabilities. A result would be that users with less powerful +workstations would simply have less functionality. He urged members of +the audience to advocate standards and accompanying software that handle +layered functionality across a wide variety of platforms. + +BESSER also addressed problems in platform design, namely, deciding how +large a machine to design for situations when the largest number of users +have the lowest level of the machine, and one desires higher +functionality. BESSER then proceeded to the question of file size and +its implications for networking. He discussed still images in the main. +For example, a digital color image that fills the screen of a standard +mega-pel workstation (Sun or Next) will require one megabyte of storage +for an eight-bit image or three megabytes of storage for a true color or +twenty-four-bit image. Lossless compression algorithms (that is, +computational procedures in which no data is lost in the process of +compressing [and decompressing] an image--the exact bit-representation is +maintained) might bring storage down to a third of a megabyte per image, +but not much further than that. The question of size makes it difficult +to fit an appropriately sized set of these images on a single disk or to +transmit them quickly enough on a network. + +With these full screen mega-pel images that constitute a third of a +megabyte, one gets 1,000-3,000 full-screen images on a one-gigabyte disk; +a standard CD-ROM represents approximately 60 percent of that. Storing +images the size of a PC screen (just 8 bit color) increases storage +capacity to 4,000-12,000 images per gigabyte; 60 percent of that gives +one the size of a CD-ROM, which in turn creates a major problem. One +cannot have full-screen, full-color images with lossless compression; one +must compress them or use a lower resolution. For megabyte-size images, +anything slower than a T-1 speed is impractical. For example, on a +fifty-six-kilobaud line, it takes three minutes to transfer a +one-megabyte file, if it is not compressed; and this speed assumes ideal +circumstances (no other user contending for network bandwidth). Thus, +questions of disk access, remote display, and current telephone +connection speed make transmission of megabyte-size images impractical. + +BESSER then discussed ways to deal with these large images, for example, +compression and decompression at the user's end. In this connection, the +issues of how much one is willing to lose in the compression process and +what image quality one needs in the first place are unknown. But what is +known is that compression entails some loss of data. BESSER urged that +more studies be conducted on image quality in different situations, for +example, what kind of images are needed for what kind of disciplines, and +what kind of image quality is needed for a browsing tool, an intermediate +viewing tool, and archiving. + +BESSER remarked two promising trends for compression: from a technical +perspective, algorithms that use what is called subjective redundancy +employ principles from visual psycho-physics to identify and remove +information from the image that the human eye cannot perceive; from an +interchange and interoperability perspective, the JPEG (i.e., Joint +Photographic Experts Group, an ISO standard) compression algorithms also +offer promise. These issues of compression and decompression, BESSER +argued, resembled those raised earlier concerning the design of different +platforms. Gauging the capabilities of potential users constitutes a +primary goal. BESSER advocated layering or separating the images from +the applications that retrieve and display them, to avoid tying them to +particular software. + +BESSER detailed several lessons learned from his work at Berkeley with +Imagequery, especially the advantages and disadvantages of using +X-Windows. In the latter category, for example, retrieval is tied +directly to one's data, an intolerable situation in the long run on a +networked system. Finally, BESSER described a project of Jim Wallace at +the Smithsonian Institution, who is mounting images in a extremely +rudimentary way on the Compuserv and Genie networks and is preparing to +mount them on America On Line. Although the average user takes over +thirty minutes to download these images (assuming a fairly fast modem), +nevertheless, images have been downloaded 25,000 times. + +BESSER concluded his talk with several comments on the business +arrangement between the Smithsonian and Compuserv. He contended that not +enough is known concerning the value of images. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating digitized photographic collections nearly +impossible except with large organizations like museums * Need for study +to determine quality of images users will tolerate * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief exchange between LESK and BESSER that followed, several +clarifications emerged. + +LESK argued that the photographers were far ahead of BESSER: It is +almost impossible to create such digitized photographic collections +except with large organizations like museums, because all the +photographic agencies have been going crazy about this and will not sign +licensing agreements on any sort of reasonable terms. LESK had heard +that National Geographic, for example, had tried to buy the right to use +some image in some kind of educational production for $100 per image, but +the photographers will not touch it. They want accounting and payment +for each use, which cannot be accomplished within the system. BESSER +responded that a consortium of photographers, headed by a former National +Geographic photographer, had started assembling its own collection of +electronic reproductions of images, with the money going back to the +cooperative. + +LESK contended that BESSER was unnecessarily pessimistic about multimedia +images, because people are accustomed to low-quality images, particularly +from video. BESSER urged the launching of a study to determine what +users would tolerate, what they would feel comfortable with, and what +absolutely is the highest quality they would ever need. Conceding that +he had adopted a dire tone in order to arouse people about the issue, +BESSER closed on a sanguine note by saying that he would not be in this +business if he did not think that things could be accomplished. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LARSEN * Issues of scalability and modularity * Geometric growth of the +Internet and the role played by layering * Basic functions sustaining +this growth * A library's roles and functions in a network environment * +Effects of implementation of the Z39.50 protocol for information +retrieval on the library system * The trade-off between volumes of data +and its potential usage * A snapshot of current trends * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ronald LARSEN, associate director for information technology, University +of Maryland at College Park, first addressed the issues of scalability +and modularity. He noted the difficulty of anticipating the effects of +orders-of-magnitude growth, reflecting on the twenty years of experience +with the Arpanet and Internet. Recalling the day's demonstrations of +CD-ROM and optical disk material, he went on to ask if the field has yet +learned how to scale new systems to enable delivery and dissemination +across large-scale networks. + +LARSEN focused on the geometric growth of the Internet from its inception +circa 1969 to the present, and the adjustments required to respond to +that rapid growth. To illustrate the issue of scalability, LARSEN +considered computer networks as including three generic components: +computers, network communication nodes, and communication media. Each +component scales (e.g., computers range from PCs to supercomputers; +network nodes scale from interface cards in a PC through sophisticated +routers and gateways; and communication media range from 2,400-baud +dial-up facilities through 4.5-Mbps backbone links, and eventually to +multigigabit-per-second communication lines), and architecturally, the +components are organized to scale hierarchically from local area networks +to international-scale networks. Such growth is made possible by +building layers of communication protocols, as BESSER pointed out. +By layering both physically and logically, a sense of scalability is +maintained from local area networks in offices, across campuses, through +bridges, routers, campus backbones, fiber-optic links, etc., up into +regional networks and ultimately into national and international +networks. + +LARSEN then illustrated the geometric growth over a two-year period-- +through September 1991--of the number of networks that comprise the +Internet. This growth has been sustained largely by the availability of +three basic functions: electronic mail, file transfer (ftp), and remote +log-on (telnet). LARSEN also reviewed the growth in the kind of traffic +that occurs on the network. Network traffic reflects the joint contributions +of a larger population of users and increasing use per user. Today one sees +serious applications involving moving images across the network--a rarity +ten years ago. LARSEN recalled and concurred with BESSER's main point +that the interesting problems occur at the application level. + +LARSEN then illustrated a model of a library's roles and functions in a +network environment. He noted, in particular, the placement of on-line +catalogues onto the network and patrons obtaining access to the library +increasingly through local networks, campus networks, and the Internet. +LARSEN supported LYNCH's earlier suggestion that we need to address +fundamental questions of networked information in order to build +environments that scale in the information sense as well as in the +physical sense. + +LARSEN supported the role of the library system as the access point into +the nation's electronic collections. Implementation of the Z39.50 +protocol for information retrieval would make such access practical and +feasible. For example, this would enable patrons in Maryland to search +California libraries, or other libraries around the world that are +conformant with Z39.50 in a manner that is familiar to University of +Maryland patrons. This client-server model also supports moving beyond +secondary content into primary content. (The notion of how one links +from secondary content to primary content, LARSEN said, represents a +fundamental problem that requires rigorous thought.) After noting +numerous network experiments in accessing full-text materials, including +projects supporting the ordering of materials across the network, LARSEN +revisited the issue of transmitting high-density, high-resolution color +images across the network and the large amounts of bandwidth they +require. He went on to address the bandwidth and synchronization +problems inherent in sending full-motion video across the network. + +LARSEN illustrated the trade-off between volumes of data in bytes or +orders of magnitude and the potential usage of that data. He discussed +transmission rates (particularly, the time it takes to move various forms +of information), and what one could do with a network supporting +multigigabit-per-second transmission. At the moment, the network +environment includes a composite of data-transmission requirements, +volumes and forms, going from steady to bursty (high-volume) and from +very slow to very fast. This aggregate must be considered in the design, +construction, and operation of multigigabyte networks. + +LARSEN's objective is to use the networks and library systems now being +constructed to increase access to resources wherever they exist, and +thus, to evolve toward an on-line electronic virtual library. + +LARSEN concluded by offering a snapshot of current trends: continuing +geometric growth in network capacity and number of users; slower +development of applications; and glacial development and adoption of +standards. The challenge is to design and develop each new application +system with network access and scalability in mind. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BROWNRIGG * Access to the Internet cannot be taken for granted * Packet +radio and the development of MELVYL in 1980-81 in the Division of Library +Automation at the University of California * Design criteria for packet +radio * A demonstration project in San Diego and future plans * Spread +spectrum * Frequencies at which the radios will run and plans to +reimplement the WAIS server software in the public domain * Need for an +infrastructure of radios that do not move around * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Edwin BROWNRIGG, executive director, Memex Research Institute, first +polled the audience in order to seek out regular users of the Internet as +well as those planning to use it some time in the future. With nearly +everybody in the room falling into one category or the other, BROWNRIGG +made a point re access, namely that numerous individuals, especially those +who use the Internet every day, take for granted their access to it, the +speeds with which they are connected, and how well it all works. +However, as BROWNRIGG discovered between 1987 and 1989 in Australia, +if one wants access to the Internet but cannot afford it or has some +physical boundary that prevents her or him from gaining access, it can +be extremely frustrating. He suggested that because of economics and +physical barriers we were beginning to create a world of haves and have-nots +in the process of scholarly communication, even in the United States. + +BROWNRIGG detailed the development of MELVYL in academic year 1980-81 in +the Division of Library Automation at the University of California, in +order to underscore the issue of access to the system, which at the +outset was extremely limited. In short, the project needed to build a +network, which at that time entailed use of satellite technology, that is, +putting earth stations on campus and also acquiring some terrestrial links +from the State of California's microwave system. The installation of +satellite links, however, did not solve the problem (which actually +formed part of a larger problem involving politics and financial resources). +For while the project team could get a signal onto a campus, it had no means +of distributing the signal throughout the campus. The solution involved +adopting a recent development in wireless communication called packet radio, +which combined the basic notion of packet-switching with radio. The project +used this technology to get the signal from a point on campus where it +came down, an earth station for example, into the libraries, because it +found that wiring the libraries, especially the older marble buildings, +would cost $2,000-$5,000 per terminal. + +BROWNRIGG noted that, ten years ago, the project had neither the public +policy nor the technology that would have allowed it to use packet radio +in any meaningful way. Since then much had changed. He proceeded to +detail research and development of the technology, how it is being +deployed in California, and what direction he thought it would take. +The design criteria are to produce a high-speed, one-time, low-cost, +high-quality, secure, license-free device (packet radio) that one can +plug in and play today, forget about it, and have access to the Internet. +By high speed, BROWNRIGG meant 1 megabyte and 1.5 megabytes. Those units +have been built, he continued, and are in the process of being +type-certified by an independent underwriting laboratory so that they can +be type-licensed by the Federal Communications Commission. As is the +case with citizens band, one will be able to purchase a unit and not have +to worry about applying for a license. + +The basic idea, BROWNRIGG elaborated, is to take high-speed radio data +transmission and create a backbone network that at certain strategic +points in the network will "gateway" into a medium-speed packet radio +(i.e., one that runs at 38.4 kilobytes), so that perhaps by 1994-1995 +people, like those in the audience for the price of a VCR could purchase +a medium-speed radio for the office or home, have full network connectivity +to the Internet, and partake of all its services, with no need for an FCC +license and no regular bill from the local common carrier. BROWNRIGG +presented several details of a demonstration project currently taking +place in San Diego and described plans, pending funding, to install a +full-bore network in the San Francisco area. This network will have 600 +nodes running at backbone speeds, and 100 of these nodes will be libraries, +which in turn will be the gateway ports to the 38.4 kilobyte radios that +will give coverage for the neighborhoods surrounding the libraries. + +BROWNRIGG next explained Part 15.247, a new rule within Title 47 of the +Code of Federal Regulations enacted by the FCC in 1985. This rule +challenged the industry, which has only now risen to the occasion, to +build a radio that would run at no more than one watt of output power and +use a fairly exotic method of modulating the radio wave called spread +spectrum. Spread spectrum in fact permits the building of networks so +that numerous data communications can occur simultaneously, without +interfering with each other, within the same wide radio channel. + +BROWNRIGG explained that the frequencies at which the radios would run +are very short wave signals. They are well above standard microwave and +radar. With a radio wave that small, one watt becomes a tremendous punch +per bit and thus makes transmission at reasonable speed possible. In +order to minimize the potential for congestion, the project is +undertaking to reimplement software which has been available in the +networking business and is taken for granted now, for example, TCP/IP, +routing algorithms, bridges, and gateways. In addition, the project +plans to take the WAIS server software in the public domain and +reimplement it so that one can have a WAIS server on a Mac instead of a +Unix machine. The Memex Research Institute believes that libraries, in +particular, will want to use the WAIS servers with packet radio. This +project, which has a team of about twelve people, will run through 1993 +and will include the 100 libraries already mentioned as well as other +professionals such as those in the medical profession, engineering, and +law. Thus, the need is to create an infrastructure of radios that do not +move around, which, BROWNRIGG hopes, will solve a problem not only for +libraries but for individuals who, by and large today, do not have access +to the Internet from their homes and offices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Project operating frequencies * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During a brief discussion period, which also concluded the day's +proceedings, BROWNRIGG stated that the project was operating in four +frequencies. The slow speed is operating at 435 megahertz, and it would +later go up to 920 megahertz. With the high-speed frequency, the +one-megabyte radios will run at 2.4 gigabits, and 1.5 will run at 5.7. +At 5.7, rain can be a factor, but it would have to be tropical rain, +unlike what falls in most parts of the United States. + + ****** + +SESSION IV. IMAGE CAPTURE, TEXT CAPTURE, OVERVIEW OF TEXT AND + IMAGE STORAGE FORMATS + +William HOOTON, vice president of operations, I-NET, moderated this session. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +KENNEY * Factors influencing development of CXP * Advantages of using +digital technology versus photocopy and microfilm * A primary goal of +CXP; publishing challenges * Characteristics of copies printed * Quality +of samples achieved in image capture * Several factors to be considered +in choosing scanning * Emphasis of CXP on timely and cost-effective +production of black-and-white printed facsimiles * Results of producing +microfilm from digital files * Advantages of creating microfilm * Details +concerning production * Costs * Role of digital technology in library +preservation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Anne KENNEY, associate director, Department of Preservation and +Conservation, Cornell University, opened her talk by observing that the +Cornell Xerox Project (CXP) has been guided by the assumption that the +ability to produce printed facsimiles or to replace paper with paper +would be important, at least for the present generation of users and +equipment. She described three factors that influenced development of +the project: 1) Because the project has emphasized the preservation of +deteriorating brittle books, the quality of what was produced had to be +sufficiently high to return a paper replacement to the shelf. CXP was +only interested in using: 2) a system that was cost-effective, which +meant that it had to be cost-competitive with the processes currently +available, principally photocopy and microfilm, and 3) new or currently +available product hardware and software. + +KENNEY described the advantages that using digital technology offers over +both photocopy and microfilm: 1) The potential exists to create a higher +quality reproduction of a deteriorating original than conventional +light-lens technology. 2) Because a digital image is an encoded +representation, it can be reproduced again and again with no resulting +loss of quality, as opposed to the situation with light-lens processes, +in which there is discernible difference between a second and a +subsequent generation of an image. 3) A digital image can be manipulated +in a number of ways to improve image capture; for example, Xerox has +developed a windowing application that enables one to capture a page +containing both text and illustrations in a manner that optimizes the +reproduction of both. (With light-lens technology, one must choose which +to optimize, text or the illustration; in preservation microfilming, the +current practice is to shoot an illustrated page twice, once to highlight +the text and the second time to provide the best capture for the +illustration.) 4) A digital image can also be edited, density levels +adjusted to remove underlining and stains, and to increase legibility for +faint documents. 5) On-screen inspection can take place at the time of +initial setup and adjustments made prior to scanning, factors that +substantially reduce the number of retakes required in quality control. + +A primary goal of CXP has been to evaluate the paper output printed on +the Xerox DocuTech, a high-speed printer that produces 600-dpi pages from +scanned images at a rate of 135 pages a minute. KENNEY recounted several +publishing challenges to represent faithful and legible reproductions of +the originals that the 600-dpi copy for the most part successfully +captured. For example, many of the deteriorating volumes in the project +were heavily illustrated with fine line drawings or halftones or came in +languages such as Japanese, in which the buildup of characters comprised +of varying strokes is difficult to reproduce at lower resolutions; a +surprising number of them came with annotations and mathematical +formulas, which it was critical to be able to duplicate exactly. + +KENNEY noted that 1) the copies are being printed on paper that meets the +ANSI standards for performance, 2) the DocuTech printer meets the machine +and toner requirements for proper adhesion of print to page, as described +by the National Archives, and thus 3) paper product is considered to be +the archival equivalent of preservation photocopy. + +KENNEY then discussed several samples of the quality achieved in the +project that had been distributed in a handout, for example, a copy of a +print-on-demand version of the 1911 Reed lecture on the steam turbine, +which contains halftones, line drawings, and illustrations embedded in +text; the first four loose pages in the volume compared the capture +capabilities of scanning to photocopy for a standard test target, the +IEEE standard 167A 1987 test chart. In all instances scanning proved +superior to photocopy, though only slightly more so in one. + +Conceding the simplistic nature of her review of the quality of scanning +to photocopy, KENNEY described it as one representation of the kinds of +settings that could be used with scanning capabilities on the equipment +CXP uses. KENNEY also pointed out that CXP investigated the quality +achieved with binary scanning only, and noted the great promise in gray +scale and color scanning, whose advantages and disadvantages need to be +examined. She argued further that scanning resolutions and file formats +can represent a complex trade-off between the time it takes to capture +material, file size, fidelity to the original, and on-screen display; and +printing and equipment availability. All these factors must be taken +into consideration. + +CXP placed primary emphasis on the production in a timely and +cost-effective manner of printed facsimiles that consisted largely of +black-and-white text. With binary scanning, large files may be +compressed efficiently and in a lossless manner (i.e., no data is lost in +the process of compressing [and decompressing] an image--the exact +bit-representation is maintained) using Group 4 CCITT (i.e., the French +acronym for International Consultative Committee for Telegraph and +Telephone) compression. CXP was getting compression ratios of about +forty to one. Gray-scale compression, which primarily uses JPEG, is much +less economical and can represent a lossy compression (i.e., not +lossless), so that as one compresses and decompresses, the illustration +is subtly changed. While binary files produce a high-quality printed +version, it appears 1) that other combinations of spatial resolution with +gray and/or color hold great promise as well, and 2) that gray scale can +represent a tremendous advantage for on-screen viewing. The quality +associated with binary and gray scale also depends on the equipment used. +For instance, binary scanning produces a much better copy on a binary +printer. + +Among CXP's findings concerning the production of microfilm from digital +files, KENNEY reported that the digital files for the same Reed lecture +were used to produce sample film using an electron beam recorder. The +resulting film was faithful to the image capture of the digital files, +and while CXP felt that the text and image pages represented in the Reed +lecture were superior to that of the light-lens film, the resolution +readings for the 600 dpi were not as high as standard microfilming. +KENNEY argued that the standards defined for light-lens technology are +not totally transferable to a digital environment. Moreover, they are +based on definition of quality for a preservation copy. Although making +this case will prove to be a long, uphill struggle, CXP plans to continue +to investigate the issue over the course of the next year. + +KENNEY concluded this portion of her talk with a discussion of the +advantages of creating film: it can serve as a primary backup and as a +preservation master to the digital file; it could then become the print +or production master and service copies could be paper, film, optical +disks, magnetic media, or on-screen display. + +Finally, KENNEY presented details re production: + + * Development and testing of a moderately-high resolution production + scanning workstation represented a third goal of CXP; to date, 1,000 + volumes have been scanned, or about 300,000 images. + + * The resulting digital files are stored and used to produce + hard-copy replacements for the originals and additional prints on + demand; although the initial costs are high, scanning technology + offers an affordable means for reformatting brittle material. + + * A technician in production mode can scan 300 pages per hour when + performing single-sheet scanning, which is a necessity when working + with truly brittle paper; this figure is expected to increase + significantly with subsequent iterations of the software from Xerox; + a three-month time-and-cost study of scanning found that the average + 300-page book would take about an hour and forty minutes to scan + (this figure included the time for setup, which involves keying in + primary bibliographic data, going into quality control mode to + define page size, establishing front-to-back registration, and + scanning sample pages to identify a default range of settings for + the entire book--functions not dissimilar to those performed by + filmers or those preparing a book for photocopy). + + * The final step in the scanning process involved rescans, which + happily were few and far between, representing well under 1 percent + of the total pages scanned. + +In addition to technician time, CXP costed out equipment, amortized over +four years, the cost of storing and refreshing the digital files every +four years, and the cost of printing and binding, book-cloth binding, a +paper reproduction. The total amounted to a little under $65 per single +300-page volume, with 30 percent overhead included--a figure competitive +with the prices currently charged by photocopy vendors. + +Of course, with scanning, in addition to the paper facsimile, one is left +with a digital file from which subsequent copies of the book can be +produced for a fraction of the cost of photocopy, with readers afforded +choices in the form of these copies. + +KENNEY concluded that digital technology offers an electronic means for a +library preservation effort to pay for itself. If a brittle-book program +included the means of disseminating reprints of books that are in demand +by libraries and researchers alike, the initial investment in capture +could be recovered and used to preserve additional but less popular +books. She disclosed that an economic model for a self-sustaining +program could be developed for CXP's report to the Commission on +Preservation and Access (CPA). + +KENNEY stressed that the focus of CXP has been on obtaining high quality +in a production environment. The use of digital technology is viewed as +an affordable alternative to other reformatting options. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ANDRE * Overview and history of NATDP * Various agricultural CD-ROM +products created inhouse and by service bureaus * Pilot project on +Internet transmission * Additional products in progress * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Pamela ANDRE, associate director for automation, National Agricultural +Text Digitizing Program (NATDP), National Agricultural Library (NAL), +presented an overview of NATDP, which has been underway at NAL the last +four years, before Judith ZIDAR discussed the technical details. ANDRE +defined agricultural information as a broad range of material going from +basic and applied research in the hard sciences to the one-page pamphlets +that are distributed by the cooperative state extension services on such +things as how to grow blueberries. + +NATDP began in late 1986 with a meeting of representatives from the +land-grant library community to deal with the issue of electronic +information. NAL and forty-five of these libraries banded together to +establish this project--to evaluate the technology for converting what +were then source documents in paper form into electronic form, to provide +access to that digital information, and then to distribute it. +Distributing that material to the community--the university community as +well as the extension service community, potentially down to the county +level--constituted the group's chief concern. + +Since January 1988 (when the microcomputer-based scanning system was +installed at NAL), NATDP has done a variety of things, concerning which +ZIDAR would provide further details. For example, the first technology +considered in the project's discussion phase was digital videodisc, which +indicates how long ago it was conceived. + +Over the four years of this project, four separate CD-ROM products on +four different agricultural topics were created, two at a +scanning-and-OCR station installed at NAL, and two by service bureaus. +Thus, NATDP has gained comparative information in terms of those relative +costs. Each of these products contained the full ASCII text as well as +page images of the material, or between 4,000 and 6,000 pages of material +on these disks. Topics included aquaculture, food, agriculture and +science (i.e., international agriculture and research), acid rain, and +Agent Orange, which was the final product distributed (approximately +eighteen months before the Workshop). + +The third phase of NATDP focused on delivery mechanisms other than +CD-ROM. At the suggestion of Clifford LYNCH, who was a technical +consultant to the project at this point, NATDP became involved with the +Internet and initiated a project with the help of North Carolina State +University, in which fourteen of the land-grant university libraries are +transmitting digital images over the Internet in response to interlibrary +loan requests--a topic for another meeting. At this point, the pilot +project had been completed for about a year and the final report would be +available shortly after the Workshop. In the meantime, the project's +success had led to its extension. (ANDRE noted that one of the first +things done under the program title was to select a retrieval package to +use with subsequent products; Windows Personal Librarian was the package +of choice after a lengthy evaluation.) + +Three additional products had been planned and were in progress: + + 1) An arrangement with the American Society of Agronomy--a + professional society that has published the Agronomy Journal since + about 1908--to scan and create bit-mapped images of its journal. + ASA granted permission first to put and then to distribute this + material in electronic form, to hold it at NAL, and to use these + electronic images as a mechanism to deliver documents or print out + material for patrons, among other uses. Effectively, NAL has the + right to use this material in support of its program. + (Significantly, this arrangement offers a potential cooperative + model for working with other professional societies in agriculture + to try to do the same thing--put the journals of particular interest + to agriculture research into electronic form.) + + 2) An extension of the earlier product on aquaculture. + + 3) The George Washington Carver Papers--a joint project with + Tuskegee University to scan and convert from microfilm some 3,500 + images of Carver's papers, letters, and drawings. + +It was anticipated that all of these products would appear no more than +six months after the Workshop. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * (A separate arena for scanning) * Steps in creating a database * +Image capture, with and without performing OCR * Keying in tracking data +* Scanning, with electronic and manual tracking * Adjustments during +scanning process * Scanning resolutions * Compression * De-skewing and +filtering * Image capture from microform: the papers and letters of +George Washington Carver * Equipment used for a scanning system * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), illustrated the technical +details of NATDP, including her primary responsibility, scanning and +creating databases on a topic and putting them on CD-ROM. + +(ZIDAR remarked a separate arena from the CD-ROM projects, although the +processing of the material is nearly identical, in which NATDP is also +scanning material and loading it on a Next microcomputer, which in turn +is linked to NAL's integrated library system. Thus, searches in NAL's +bibliographic database will enable people to pull up actual page images +and text for any documents that have been entered.) + +In accordance with the session's topic, ZIDAR focused her illustrated +talk on image capture, offering a primer on the three main steps in the +process: 1) assemble the printed publications; 2) design the database +(database design occurs in the process of preparing the material for +scanning; this step entails reviewing and organizing the material, +defining the contents--what will constitute a record, what kinds of +fields will be captured in terms of author, title, etc.); 3) perform a +certain amount of markup on the paper publications. NAL performs this +task record by record, preparing work sheets or some other sort of +tracking material and designing descriptors and other enhancements to be +added to the data that will not be captured from the printed publication. +Part of this process also involves determining NATDP's file and directory +structure: NATDP attempts to avoid putting more than approximately 100 +images in a directory, because placing more than that on a CD-ROM would +reduce the access speed. + +This up-front process takes approximately two weeks for a +6,000-7,000-page database. The next step is to capture the page images. +How long this process takes is determined by the decision whether or not +to perform OCR. Not performing OCR speeds the process, whereas text +capture requires greater care because of the quality of the image: it +has to be straighter and allowance must be made for text on a page, not +just for the capture of photographs. + +NATDP keys in tracking data, that is, a standard bibliographic record +including the title of the book and the title of the chapter, which will +later either become the access information or will be attached to the +front of a full-text record so that it is searchable. + +Images are scanned from a bound or unbound publication, chiefly from +bound publications in the case of NATDP, however, because often they are +the only copies and the publications are returned to the shelves. NATDP +usually scans one record at a time, because its database tracking system +tracks the document in that way and does not require further logical +separating of the images. After performing optical character +recognition, NATDP moves the images off the hard disk and maintains a +volume sheet. Though the system tracks electronically, all the +processing steps are also tracked manually with a log sheet. + +ZIDAR next illustrated the kinds of adjustments that one can make when +scanning from paper and microfilm, for example, redoing images that need +special handling, setting for dithering or gray scale, and adjusting for +brightness or for the whole book at one time. + +NATDP is scanning at 300 dots per inch, a standard scanning resolution. +Though adequate for capturing text that is all of a standard size, 300 +dpi is unsuitable for any kind of photographic material or for very small +text. Many scanners allow for different image formats, TIFF, of course, +being a de facto standard. But if one intends to exchange images with +other people, the ability to scan other image formats, even if they are +less common, becomes highly desirable. + +CCITT Group 4 is the standard compression for normal black-and-white +images, JPEG for gray scale or color. ZIDAR recommended 1) using the +standard compressions, particularly if one attempts to make material +available and to allow users to download images and reuse them from +CD-ROMs; and 2) maintaining the ability to output an uncompressed image, +because in image exchange uncompressed images are more likely to be able +to cross platforms. + +ZIDAR emphasized the importance of de-skewing and filtering as +requirements on NATDP's upgraded system. For instance, scanning bound +books, particularly books published by the federal government whose pages +are skewed, and trying to scan them straight if OCR is to be performed, +is extremely time-consuming. The same holds for filtering of +poor-quality or older materials. + +ZIDAR described image capture from microform, using as an example three +reels from a sixty-seven-reel set of the papers and letters of George +Washington Carver that had been produced by Tuskegee University. These +resulted in approximately 3,500 images, which NATDP had had scanned by +its service contractor, Science Applications International Corporation +(SAIC). NATDP also created bibliographic records for access. (NATDP did +not have such specialized equipment as a microfilm scanner. + +Unfortunately, the process of scanning from microfilm was not an +unqualified success, ZIDAR reported: because microfilm frame sizes vary, +occasionally some frames were missed, which without spending much time +and money could not be recaptured. + +OCR could not be performed from the scanned images of the frames. The +bleeding in the text simply output text, when OCR was run, that could not +even be edited. NATDP tested for negative versus positive images, +landscape versus portrait orientation, and single- versus dual-page +microfilm, none of which seemed to affect the quality of the image; but +also on none of them could OCR be performed. + +In selecting the microfilm they would use, therefore, NATDP had other +factors in mind. ZIDAR noted two factors that influenced the quality of +the images: 1) the inherent quality of the original and 2) the amount of +size reduction on the pages. + +The Carver papers were selected because they are informative and visually +interesting, treat a single subject, and are valuable in their own right. +The images were scanned and divided into logical records by SAIC, then +delivered, and loaded onto NATDP's system, where bibliographic +information taken directly from the images was added. Scanning was +completed in summer 1991 and by the end of summer 1992 the disk was +scheduled to be published. + +Problems encountered during processing included the following: Because +the microfilm scanning had to be done in a batch, adjustment for +individual page variations was not possible. The frame size varied on +account of the nature of the material, and therefore some of the frames +were missed while others were just partial frames. The only way to go +back and capture this material was to print out the page with the +microfilm reader from the missing frame and then scan it in from the +page, which was extremely time-consuming. The quality of the images +scanned from the printout of the microfilm compared unfavorably with that +of the original images captured directly from the microfilm. The +inability to perform OCR also was a major disappointment. At the time, +computer output microfilm was unavailable to test. + +The equipment used for a scanning system was the last topic addressed by +ZIDAR. The type of equipment that one would purchase for a scanning +system included: a microcomputer, at least a 386, but preferably a 486; +a large hard disk, 380 megabyte at minimum; a multi-tasking operating +system that allows one to run some things in batch in the background +while scanning or doing text editing, for example, Unix or OS/2 and, +theoretically, Windows; a high-speed scanner and scanning software that +allows one to make the various adjustments mentioned earlier; a +high-resolution monitor (150 dpi ); OCR software and hardware to perform +text recognition; an optical disk subsystem on which to archive all the +images as the processing is done; file management and tracking software. + +ZIDAR opined that the software one purchases was more important than the +hardware and might also cost more than the hardware, but it was likely to +prove critical to the success or failure of one's system. In addition to +a stand-alone scanning workstation for image capture, then, text capture +requires one or two editing stations networked to this scanning station +to perform editing. Editing the text takes two or three times as long as +capturing the images. + +Finally, ZIDAR stressed the importance of buying an open system that allows +for more than one vendor, complies with standards, and can be upgraded. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WATERS *Yale University Library's master plan to convert microfilm to +digital imagery (POB) * The place of electronic tools in the library of +the future * The uses of images and an image library * Primary input from +preservation microfilm * Features distinguishing POB from CXP and key +hypotheses guiding POB * Use of vendor selection process to facilitate +organizational work * Criteria for selecting vendor * Finalists and +results of process for Yale * Key factor distinguishing vendors * +Components, design principles, and some estimated costs of POB * Role of +preservation materials in developing imaging market * Factors affecting +quality and cost * Factors affecting the usability of complex documents +in image form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Donald WATERS, head of the Systems Office, Yale University Library, +reported on the progress of a master plan for a project at Yale to +convert microfilm to digital imagery, Project Open Book (POB). Stating +that POB was in an advanced stage of planning, WATERS detailed, in +particular, the process of selecting a vendor partner and several key +issues under discussion as Yale prepares to move into the project itself. +He commented first on the vision that serves as the context of POB and +then described its purpose and scope. + +WATERS sees the library of the future not necessarily as an electronic +library but as a place that generates, preserves, and improves for its +clients ready access to both intellectual and physical recorded +knowledge. Electronic tools must find a place in the library in the +context of this vision. Several roles for electronic tools include +serving as: indirect sources of electronic knowledge or as "finding" +aids (the on-line catalogues, the article-level indices, registers for +documents and archives); direct sources of recorded knowledge; full-text +images; and various kinds of compound sources of recorded knowledge (the +so-called compound documents of Hypertext, mixed text and image, +mixed-text image format, and multimedia). + +POB is looking particularly at images and an image library, the uses to +which images will be put (e.g., storage, printing, browsing, and then use +as input for other processes), OCR as a subsequent process to image +capture, or creating an image library, and also possibly generating +microfilm. + +While input will come from a variety of sources, POB is considering +especially input from preservation microfilm. A possible outcome is that +the film and paper which provide the input for the image library +eventually may go off into remote storage, and that the image library may +be the primary access tool. + +The purpose and scope of POB focus on imaging. Though related to CXP, +POB has two features which distinguish it: 1) scale--conversion of +10,000 volumes into digital image form; and 2) source--conversion from +microfilm. Given these features, several key working hypotheses guide +POB, including: 1) Since POB is using microfilm, it is not concerned with +the image library as a preservation medium. 2) Digital imagery can improve +access to recorded knowledge through printing and network distribution at +a modest incremental cost of microfilm. 3) Capturing and storing documents +in a digital image form is necessary to further improvements in access. +(POB distinguishes between the imaging, digitizing process and OCR, +which at this stage it does not plan to perform.) + +Currently in its first or organizational phase, POB found that it could +use a vendor selection process to facilitate a good deal of the +organizational work (e.g., creating a project team and advisory board, +confirming the validity of the plan, establishing the cost of the project +and a budget, selecting the materials to convert, and then raising the +necessary funds). + +POB developed numerous selection criteria, including: a firm committed +to image-document management, the ability to serve as systems integrator +in a large-scale project over several years, interest in developing the +requisite software as a standard rather than a custom product, and a +willingness to invest substantial resources in the project itself. + +Two vendors, DEC and Xerox, were selected as finalists in October 1991, +and with the support of the Commission on Preservation and Access, each +was commissioned to generate a detailed requirements analysis for the +project and then to submit a formal proposal for the completion of the +project, which included a budget and costs. The terms were that POB would +pay the loser. The results for Yale of involving a vendor included: +broad involvement of Yale staff across the board at a relatively low +cost, which may have long-term significance in carrying out the project +(twenty-five to thirty university people are engaged in POB); better +understanding of the factors that affect corporate response to markets +for imaging products; a competitive proposal; and a more sophisticated +view of the imaging markets. + +The most important factor that distinguished the vendors under +consideration was their identification with the customer. The size and +internal complexity of the company also was an important factor. POB was +looking at large companies that had substantial resources. In the end, +the process generated for Yale two competitive proposals, with Xerox's +the clear winner. WATERS then described the components of the proposal, +the design principles, and some of the costs estimated for the process. + +Components are essentially four: a conversion subsystem, a +network-accessible storage subsystem for 10,000 books (and POB expects +200 to 600 dpi storage), browsing stations distributed on the campus +network, and network access to the image printers. + +Among the design principles, POB wanted conversion at the highest +possible resolution. Assuming TIFF files, TIFF files with Group 4 +compression, TCP/IP, and ethernet network on campus, POB wanted a +client-server approach with image documents distributed to the +workstations and made accessible through native workstation interfaces +such as Windows. POB also insisted on a phased approach to +implementation: 1) a stand-alone, single-user, low-cost entry into the +business with a workstation focused on conversion and allowing POB to +explore user access; 2) movement into a higher-volume conversion with +network-accessible storage and multiple access stations; and 3) a +high-volume conversion, full-capacity storage, and multiple browsing +stations distributed throughout the campus. + +The costs proposed for start-up assumed the existence of the Yale network +and its two DocuTech image printers. Other start-up costs are estimated +at $1 million over the three phases. At the end of the project, the annual +operating costs estimated primarily for the software and hardware proposed +come to about $60,000, but these exclude costs for labor needed in the +conversion process, network and printer usage, and facilities management. + +Finally, the selection process produced for Yale a more sophisticated +view of the imaging markets: the management of complex documents in +image form is not a preservation problem, not a library problem, but a +general problem in a broad, general industry. Preservation materials are +useful for developing that market because of the qualities of the +material. For example, much of it is out of copyright. The resolution +of key issues such as the quality of scanning and image browsing also +will affect development of that market. + +The technology is readily available but changing rapidly. In this +context of rapid change, several factors affect quality and cost, to +which POB intends to pay particular attention, for example, the various +levels of resolution that can be achieved. POB believes it can bring +resolution up to 600 dpi, but an interpolation process from 400 to 600 is +more likely. The variation quality in microfilm will prove to be a +highly important factor. POB may reexamine the standards used to film in +the first place by looking at this process as a follow-on to microfilming. + +Other important factors include: the techniques available to the +operator for handling material, the ways of integrating quality control +into the digitizing work flow, and a work flow that includes indexing and +storage. POB's requirement was to be able to deal with quality control +at the point of scanning. Thus, thanks to Xerox, POB anticipates having +a mechanism which will allow it not only to scan in batch form, but to +review the material as it goes through the scanner and control quality +from the outset. + +The standards for measuring quality and costs depend greatly on the uses +of the material, including subsequent OCR, storage, printing, and +browsing. But especially at issue for POB is the facility for browsing. +This facility, WATERS said, is perhaps the weakest aspect of imaging +technology and the most in need of development. + +A variety of factors affect the usability of complex documents in image +form, among them: 1) the ability of the system to handle the full range +of document types, not just monographs but serials, multi-part +monographs, and manuscripts; 2) the location of the database of record +for bibliographic information about the image document, which POB wants +to enter once and in the most useful place, the on-line catalog; 3) a +document identifier for referencing the bibliographic information in one +place and the images in another; 4) the technique for making the basic +internal structure of the document accessible to the reader; and finally, +5) the physical presentation on the CRT of those documents. POB is ready +to complete this phase now. One last decision involves deciding which +material to scan. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * TIFF files constitute de facto standard * NARA's experience +with image conversion software and text conversion * RFC 1314 * +Considerable flux concerning available hardware and software solutions * +NAL through-put rate during scanning * Window management questions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the question-and-answer period that followed WATERS's presentation, +the following points emerged: + + * ZIDAR's statement about using TIFF files as a standard meant de + facto standard. This is what most people use and typically exchange + with other groups, across platforms, or even occasionally across + display software. + + * HOLMES commented on the unsuccessful experience of NARA in + attempting to run image-conversion software or to exchange between + applications: What are supposedly TIFF files go into other software + that is supposed to be able to accept TIFF but cannot recognize the + format and cannot deal with it, and thus renders the exchange + useless. Re text conversion, he noted the different recognition + rates obtained by substituting the make and model of scanners in + NARA's recent test of an "intelligent" character-recognition product + for a new company. In the selection of hardware and software, + HOLMES argued, software no longer constitutes the overriding factor + it did until about a year ago; rather it is perhaps important to + look at both now. + + * Danny Cohen and Alan Katz of the University of Southern California + Information Sciences Institute began circulating as an Internet RFC + (RFC 1314) about a month ago a standard for a TIFF interchange + format for Internet distribution of monochrome bit-mapped images, + which LYNCH said he believed would be used as a de facto standard. + + * FLEISCHHAUER's impression from hearing these reports and thinking + about AM's experience was that there is considerable flux concerning + available hardware and software solutions. HOOTON agreed and + commented at the same time on ZIDAR's statement that the equipment + employed affects the results produced. One cannot draw a complete + conclusion by saying it is difficult or impossible to perform OCR + from scanning microfilm, for example, with that device, that set of + parameters, and system requirements, because numerous other people + are accomplishing just that, using other components, perhaps. + HOOTON opined that both the hardware and the software were highly + important. Most of the problems discussed today have been solved in + numerous different ways by other people. Though it is good to be + cognizant of various experiences, this is not to say that it will + always be thus. + + * At NAL, the through-put rate of the scanning process for paper, + page by page, performing OCR, ranges from 300 to 600 pages per day; + not performing OCR is considerably faster, although how much faster + is not known. This is for scanning from bound books, which is much + slower. + + * WATERS commented on window management questions: DEC proposed an + X-Windows solution which was problematical for two reasons. One was + POB's requirement to be able to manipulate images on the workstation + and bring them down to the workstation itself and the other was + network usage. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +THOMA * Illustration of deficiencies in scanning and storage process * +Image quality in this process * Different costs entailed by better image +quality * Techniques for overcoming various de-ficiencies: fixed +thresholding, dynamic thresholding, dithering, image merge * Page edge +effects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +George THOMA, chief, Communications Engineering Branch, National Library +of Medicine (NLM), illustrated several of the deficiencies discussed by +the previous speakers. He introduced the topic of special problems by +noting the advantages of electronic imaging. For example, it is regenerable +because it is a coded file, and real-time quality control is possible with +electronic capture, whereas in photographic capture it is not. + +One of the difficulties discussed in the scanning and storage process was +image quality which, without belaboring the obvious, means different +things for maps, medical X-rays, or broadcast television. In the case of +documents, THOMA said, image quality boils down to legibility of the +textual parts, and fidelity in the case of gray or color photo print-type +material. Legibility boils down to scan density, the standard in most +cases being 300 dpi. Increasing the resolution with scanners that +perform 600 or 1200 dpi, however, comes at a cost. + +Better image quality entails at least four different kinds of costs: 1) +equipment costs, because the CCD (i.e., charge-couple device) with +greater number of elements costs more; 2) time costs that translate to +the actual capture costs, because manual labor is involved (the time is +also dependent on the fact that more data has to be moved around in the +machine in the scanning or network devices that perform the scanning as +well as the storage); 3) media costs, because at high resolutions larger +files have to be stored; and 4) transmission costs, because there is just +more data to be transmitted. + +But while resolution takes care of the issue of legibility in image +quality, other deficiencies have to do with contrast and elements on the +page scanned or the image that needed to be removed or clarified. Thus, +THOMA proceeded to illustrate various deficiencies, how they are +manifested, and several techniques to overcome them. + +Fixed thresholding was the first technique described, suitable for +black-and-white text, when the contrast does not vary over the page. One +can have many different threshold levels in scanning devices. Thus, +THOMA offered an example of extremely poor contrast, which resulted from +the fact that the stock was a heavy red. This is the sort of image that +when microfilmed fails to provide any legibility whatsoever. Fixed +thresholding is the way to change the black-to-red contrast to the +desired black-to-white contrast. + +Other examples included material that had been browned or yellowed by +age. This was also a case of contrast deficiency, and correction was +done by fixed thresholding. A final example boils down to the same +thing, slight variability, but it is not significant. Fixed thresholding +solves this problem as well. The microfilm equivalent is certainly legible, +but it comes with dark areas. Though THOMA did not have a slide of the +microfilm in this case, he did show the reproduced electronic image. + +When one has variable contrast over a page or the lighting over the page +area varies, especially in the case where a bound volume has light +shining on it, the image must be processed by a dynamic thresholding +scheme. One scheme, dynamic averaging, allows the threshold level not to +be fixed but to be recomputed for every pixel from the neighboring +characteristics. The neighbors of a pixel determine where the threshold +should be set for that pixel. + +THOMA showed an example of a page that had been made deficient by a +variety of techniques, including a burn mark, coffee stains, and a yellow +marker. Application of a fixed-thresholding scheme, THOMA argued, might +take care of several deficiencies on the page but not all of them. +Performing the calculation for a dynamic threshold setting, however, +removes most of the deficiencies so that at least the text is legible. + +Another problem is representing a gray level with black-and-white pixels +by a process known as dithering or electronic screening. But dithering +does not provide good image quality for pure black-and-white textual +material. THOMA illustrated this point with examples. Although its +suitability for photoprint is the reason for electronic screening or +dithering, it cannot be used for every compound image. In the document +that was distributed by CXP, THOMA noticed that the dithered image of the +IEEE test chart evinced some deterioration in the text. He presented an +extreme example of deterioration in the text in which compounded +documents had to be set right by other techniques. The technique +illustrated by the present example was an image merge in which the page +is scanned twice and the settings go from fixed threshold to the +dithering matrix; the resulting images are merged to give the best +results with each technique. + +THOMA illustrated how dithering is also used in nonphotographic or +nonprint materials with an example of a grayish page from a medical text, +which was reproduced to show all of the gray that appeared in the +original. Dithering provided a reproduction of all the gray in the +original of another example from the same text. + +THOMA finally illustrated the problem of bordering, or page-edge, +effects. Books and bound volumes that are placed on a photocopy machine +or a scanner produce page-edge effects that are undesirable for two +reasons: 1) the aesthetics of the image; after all, if the image is to +be preserved, one does not necessarily want to keep all of its +deficiencies; 2) compression (with the bordering problem THOMA +illustrated, the compression ratio deteriorated tremendously). One way +to eliminate this more serious problem is to have the operator at the +point of scanning window the part of the image that is desirable and +automatically turn all of the pixels out of that picture to white. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * AM's experience with scanning bound materials * Dithering +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +reported AM's experience with scanning bound materials, which he likened +to the problems involved in using photocopying machines. Very few +devices in the industry offer book-edge scanning, let alone book cradles. +The problem may be unsolvable, FLEISCHHAUER said, because a large enough +market does not exist for a preservation-quality scanner. AM is using a +Kurzweil scanner, which is a book-edge scanner now sold by Xerox. + +Devoting the remainder of his brief presentation to dithering, +FLEISCHHAUER related AM's experience with a contractor who was using +unsophisticated equipment and software to reduce moire patterns from +printed halftones. AM took the same image and used the dithering +algorithm that forms part of the same Kurzweil Xerox scanner; it +disguised moire patterns much more effectively. + +FLEISCHHAUER also observed that dithering produces a binary file which is +useful for numerous purposes, for example, printing it on a laser printer +without having to "re-halftone" it. But it tends to defeat efficient +compression, because the very thing that dithers to reduce moire patterns +also tends to work against compression schemes. AM thought the +difference in image quality was worth it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Relative use as a criterion for POB's selection of books to +be converted into digital form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period, WATERS noted that one of the criteria for +selecting books among the 10,000 to be converted into digital image form +would be how much relative use they would receive--a subject still +requiring evaluation. The challenge will be to understand whether +coherent bodies of material will increase usage or whether POB should +seek material that is being used, scan that, and make it more accessible. +POB might decide to digitize materials that are already heavily used, in +order to make them more accessible and decrease wear on them. Another +approach would be to provide a large body of intellectually coherent +material that may be used more in digital form than it is currently used +in microfilm. POB would seek material that was out of copyright. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BARONAS * Origin and scope of AIIM * Types of documents produced in +AIIM's standards program * Domain of AIIM's standardization work * AIIM's +structure * TC 171 and MS23 * Electronic image management standards * +Categories of EIM standardization where AIIM standards are being +developed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Jean BARONAS, senior manager, Department of Standards and Technology, +Association for Information and Image Management (AIIM), described the +not-for-profit association and the national and international programs +for standardization in which AIIM is active. + +Accredited for twenty-five years as the nation's standards development +organization for document image management, AIIM began life in a library +community developing microfilm standards. Today the association +maintains both its library and business-image management standardization +activities--and has moved into electronic image-management +standardization (EIM). + +BARONAS defined the program's scope. AIIM deals with: 1) the +terminology of standards and of the technology it uses; 2) methods of +measurement for the systems, as well as quality; 3) methodologies for +users to evaluate and measure quality; 4) the features of apparatus used +to manage and edit images; and 5) the procedures used to manage images. + +BARONAS noted that three types of documents are produced in the AIIM +standards program: the first two, accredited by the American National +Standards Institute (ANSI), are standards and standard recommended +practices. Recommended practices differ from standards in that they +contain more tutorial information. A technical report is not an ANSI +standard. Because AIIM's policies and procedures for developing +standards are approved by ANSI, its standards are labeled ANSI/AIIM, +followed by the number and title of the standard. + +BARONAS then illustrated the domain of AIIM's standardization work. For +example, AIIM is the administrator of the U.S. Technical Advisory Group +(TAG) to the International Standards Organization's (ISO) technical +committee, TC l7l Micrographics and Optical Memories for Document and +Image Recording, Storage, and Use. AIIM officially works through ANSI in +the international standardization process. + +BARONAS described AIIM's structure, including its board of directors, its +standards board of twelve individuals active in the image-management +industry, its strategic planning and legal admissibility task forces, and +its National Standards Council, which is comprised of the members of a +number of organizations who vote on every AIIM standard before it is +published. BARONAS pointed out that AIIM's liaisons deal with numerous +other standards developers, including the optical disk community, office +and publishing systems, image-codes-and-character set committees, and the +National Information Standards Organization (NISO). + +BARONAS illustrated the procedures of TC l7l, which covers all aspects of +image management. When AIIM's national program has conceptualized a new +project, it is usually submitted to the international level, so that the +member countries of TC l7l can simultaneously work on the development of +the standard or the technical report. BARONAS also illustrated a classic +microfilm standard, MS23, which deals with numerous imaging concepts that +apply to electronic imaging. Originally developed in the l970s, revised +in the l980s, and revised again in l991, this standard is scheduled for +another revision. MS23 is an active standard whereby users may propose +new density ranges and new methods of evaluating film images in the +standard's revision. + +BARONAS detailed several electronic image-management standards, for +instance, ANSI/AIIM MS44, a quality-control guideline for scanning 8.5" +by 11" black-and-white office documents. This standard is used with the +IEEE fax image--a continuous tone photographic image with gray scales, +text, and several continuous tone pictures--and AIIM test target number +2, a representative document used in office document management. + +BARONAS next outlined the four categories of EIM standardization in which +AIIM standards are being developed: transfer and retrieval, evaluation, +optical disc and document scanning applications, and design and +conversion of documents. She detailed several of the main projects of +each: 1) in the category of image transfer and retrieval, a bi-level +image transfer format, ANSI/AIIM MS53, which is a proposed standard that +describes a file header for image transfer between unlike systems when +the images are compressed using G3 and G4 compression; 2) the category of +image evaluation, which includes the AIIM-proposed TR26 tutorial on image +resolution (this technical report will treat the differences and +similarities between classical or photographic and electronic imaging); +3) design and conversion, which includes a proposed technical report +called "Forms Design Optimization for EIM" (this report considers how +general-purpose business forms can be best designed so that scanning is +optimized; reprographic characteristics such as type, rules, background, +tint, and color will likewise be treated in the technical report); 4) +disk and document scanning applications includes a project a) on planning +platters and disk management, b) on generating an application profile for +EIM when images are stored and distributed on CD-ROM, and c) on +evaluating SCSI2, and how a common command set can be generated for SCSI2 +so that document scanners are more easily integrated. (ANSI/AIIM MS53 +will also apply to compressed images.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BATTIN * The implications of standards for preservation * A major +obstacle to successful cooperation * A hindrance to access in the digital +environment * Standards a double-edged sword for those concerned with the +preservation of the human record * Near-term prognosis for reliable +archival standards * Preservation concerns for electronic media * Need +for reconceptualizing our preservation principles * Standards in the real +world and the politics of reproduction * Need to redefine the concept of +archival and to begin to think in terms of life cycles * Cooperation and +the La Guardia Eight * Concerns generated by discussions on the problems +of preserving text and image * General principles to be adopted in a +world without standards * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Patricia BATTIN, president, the Commission on Preservation and Access +(CPA), addressed the implications of standards for preservation. She +listed several areas where the library profession and the analog world of +the printed book had made enormous contributions over the past hundred +years--for example, in bibliographic formats, binding standards, and, most +important, in determining what constitutes longevity or archival quality. + +Although standards have lightened the preservation burden through the +development of national and international collaborative programs, +nevertheless, a pervasive mistrust of other people's standards remains a +major obstacle to successful cooperation, BATTIN said. + +The zeal to achieve perfection, regardless of the cost, has hindered +rather than facilitated access in some instances, and in the digital +environment, where no real standards exist, has brought an ironically +just reward. + +BATTIN argued that standards are a double-edged sword for those concerned +with the preservation of the human record, that is, the provision of +access to recorded knowledge in a multitude of media as far into the +future as possible. Standards are essential to facilitate +interconnectivity and access, but, BATTIN said, as LYNCH pointed out +yesterday, if set too soon they can hinder creativity, expansion of +capability, and the broadening of access. The characteristics of +standards for digital imagery differ radically from those for analog +imagery. And the nature of digital technology implies continuing +volatility and change. To reiterate, precipitous standard-setting can +inhibit creativity, but delayed standard-setting results in chaos. + +Since in BATTIN'S opinion the near-term prognosis for reliable archival +standards, as defined by librarians in the analog world, is poor, two +alternatives remain: standing pat with the old technology, or +reconceptualizing. + +Preservation concerns for electronic media fall into two general domains. +One is the continuing assurance of access to knowledge originally +generated, stored, disseminated, and used in electronic form. This +domain contains several subdivisions, including 1) the closed, +proprietary systems discussed the previous day, bundled information such +as electronic journals and government agency records, and electronically +produced or captured raw data; and 2) the application of digital +technologies to the reformatting of materials originally published on a +deteriorating analog medium such as acid paper or videotape. + +The preservation of electronic media requires a reconceptualizing of our +preservation principles during a volatile, standardless transition which +may last far longer than any of us envision today. BATTIN urged the +necessity of shifting focus from assessing, measuring, and setting +standards for the permanence of the medium to the concept of managing +continuing access to information stored on a variety of media and +requiring a variety of ever-changing hardware and software for access--a +fundamental shift for the library profession. + +BATTIN offered a primer on how to move forward with reasonable confidence +in a world without standards. Her comments fell roughly into two sections: +1) standards in the real world and 2) the politics of reproduction. + +In regard to real-world standards, BATTIN argued the need to redefine the +concept of archive and to begin to think in terms of life cycles. In +the past, the naive assumption that paper would last forever produced a +cavalier attitude toward life cycles. The transient nature of the +electronic media has compelled people to recognize and accept upfront the +concept of life cycles in place of permanency. + +Digital standards have to be developed and set in a cooperative context +to ensure efficient exchange of information. Moreover, during this +transition period, greater flexibility concerning how concepts such as +backup copies and archival copies in the CXP are defined is necessary, +or the opportunity to move forward will be lost. + +In terms of cooperation, particularly in the university setting, BATTIN +also argued the need to avoid going off in a hundred different +directions. The CPA has catalyzed a small group of universities called +the La Guardia Eight--because La Guardia Airport is where meetings take +place--Harvard, Yale, Cornell, Princeton, Penn State, Tennessee, +Stanford, and USC, to develop a digital preservation consortium to look +at all these issues and develop de facto standards as we move along, +instead of waiting for something that is officially blessed. Continuing +to apply analog values and definitions of standards to the digital +environment, BATTIN said, will effectively lead to forfeiture of the +benefits of digital technology to research and scholarship. + +Under the second rubric, the politics of reproduction, BATTIN reiterated +an oft-made argument concerning the electronic library, namely, that it +is more difficult to transform than to create, and nowhere is that belief +expressed more dramatically than in the conversion of brittle books to +new media. Preserving information published in electronic media involves +making sure the information remains accessible and that digital +information is not lost through reproduction. In the analog world of +photocopies and microfilm, the issue of fidelity to the original becomes +paramount, as do issues of "Whose fidelity?" and "Whose original?" + +BATTIN elaborated these arguments with a few examples from a recent study +conducted by the CPA on the problems of preserving text and image. +Discussions with scholars, librarians, and curators in a variety of +disciplines dependent on text and image generated a variety of concerns, +for example: 1) Copy what is, not what the technology is capable of. +This is very important for the history of ideas. Scholars wish to know +what the author saw and worked from. And make available at the +workstation the opportunity to erase all the defects and enhance the +presentation. 2) The fidelity of reproduction--what is good enough, what +can we afford, and the difference it makes--issues of subjective versus +objective resolution. 3) The differences between primary and secondary +users. Restricting the definition of primary user to the one in whose +discipline the material has been published runs one headlong into the +reality that these printed books have had a host of other users from a +host of other disciplines, who not only were looking for very different +things, but who also shared values very different from those of the +primary user. 4) The relationship of the standard of reproduction to new +capabilities of scholarship--the browsing standard versus an archival +standard. How good must the archival standard be? Can a distinction be +drawn between potential users in setting standards for reproduction? +Archival storage, use copies, browsing copies--ought an attempt to set +standards even be made? 5) Finally, costs. How much are we prepared to +pay to capture absolute fidelity? What are the trade-offs between vastly +enhanced access, degrees of fidelity, and costs? + +These standards, BATTIN concluded, serve to complicate further the +reproduction process, and add to the long list of technical standards +that are necessary to ensure widespread access. Ways to articulate and +analyze the costs that are attached to the different levels of standards +must be found. + +Given the chaos concerning standards, which promises to linger for the +foreseeable future, BATTIN urged adoption of the following general +principles: + + * Strive to understand the changing information requirements of + scholarly disciplines as more and more technology is integrated into + the process of research and scholarly communication in order to meet + future scholarly needs, not to build for the past. Capture + deteriorating information at the highest affordable resolution, even + though the dissemination and display technologies will lag. + + * Develop cooperative mechanisms to foster agreement on protocols + for document structure and other interchange mechanisms necessary + for widespread dissemination and use before official standards are + set. + + * Accept that, in a transition period, de facto standards will have + to be developed. + + * Capture information in a way that keeps all options open and + provides for total convertibility: OCR, scanning of microfilm, + producing microfilm from scanned documents, etc. + + * Work closely with the generators of information and the builders + of networks and databases to ensure that continuing accessibility is + a primary concern from the beginning. + + * Piggyback on standards under development for the broad market, and + avoid library-specific standards; work with the vendors, in order to + take advantage of that which is being standardized for the rest of + the world. + + * Concentrate efforts on managing permanence in the digital world, + rather than perfecting the longevity of a particular medium. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional comments on TIFF * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief discussion period that followed BATTIN's presentation, +BARONAS explained that TIFF was not developed in collaboration with or +under the auspices of AIIM. TIFF is a company product, not a standard, +is owned by two corporations, and is always changing. BARONAS also +observed that ANSI/AIIM MS53, a bi-level image file transfer format that +allows unlike systems to exchange images, is compatible with TIFF as well +as with DEC's architecture and IBM's MODCA/IOCA. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOOTON * Several questions to be considered in discussing text conversion +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON introduced the final topic, text conversion, by noting that it is +becoming an increasingly important part of the imaging business. Many +people now realize that it enhances their system to be able to have more +and more character data as part of their imaging system. Re the issue of +OCR versus rekeying, HOOTON posed several questions: How does one get +text into computer-readable form? Does one use automated processes? +Does one attempt to eliminate the use of operators where possible? +Standards for accuracy, he said, are extremely important: it makes a +major difference in cost and time whether one sets as a standard 98.5 +percent acceptance or 99.5 percent. He mentioned outsourcing as a +possibility for converting text. Finally, what one does with the image +to prepare it for the recognition process is also important, he said, +because such preparation changes how recognition is viewed, as well as +facilitates recognition itself. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LESK * Roles of participants in CORE * Data flow * The scanning process * +The image interface * Results of experiments involving the use of +electronic resources and traditional paper copies * Testing the issue of +serendipity * Conclusions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Michael LESK, executive director, Computer Science Research, Bell +Communications Research, Inc. (Bellcore), discussed the Chemical Online +Retrieval Experiment (CORE), a cooperative project involving Cornell +University, OCLC, Bellcore, and the American Chemical Society (ACS). + +LESK spoke on 1) how the scanning was performed, including the unusual +feature of page segmentation, and 2) the use made of the text and the +image in experiments. + +Working with the chemistry journals (because ACS has been saving its +typesetting tapes since the mid-1970s and thus has a significant back-run +of the most important chemistry journals in the United States), CORE is +attempting to create an automated chemical library. Approximately a +quarter of the pages by square inch are made up of images of +quasi-pictorial material; dealing with the graphic components of the +pages is extremely important. LESK described the roles of participants +in CORE: 1) ACS provides copyright permission, journals on paper, +journals on microfilm, and some of the definitions of the files; 2) at +Bellcore, LESK chiefly performs the data preparation, while Dennis Egan +performs experiments on the users of chemical abstracts, and supplies the +indexing and numerous magnetic tapes; 3) Cornell provides the site of the +experiment; 4) OCLC develops retrieval software and other user interfaces. +Various manufacturers and publishers have furnished other help. + +Concerning data flow, Bellcore receives microfilm and paper from ACS; the +microfilm is scanned by outside vendors, while the paper is scanned +inhouse on an Improvision scanner, twenty pages per minute at 300 dpi, +which provides sufficient quality for all practical uses. LESK would +prefer to have more gray level, because one of the ACS journals prints on +some colored pages, which creates a problem. + +Bellcore performs all this scanning, creates a page-image file, and also +selects from the pages the graphics, to mix with the text file (which is +discussed later in the Workshop). The user is always searching the ASCII +file, but she or he may see a display based on the ASCII or a display +based on the images. + +LESK illustrated how the program performs page analysis, and the image +interface. (The user types several words, is presented with a list-- +usually of the titles of articles contained in an issue--that derives +from the ASCII, clicks on an icon and receives an image that mirrors an +ACS page.) LESK also illustrated an alternative interface, based on text +on the ASCII, the so-called SuperBook interface from Bellcore. + +LESK next presented the results of an experiment conducted by Dennis Egan +and involving thirty-six students at Cornell, one third of them +undergraduate chemistry majors, one third senior undergraduate chemistry +majors, and one third graduate chemistry students. A third of them +received the paper journals, the traditional paper copies and chemical +abstracts on paper. A third received image displays of the pictures of +the pages, and a third received the text display with pop-up graphics. + +The students were given several questions made up by some chemistry +professors. The questions fell into five classes, ranging from very easy +to very difficult, and included questions designed to simulate browsing +as well as a traditional information retrieval-type task. + +LESK furnished the following results. In the straightforward question +search--the question being, what is the phosphorus oxygen bond distance +and hydroxy phosphate?--the students were told that they could take +fifteen minutes and, then, if they wished, give up. The students with +paper took more than fifteen minutes on average, and yet most of them +gave up. The students with either electronic format, text or image, +received good scores in reasonable time, hardly ever had to give up, and +usually found the right answer. + +In the browsing study, the students were given a list of eight topics, +told to imagine that an issue of the Journal of the American Chemical +Society had just appeared on their desks, and were also told to flip +through it and to find topics mentioned in the issue. The average scores +were about the same. (The students were told to answer yes or no about +whether or not particular topics appeared.) The errors, however, were +quite different. The students with paper rarely said that something +appeared when it had not. But they often failed to find something +actually mentioned in the issue. The computer people found numerous +things, but they also frequently said that a topic was mentioned when it +was not. (The reason, of course, was that they were performing word +searches. They were finding that words were mentioned and they were +concluding that they had accomplished their task.) + +This question also contained a trick to test the issue of serendipity. +The students were given another list of eight topics and instructed, +without taking a second look at the journal, to recall how many of this +new list of eight topics were in this particular issue. This was an +attempt to see if they performed better at remembering what they were not +looking for. They all performed about the same, paper or electronics, +about 62 percent accurate. In short, LESK said, people were not very +good when it came to serendipity, but they were no worse at it with +computers than they were with paper. + +(LESK gave a parenthetical illustration of the learning curve of students +who used SuperBook.) + +The students using the electronic systems started off worse than the ones +using print, but by the third of the three sessions in the series had +caught up to print. As one might expect, electronics provide a much +better means of finding what one wants to read; reading speeds, once the +object of the search has been found, are about the same. + +Almost none of the students could perform the hard task--the analogous +transformation. (It would require the expertise of organic chemists to +complete.) But an interesting result was that the students using the text +search performed terribly, while those using the image system did best. +That the text search system is driven by text offers the explanation. +Everything is focused on the text; to see the pictures, one must press +on an icon. Many students found the right article containing the answer +to the question, but they did not click on the icon to bring up the right +figure and see it. They did not know that they had found the right place, +and thus got it wrong. + +The short answer demonstrated by this experiment was that in the event +one does not know what to read, one needs the electronic systems; the +electronic systems hold no advantage at the moment if one knows what to +read, but neither do they impose a penalty. + +LESK concluded by commenting that, on one hand, the image system was easy +to use. On the other hand, the text display system, which represented +twenty man-years of work in programming and polishing, was not winning, +because the text was not being read, just searched. The much easier +system is highly competitive as well as remarkably effective for the +actual chemists. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ERWAY * Most challenging aspect of working on AM * Assumptions guiding +AM's approach * Testing different types of service bureaus * AM's +requirement for 99.95 percent accuracy * Requirements for text-coding * +Additional factors influencing AM's approach to coding * Results of AM's +experience with rekeying * Other problems in dealing with service bureaus +* Quality control the most time-consuming aspect of contracting out +conversion * Long-term outlook uncertain * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To Ricky ERWAY, associate coordinator, American Memory, Library of +Congress, the constant variety of conversion projects taking place +simultaneously represented perhaps the most challenging aspect of working +on AM. Thus, the challenge was not to find a solution for text +conversion but a tool kit of solutions to apply to LC's varied +collections that need to be converted. ERWAY limited her remarks to the +process of converting text to machine-readable form, and the variety of +LC's text collections, for example, bound volumes, microfilm, and +handwritten manuscripts. + +Two assumptions have guided AM's approach, ERWAY said: 1) A desire not +to perform the conversion inhouse. Because of the variety of formats and +types of texts, to capitalize the equipment and have the talents and +skills to operate them at LC would be extremely expensive. Further, the +natural inclination to upgrade to newer and better equipment each year +made it reasonable for AM to focus on what it did best and seek external +conversion services. Using service bureaus also allowed AM to have +several types of operations take place at the same time. 2) AM was not a +technology project, but an effort to improve access to library +collections. Hence, whether text was converted using OCR or rekeying +mattered little to AM. What mattered were cost and accuracy of results. + +AM considered different types of service bureaus and selected three to +perform several small tests in order to acquire a sense of the field. +The sample collections with which they worked included handwritten +correspondence, typewritten manuscripts from the 1940s, and +eighteenth-century printed broadsides on microfilm. On none of these +samples was OCR performed; they were all rekeyed. AM had several special +requirements for the three service bureaus it had engaged. For instance, +any errors in the original text were to be retained. Working from bound +volumes or anything that could not be sheet-fed also constituted a factor +eliminating companies that would have performed OCR. + +AM requires 99.95 percent accuracy, which, though it sounds high, often +means one or two errors per page. The initial batch of test samples +contained several handwritten materials for which AM did not require +text-coding. The results, ERWAY reported, were in all cases fairly +comparable: for the most part, all three service bureaus achieved 99.95 +percent accuracy. AM was satisfied with the work but surprised at the cost. + +As AM began converting whole collections, it retained the requirement for +99.95 percent accuracy and added requirements for text-coding. AM needed +to begin performing work more than three years ago before LC requirements +for SGML applications had been established. Since AM's goal was simply +to retain any of the intellectual content represented by the formatting +of the document (which would be lost if one performed a straight ASCII +conversion), AM used "SGML-like" codes. These codes resembled SGML tags +but were used without the benefit of document-type definitions. AM found +that many service bureaus were not yet SGML-proficient. + +Additional factors influencing the approach AM took with respect to +coding included: 1) the inability of any known microcomputer-based +user-retrieval software to take advantage of SGML coding; and 2) the +multiple inconsistencies in format of the older documents, which +confirmed AM in its desire not to attempt to force the different formats +to conform to a single document-type definition (DTD) and thus create the +need for a separate DTD for each document. + +The five text collections that AM has converted or is in the process of +converting include a collection of eighteenth-century broadsides, a +collection of pamphlets, two typescript document collections, and a +collection of 150 books. + +ERWAY next reviewed the results of AM's experience with rekeying, noting +again that because the bulk of AM's materials are historical, the quality +of the text often does not lend itself to OCR. While non-English +speakers are less likely to guess or elaborate or correct typos in the +original text, they are also less able to infer what we would; they also +are nearly incapable of converting handwritten text. Another +disadvantage of working with overseas keyers is that they are much less +likely to telephone with questions, especially on the coding, with the +result that they develop their own rules as they encounter new +situations. + +Government contracting procedures and time frames posed a major challenge +to performing the conversion. Many service bureaus are not accustomed to +retaining the image, even if they perform OCR. Thus, questions of image +format and storage media were somewhat novel to many of them. ERWAY also +remarked other problems in dealing with service bureaus, for example, +their inability to perform text conversion from the kind of microfilm +that LC uses for preservation purposes. + +But quality control, in ERWAY's experience, was the most time-consuming +aspect of contracting out conversion. AM has been attempting to perform +a 10-percent quality review, looking at either every tenth document or +every tenth page to make certain that the service bureaus are maintaining +99.95 percent accuracy. But even if they are complying with the +requirement for accuracy, finding errors produces a desire to correct +them and, in turn, to clean up the whole collection, which defeats the +purpose to some extent. Even a double entry requires a +character-by-character comparison to the original to meet the accuracy +requirement. LC is not accustomed to publish imperfect texts, which +makes attempting to deal with the industry standard an emotionally +fraught issue for AM. As was mentioned in the previous day's discussion, +going from 99.95 to 99.99 percent accuracy usually doubles costs and +means a third keying or another complete run-through of the text. + +Although AM has learned much from its experiences with various collections +and various service bureaus, ERWAY concluded pessimistically that no +breakthrough has been achieved. Incremental improvements have occurred +in some of the OCR technology, some of the processes, and some of the +standards acceptances, which, though they may lead to somewhat lower costs, +do not offer much encouragement to many people who are anxiously awaiting +the day that the entire contents of LC are available on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * Several answers to why one attempts to perform full-text +conversion * Per page cost of performing OCR * Typical problems +encountered during editing * Editing poor copy OCR vs. rekeying * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), offered several answers to +the question of why one attempts to perform full-text conversion: 1) +Text in an image can be read by a human but not by a computer, so of +course it is not searchable and there is not much one can do with it. 2) +Some material simply requires word-level access. For instance, the legal +profession insists on full-text access to its material; with taxonomic or +geographic material, which entails numerous names, one virtually requires +word-level access. 3) Full text permits rapid browsing and searching, +something that cannot be achieved in an image with today's technology. +4) Text stored as ASCII and delivered in ASCII is standardized and highly +portable. 5) People just want full-text searching, even those who do not +know how to do it. NAL, for the most part, is performing OCR at an +actual cost per average-size page of approximately $7. NAL scans the +page to create the electronic image and passes it through the OCR device. + +ZIDAR next rehearsed several typical problems encountered during editing. +Praising the celerity of her student workers, ZIDAR observed that editing +requires approximately five to ten minutes per page, assuming that there +are no large tables to audit. Confusion among the three characters I, 1, +and l, constitutes perhaps the most common problem encountered. Zeroes +and O's also are frequently confused. Double M's create a particular +problem, even on clean pages. They are so wide in most fonts that they +touch, and the system simply cannot tell where one letter ends and the +other begins. Complex page formats occasionally fail to columnate +properly, which entails rescanning as though one were working with a +single column, entering the ASCII, and decolumnating for better +searching. With proportionally spaced text, OCR can have difficulty +discerning what is a space and what are merely spaces between letters, as +opposed to spaces between words, and therefore will merge text or break +up words where it should not. + +ZIDAR said that it can often take longer to edit a poor-copy OCR than to +key it from scratch. NAL has also experimented with partial editing of +text, whereby project workers go into and clean up the format, removing +stray characters but not running a spell-check. NAL corrects typos in +the title and authors' names, which provides a foothold for searching and +browsing. Even extremely poor-quality OCR (e.g., 60-percent accuracy) +can still be searched, because numerous words are correct, while the +important words are probably repeated often enough that they are likely +to be found correct somewhere. Librarians, however, cannot tolerate this +situation, though end users seem more willing to use this text for +searching, provided that NAL indicates that it is unedited. ZIDAR +concluded that rekeying of text may be the best route to take, in spite +of numerous problems with quality control and cost. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Modifying an image before performing OCR * NAL's costs per +page *AM's costs per page and experience with Federal Prison Industries * +Elements comprising NATDP's costs per page * OCR and structured markup * +Distinction between the structure of a document and its representation +when put on the screen or printed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON prefaced the lengthy discussion that followed with several +comments about modifying an image before one reaches the point of +performing OCR. For example, in regard to an application containing a +significant amount of redundant data, such as form-type data, numerous +companies today are working on various kinds of form renewal, prior to +going through a recognition process, by using dropout colors. Thus, +acquiring access to form design or using electronic means are worth +considering. HOOTON also noted that conversion usually makes or breaks +one's imaging system. It is extremely important, extremely costly in +terms of either capital investment or service, and determines the quality +of the remainder of one's system, because it determines the character of +the raw material used by the system. + +Concerning the four projects undertaken by NAL, two inside and two +performed by outside contractors, ZIDAR revealed that an in-house service +bureau executed the first at a cost between $8 and $10 per page for +everything, including building of the database. The project undertaken +by the Consultative Group on International Agricultural Research (CGIAR) +cost approximately $10 per page for the conversion, plus some expenses +for the software and building of the database. The Acid Rain Project--a +two-disk set produced by the University of Vermont, consisting of +Canadian publications on acid rain--cost $6.70 per page for everything, +including keying of the text, which was double keyed, scanning of the +images, and building of the database. The in-house project offered +considerable ease of convenience and greater control of the process. On +the other hand, the service bureaus know their job and perform it +expeditiously, because they have more people. + +As a useful comparison, ERWAY revealed AM's costs as follows: $0.75 +cents to $0.85 cents per thousand characters, with an average page +containing 2,700 characters. Requirements for coding and imaging +increase the costs. Thus, conversion of the text, including the coding, +costs approximately $3 per page. (This figure does not include the +imaging and database-building included in the NAL costs.) AM also +enjoyed a happy experience with Federal Prison Industries, which +precluded the necessity of going through the request-for-proposal process +to award a contract, because it is another government agency. The +prisoners performed AM's rekeying just as well as other service bureaus +and proved handy as well. AM shipped them the books, which they would +photocopy on a book-edge scanner. They would perform the markup on +photocopies, return the books as soon as they were done with them, +perform the keying, and return the material to AM on WORM disks. + +ZIDAR detailed the elements that constitute the previously noted cost of +approximately $7 per page. Most significant is the editing, correction +of errors, and spell-checkings, which though they may sound easy to +perform require, in fact, a great deal of time. Reformatting text also +takes a while, but a significant amount of NAL's expenses are for equipment, +which was extremely expensive when purchased because it was one of the few +systems on the market. The costs of equipment are being amortized over +five years but are still quite high, nearly $2,000 per month. + +HOCKEY raised a general question concerning OCR and the amount of editing +required (substantial in her experience) to generate the kind of +structured markup necessary for manipulating the text on the computer or +loading it into any retrieval system. She wondered if the speakers could +extend the previous question about the cost-benefit of adding or exerting +structured markup. ERWAY noted that several OCR systems retain italics, +bolding, and other spatial formatting. While the material may not be in +the format desired, these systems possess the ability to remove the +original materials quickly from the hands of the people performing the +conversion, as well as to retain that information so that users can work +with it. HOCKEY rejoined that the current thinking on markup is that one +should not say that something is italic or bold so much as why it is that +way. To be sure, one needs to know that something was italicized, but +how can one get from one to the other? One can map from the structure to +the typographic representation. + +FLEISCHHAUER suggested that, given the 100 million items the Library +holds, it may not be possible for LC to do more than report that a thing +was in italics as opposed to why it was italics, although that may be +desirable in some contexts. Promising to talk a bit during the afternoon +session about several experiments OCLC performed on automatic recognition +of document elements, and which they hoped to extend, WEIBEL said that in +fact one can recognize the major elements of a document with a fairly +high degree of reliability, at least as good as OCR. STEVENS drew a +useful distinction between standard, generalized markup (i.e., defining +for a document-type definition the structure of the document), and what +he termed a style sheet, which had to do with italics, bolding, and other +forms of emphasis. Thus, two different components are at work, one being +the structure of the document itself (its logic), and the other being its +representation when it is put on the screen or printed. + + ****** + +SESSION V. APPROACHES TO PREPARING ELECTRONIC TEXTS + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOCKEY * Text in ASCII and the representation of electronic text versus +an image * The need to look at ways of using markup to assist retrieval * +The need for an encoding format that will be reusable and multifunctional ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan HOCKEY, director, Center for Electronic Texts in the Humanities +(CETH), Rutgers and Princeton Universities, announced that one talk +(WEIBEL's) was moved into this session from the morning and that David +Packard was unable to attend. The session would attempt to focus more on +what one can do with a text in ASCII and the representation of electronic +text rather than just an image, what one can do with a computer that +cannot be done with a book or an image. It would be argued that one can +do much more than just read a text, and from that starting point one can +use markup and methods of preparing the text to take full advantage of +the capability of the computer. That would lead to a discussion of what +the European Community calls REUSABILITY, what may better be termed +DURABILITY, that is, how to prepare or make a text that will last a long +time and that can be used for as many applications as possible, which +would lead to issues of improving intellectual access. + +HOCKEY urged the need to look at ways of using markup to facilitate retrieval, +not just for referencing or to help locate an item that is retrieved, but also to put markup tags in +a text to help retrieve the thing sought either with linguistic tagging or +interpretation. HOCKEY also argued that little advancement had occurred in +the software tools currently available for retrieving and searching text. +She pressed the desideratum of going beyond Boolean searches and performing +more sophisticated searching, which the insertion of more markup in the text +would facilitate. Thinking about electronic texts as opposed to images means +considering material that will never appear in print form, or print will not +be its primary form, that is, material which only appears in electronic form. +HOCKEY alluded to the history and the need for markup and tagging and +electronic text, which was developed through the use of computers in the +humanities; as MICHELSON had observed, Father Busa had started in 1949 +to prepare the first-ever text on the computer. + +HOCKEY remarked several large projects, particularly in Europe, for the +compilation of dictionaries, language studies, and language analysis, in +which people have built up archives of text and have begun to recognize +the need for an encoding format that will be reusable and multifunctional, +that can be used not just to print the text, which may be assumed to be a +byproduct of what one wants to do, but to structure it inside the computer +so that it can be searched, built into a Hypertext system, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WEIBEL * OCLC's approach to preparing electronic text: retroconversion, +keying of texts, more automated ways of developing data * Project ADAPT +and the CORE Project * Intelligent character recognition does not exist * +Advantages of SGML * Data should be free of procedural markup; +descriptive markup strongly advocated * OCLC's interface illustrated * +Storage requirements and costs for putting a lot of information on line * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Stuart WEIBEL, senior research scientist, Online Computer Library Center, +Inc. (OCLC), described OCLC's approach to preparing electronic text. He +argued that the electronic world into which we are moving must +accommodate not only the future but the past as well, and to some degree +even the present. Thus, starting out at one end with retroconversion and +keying of texts, one would like to move toward much more automated ways +of developing data. + +For example, Project ADAPT had to do with automatically converting +document images into a structured document database with OCR text as +indexing and also a little bit of automatic formatting and tagging of +that text. The CORE project hosted by Cornell University, Bellcore, +OCLC, the American Chemical Society, and Chemical Abstracts, constitutes +WEIBEL's principal concern at the moment. This project is an example of +converting text for which one already has a machine-readable version into +a format more suitable for electronic delivery and database searching. +(Since Michael LESK had previously described CORE, WEIBEL would say +little concerning it.) Borrowing a chemical phrase, de novo synthesis, +WEIBEL cited the Online Journal of Current Clinical Trials as an example +of de novo electronic publishing, that is, a form in which the primary +form of the information is electronic. + +Project ADAPT, then, which OCLC completed a couple of years ago and in +fact is about to resume, is a model in which one takes page images either +in paper or microfilm and converts them automatically to a searchable +electronic database, either on-line or local. The operating assumption +is that accepting some blemishes in the data, especially for +retroconversion of materials, will make it possible to accomplish more. +Not enough money is available to support perfect conversion. + +WEIBEL related several steps taken to perform image preprocessing +(processing on the image before performing optical character +recognition), as well as image postprocessing. He denied the existence +of intelligent character recognition and asserted that what is wanted is +page recognition, which is a long way off. OCLC has experimented with +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000, but it +is not good enough. It will never be perfect. + +Concerning the CORE Project, WEIBEL observed that Bellcore is taking the +topography files, extracting the page images, and converting those +topography files to SGML markup. LESK hands that data off to OCLC, which +builds that data into a Newton database, the same system that underlies +the on-line system in virtually all of the reference products at OCLC. +The long-term goal is to make the systems interoperable so that not just +Bellcore's system and OCLC's system can access this data, but other +systems can as well, and the key to that is the Z39.50 common command +language and the full-text extension. Z39.50 is fine for MARC records, +but is not enough to do it for full text (that is, make full texts +interoperable). + +WEIBEL next outlined the critical role of SGML for a variety of purposes, +for example, as noted by HOCKEY, in the world of extremely large +databases, using highly structured data to perform field searches. +WEIBEL argued that by building the structure of the data in (i.e., the +structure of the data originally on a printed page), it becomes easy to +look at a journal article even if one cannot read the characters and know +where the title or author is, or what the sections of that document would be. +OCLC wants to make that structure explicit in the database, because it will +be important for retrieval purposes. + +The second big advantage of SGML is that it gives one the ability to +build structure into the database that can be used for display purposes +without contaminating the data with instructions about how to format +things. The distinction lies between procedural markup, which tells one +where to put dots on the page, and descriptive markup, which describes +the elements of a document. + +WEIBEL believes that there should be no procedural markup in the data at +all, that the data should be completely unsullied by information about +italics or boldness. That should be left up to the display device, +whether that display device is a page printer or a screen display device. +By keeping one's database free of that kind of contamination, one can +make decisions down the road, for example, reorganize the data in ways +that are not cramped by built-in notions of what should be italic and +what should be bold. WEIBEL strongly advocated descriptive markup. As +an example, he illustrated the index structure in the CORE data. With +subsequent illustrated examples of markup, WEIBEL acknowledged the common +complaint that SGML is hard to read in its native form, although markup +decreases considerably once one gets into the body. Without the markup, +however, one would not have the structure in the data. One can pass +markup through a LaTeX processor and convert it relatively easily to a +printed version of the document. + +WEIBEL next illustrated an extremely cluttered screen dump of OCLC's +system, in order to show as much as possible the inherent capability on +the screen. (He noted parenthetically that he had become a supporter of +X-Windows as a result of the progress of the CORE Project.) WEIBEL also +illustrated the two major parts of the interface: l) a control box that +allows one to generate lists of items, which resembles a small table of +contents based on key words one wishes to search, and 2) a document +viewer, which is a separate process in and of itself. He demonstrated +how to follow links through the electronic database simply by selecting +the appropriate button and bringing them up. He also noted problems that +remain to be accommodated in the interface (e.g., as pointed out by LESK, +what happens when users do not click on the icon for the figure). + +Given the constraints of time, WEIBEL omitted a large number of ancillary +items in order to say a few words concerning storage requirements and +what will be required to put a lot of things on line. Since it is +extremely expensive to reconvert all of this data, especially if it is +just in paper form (and even if it is in electronic form in typesetting +tapes), he advocated building journals electronically from the start. In +that case, if one only has text graphics and indexing (which is all that +one needs with de novo electronic publishing, because there is no need to +go back and look at bit-maps of pages), one can get 10,000 journals of +full text, or almost 6 million pages per year. These pages can be put in +approximately 135 gigabytes of storage, which is not all that much, +WEIBEL said. For twenty years, something less than three terabytes would +be required. WEIBEL calculated the costs of storing this information as +follows: If a gigabyte costs approximately $1,000, then a terabyte costs +approximately $1 million to buy in terms of hardware. One also needs a +building to put it in and a staff like OCLC to handle that information. +So, to support a terabyte, multiply by five, which gives $5 million per +year for a supported terabyte of data. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Tapes saved by ACS are the typography files originally +supporting publication of the journal * Cost of building tagged text into +the database * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed WEIBEL's +presentation, these clarifications emerged. The tapes saved by the +American Chemical Society are the typography files that originally +supported the publication of the journal. Although they are not tagged +in SGML, they are tagged in very fine detail. Every single sentence is +marked, all the registry numbers, all the publications issues, dates, and +volumes. No cost figures on tagging material on a per-megabyte basis +were available. Because ACS's typesetting system runs from tagged text, +there is no extra cost per article. It was unknown what it costs ACS to +keyboard the tagged text rather than just keyboard the text in the +cheapest process. In other words, since one intends to publish things +and will need to build tagged text into a typography system in any case, +if one does that in such a way that it can drive not only typography but +an electronic system (which is what ACS intends to do--move to SGML +publishing), the marginal cost is zero. The marginal cost represents the +cost of building tagged text into the database, which is small. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +SPERBERG-McQUEEN * Distinction between texts and computers * Implications +of recognizing that all representation is encoding * Dealing with +complicated representations of text entails the need for a grammar of +documents * Variety of forms of formal grammars * Text as a bit-mapped +image does not represent a serious attempt to represent text in +electronic form * SGML, the TEI, document-type declarations, and the +reusability and longevity of data * TEI conformance explicitly allows +extension or modification of the TEI tag set * Administrative background +of the TEI * Several design goals for the TEI tag set * An absolutely +fixed requirement of the TEI Guidelines * Challenges the TEI has +attempted to face * Good texts not beyond economic feasibility * The +issue of reproducibility or processability * The issue of mages as +simulacra for the text redux * One's model of text determines what one's +software can do with a text and has economic consequences * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Prior to speaking about SGML and markup, Michael SPERBERG-McQUEEN, editor, +Text Encoding Initiative (TEI), University of Illinois-Chicago, first drew +a distinction between texts and computers: Texts are abstract cultural +and linguistic objects while computers are complicated physical devices, +he said. Abstract objects cannot be placed inside physical devices; with +computers one can only represent text and act upon those representations. + +The recognition that all representation is encoding, SPERBERG-McQUEEN +argued, leads to the recognition of two things: 1) The topic description +for this session is slightly misleading, because there can be no discussion +of pros and cons of text-coding unless what one means is pros and cons of +working with text with computers. 2) No text can be represented in a +computer without some sort of encoding; images are one way of encoding text, +ASCII is another, SGML yet another. There is no encoding without some +information loss, that is, there is no perfect reproduction of a text that +allows one to do away with the original. Thus, the question becomes, +What is the most useful representation of text for a serious work? +This depends on what kind of serious work one is talking about. + +The projects demonstrated the previous day all involved highly complex +information and fairly complex manipulation of the textual material. +In order to use that complicated information, one has to calculate it +slowly or manually and store the result. It needs to be stored, therefore, +as part of one's representation of the text. Thus, one needs to store the +structure in the text. To deal with complicated representations of text, +one needs somehow to control the complexity of the representation of a text; +that means one needs a way of finding out whether a document and an +electronic representation of a document is legal or not; and that +means one needs a grammar of documents. + +SPERBERG-McQUEEN discussed the variety of forms of formal grammars, +implicit and explicit, as applied to text, and their capabilities. He +argued that these grammars correspond to different models of text that +different developers have. For example, one implicit model of the text +is that there is no internal structure, but just one thing after another, +a few characters and then perhaps a start-title command, and then a few +more characters and an end-title command. SPERBERG-McQUEEN also +distinguished several kinds of text that have a sort of hierarchical +structure that is not very well defined, which, typically, corresponds +to grammars that are not very well defined, as well as hierarchies that +are very well defined (e.g., the Thesaurus Linguae Graecae) and extremely +complicated things such as SGML, which handle strictly hierarchical data +very nicely. + +SPERBERG-McQUEEN conceded that one other model not illustrated on his two +displays was the model of text as a bit-mapped image, an image of a page, +and confessed to having been converted to a limited extent by the +Workshop to the view that electronic images constitute a promising, +probably superior alternative to microfilming. But he was not convinced +that electronic images represent a serious attempt to represent text in +electronic form. Many of their problems stem from the fact that they are +not direct attempts to represent the text but attempts to represent the +page, thus making them representations of representations. + +In this situation of increasingly complicated textual information and the +need to control that complexity in a useful way (which begs the question +of the need for good textual grammars), one has the introduction of SGML. +With SGML, one can develop specific document-type declarations +for specific text types or, as with the TEI, attempts to generate +general document-type declarations that can handle all sorts of text. +The TEI is an attempt to develop formats for text representation that +will ensure the kind of reusability and longevity of data discussed earlier. +It offers a way to stay alive in the state of permanent technological +revolution. + +It has been a continuing challenge in the TEI to create document grammars +that do some work in controlling the complexity of the textual object but +also allowing one to represent the real text that one will find. +Fundamental to the notion of the TEI is that TEI conformance allows one +the ability to extend or modify the TEI tag set so that it fits the text +that one is attempting to represent. + +SPERBERG-McQUEEN next outlined the administrative background of the TEI. +The TEI is an international project to develop and disseminate guidelines +for the encoding and interchange of machine-readable text. It is +sponsored by the Association for Computers in the Humanities, the +Association for Computational Linguistics, and the Association for +Literary and Linguistic Computing. Representatives of numerous other +professional societies sit on its advisory board. The TEI has a number +of affiliated projects that have provided assistance by testing drafts of +the guidelines. + +Among the design goals for the TEI tag set, the scheme first of all must +meet the needs of research, because the TEI came out of the research +community, which did not feel adequately served by existing tag sets. +The tag set must be extensive as well as compatible with existing and +emerging standards. In 1990, version 1.0 of the Guidelines was released +(SPERBERG-McQUEEN illustrated their contents). + +SPERBERG-McQUEEN noted that one problem besetting electronic text has +been the lack of adequate internal or external documentation for many +existing electronic texts. The TEI guidelines as currently formulated +contain few fixed requirements, but one of them is this: There must +always be a document header, an in-file SGML tag that provides +1) a bibliographic description of the electronic object one is talking +about (that is, who included it, when, what for, and under which title); +and 2) the copy text from which it was derived, if any. If there was +no copy text or if the copy text is unknown, then one states as much. +Version 2.0 of the Guidelines was scheduled to be completed in fall 1992 +and a revised third version is to be presented to the TEI advisory board +for its endorsement this coming winter. The TEI itself exists to provide +a markup language, not a marked-up text. + +Among the challenges the TEI has attempted to face is the need for a +markup language that will work for existing projects, that is, handle the +level of markup that people are using now to tag only chapter, section, +and paragraph divisions and not much else. At the same time, such a +language also will be able to scale up gracefully to handle the highly +detailed markup which many people foresee as the future destination of +much electronic text, and which is not the future destination but the +present home of numerous electronic texts in specialized areas. + +SPERBERG-McQUEEN dismissed the lowest-common-denominator approach as +unable to support the kind of applications that draw people who have +never been in the public library regularly before, and make them come +back. He advocated more interesting text and more intelligent text. +Asserting that it is not beyond economic feasibility to have good texts, +SPERBERG-McQUEEN noted that the TEI Guidelines listing 200-odd tags +contains tags that one is expected to enter every time the relevant +textual feature occurs. It contains all the tags that people need now, +and it is not expected that everyone will tag things in the same way. + +The question of how people will tag the text is in large part a function +of their reaction to what SPERBERG-McQUEEN termed the issue of +reproducibility. What one needs to be able to reproduce are the things +one wants to work with. Perhaps a more useful concept than that of +reproducibility or recoverability is that of processability, that is, +what can one get from an electronic text without reading it again +in the original. He illustrated this contention with a page from +Jan Comenius's bilingual Introduction to Latin. + +SPERBERG-McQUEEN returned at length to the issue of images as simulacra +for the text, in order to reiterate his belief that in the long run more +than images of pages of particular editions of the text are needed, +because just as second-generation photocopies and second-generation +microfilm degenerate, so second-generation representations tend to +degenerate, and one tends to overstress some relatively trivial aspects +of the text such as its layout on the page, which is not always +significant, despite what the text critics might say, and slight other +pieces of information such as the very important lexical ties between the +English and Latin versions of Comenius's bilingual text, for example. +Moreover, in many crucial respects it is easy to fool oneself concerning +what a scanned image of the text will accomplish. For example, in order +to study the transmission of texts, information concerning the text +carrier is necessary, which scanned images simply do not always handle. +Further, even the high-quality materials being produced at Cornell use +much of the information that one would need if studying those books as +physical objects. It is a choice that has been made. It is an arguably +justifiable choice, but one does not know what color those pen strokes in +the margin are or whether there was a stain on the page, because it has +been filtered out. One does not know whether there were rips in the page +because they do not show up, and on a couple of the marginal marks one +loses half of the mark because the pen is very light and the scanner +failed to pick it up, and so what is clearly a checkmark in the margin of +the original becomes a little scoop in the margin of the facsimile. +Standard problems for facsimile editions, not new to electronics, but +also true of light-lens photography, and are remarked here because it is +important that we not fool ourselves that even if we produce a very nice +image of this page with good contrast, we are not replacing the +manuscript any more than microfilm has replaced the manuscript. + +The TEI comes from the research community, where its first allegiance +lies, but it is not just an academic exercise. It has relevance far +beyond those who spend all of their time studying text, because one's +model of text determines what one's software can do with a text. Good +models lead to good software. Bad models lead to bad software. That has +economic consequences, and it is these economic consequences that have +led the European Community to help support the TEI, and that will lead, +SPERBERG-McQUEEN hoped, some software vendors to realize that if they +provide software with a better model of the text they can make a killing. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Implications of different DTDs and tag sets * ODA versus SGML * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed, several additional points were made. +Neither AAP (i.e., Association of American Publishers) nor CALS (i.e., +Computer-aided Acquisition and Logistics Support) has a document-type +definition for ancient Greek drama, although the TEI will be able to +handle that. Given this state of affairs and assuming that the +technical-journal producers and the commercial vendors decide to use the +other two types, then an institution like the Library of Congress, which +might receive all of their publications, would have to be able to handle +three different types of document definitions and tag sets and be able to +distinguish among them. + +Office Document Architecture (ODA) has some advantages that flow from its +tight focus on office documents and clear directions for implementation. +Much of the ODA standard is easier to read and clearer at first reading +than the SGML standard, which is extremely general. What that means is +that if one wants to use graphics in TIFF and ODA, one is stuck, because +ODA defines graphics formats while TIFF does not, whereas SGML says the +world is not waiting for this work group to create another graphics format. +What is needed is an ability to use whatever graphics format one wants. + +The TEI provides a socket that allows one to connect the SGML document to +the graphics. The notation that the graphics are in is clearly a choice +that one needs to make based on her or his environment, and that is one +advantage. SGML is less megalomaniacal in attempting to define formats +for all kinds of information, though more megalomaniacal in attempting to +cover all sorts of documents. The other advantage is that the model of +text represented by SGML is simply an order of magnitude richer and more +flexible than the model of text offered by ODA. Both offer hierarchical +structures, but SGML recognizes that the hierarchical model of the text +that one is looking at may not have been in the minds of the designers, +whereas ODA does not. + +ODA is not really aiming for the kind of document that the TEI wants to +encompass. The TEI can handle the kind of material ODA has, as well as a +significantly broader range of material. ODA seems to be very much +focused on office documents, which is what it started out being called-- +office document architecture. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * Text-encoding from a publisher's perspective * +Responsibilities of a publisher * Reproduction of Migne's Latin series +whole and complete with SGML tags based on perceived need and expected +use * Particular decisions arising from the general decision to produce +and publish PLD * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The final speaker in this session, Eric CALALUCA, vice president, +Chadwyck-Healey, Inc., spoke from the perspective of a publisher re +text-encoding, rather than as one qualified to discuss methods of +encoding data, and observed that the presenters sitting in the room, +whether they had chosen to or not, were acting as publishers: making +choices, gathering data, gathering information, and making assessments. +CALALUCA offered the hard-won conviction that in publishing very large +text files (such as PLD), one cannot avoid making personal judgments of +appropriateness and structure. + +In CALALUCA's view, encoding decisions stem from prior judgments. Two +notions have become axioms for him in the consideration of future sources +for electronic publication: 1) electronic text publishing is as personal +as any other kind of publishing, and questions of if and how to encode +the data are simply a consequence of that prior decision; 2) all +personal decisions are open to criticism, which is unavoidable. + +CALALUCA rehearsed his role as a publisher or, better, as an intermediary +between what is viewed as a sound idea and the people who would make use +of it. Finding the specialist to advise in this process is the core of +that function. The publisher must monitor and hug the fine line between +giving users what they want and suggesting what they might need. One +responsibility of a publisher is to represent the desires of scholars and +research librarians as opposed to bullheadedly forcing them into areas +they would not choose to enter. + +CALALUCA likened the questions being raised today about data structure +and standards to the decisions faced by the Abbe Migne himself during +production of the Patrologia series in the mid-nineteenth century. +Chadwyck-Healey's decision to reproduce Migne's Latin series whole and +complete with SGML tags was also based upon a perceived need and an +expected use. In the same way that Migne's work came to be far more than +a simple handbook for clerics, PLD is already far more than a database +for theologians. It is a bedrock source for the study of Western +civilization, CALALUCA asserted. + +In regard to the decision to produce and publish PLD, the editorial board +offered direct judgments on the question of appropriateness of these +texts for conversion, their encoding and their distribution, and +concluded that the best possible project was one that avoided overt +intrusions or exclusions in so important a resource. Thus, the general +decision to transmit the original collection as clearly as possible with +the widest possible avenues for use led to other decisions: 1) To encode +the data or not, SGML or not, TEI or not. Again, the expected user +community asserted the need for normative tagging structures of important +humanities texts, and the TEI seemed the most appropriate structure for +that purpose. Research librarians, who are trained to view the larger +impact of electronic text sources on 80 or 90 or 100 doctoral +disciplines, loudly approved the decision to include tagging. They see +what is coming better than the specialist who is completely focused on +one edition of Ambrose's De Anima, and they also understand that the +potential uses exceed present expectations. 2) What will be tagged and +what will not. Once again, the board realized that one must tag the +obvious. But in no way should one attempt to identify through encoding +schemes every single discrete area of a text that might someday be +searched. That was another decision. Searching by a column number, an +author, a word, a volume, permitting combination searches, and tagging +notations seemed logical choices as core elements. 3) How does one make +the data available? Tying it to a CD-ROM edition creates limitations, +but a magnetic tape file that is very large, is accompanied by the +encoding specifications, and that allows one to make local modifications +also allows one to incorporate any changes one may desire within the +bounds of private research, though exporting tag files from a CD-ROM +could serve just as well. Since no one on the board could possibly +anticipate each and every way in which a scholar might choose to mine +this data bank, it was decided to satisfy the basics and make some +provisions for what might come. 4) Not to encode the database would rob +it of the interchangeability and portability these important texts should +accommodate. For CALALUCA, the extensive options presented by full-text +searching require care in text selection and strongly support encoding of +data to facilitate the widest possible search strategies. Better +software can always be created, but summoning the resources, the people, +and the energy to reconvert the text is another matter. + +PLD is being encoded, captured, and distributed, because to +Chadwyck-Healey and the board it offers the widest possible array of +future research applications that can be seen today. CALALUCA concluded +by urging the encoding of all important text sources in whatever way +seems most appropriate and durable at the time, without blanching at the +thought that one's work may require emendation in the future. (Thus, +Chadwyck-Healey produced a very large humanities text database before the +final release of the TEI Guidelines.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating texts with markup advocated * Trends in encoding * +The TEI and the issue of interchangeability of standards * A +misconception concerning the TEI * Implications for an institution like +LC in the event that a multiplicity of DTDs develops * Producing images +as a first step towards possible conversion to full text through +character recognition * The AAP tag sets as a common starting point and +the need for caution * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOCKEY prefaced the discussion that followed with several comments in +favor of creating texts with markup and on trends in encoding. In the +future, when many more texts are available for on-line searching, real +problems in finding what is wanted will develop, if one is faced with +millions of words of data. It therefore becomes important to consider +putting markup in texts to help searchers home in on the actual things +they wish to retrieve. Various approaches to refining retrieval methods +toward this end include building on a computer version of a dictionary +and letting the computer look up words in it to obtain more information +about the semantic structure or semantic field of a word, its grammatical +structure, and syntactic structure. + +HOCKEY commented on the present keen interest in the encoding world +in creating: 1) machine-readable versions of dictionaries that can be +initially tagged in SGML, which gives a structure to the dictionary entry; +these entries can then be converted into a more rigid or otherwise +different database structure inside the computer, which can be treated as +a dynamic tool for searching mechanisms; 2) large bodies of text to study +the language. In order to incorporate more sophisticated mechanisms, +more about how words behave needs to be known, which can be learned in +part from information in dictionaries. However, the last ten years have +seen much interest in studying the structure of printed dictionaries +converted into computer-readable form. The information one derives about +many words from those is only partial, one or two definitions of the +common or the usual meaning of a word, and then numerous definitions of +unusual usages. If the computer is using a dictionary to help retrieve +words in a text, it needs much more information about the common usages, +because those are the ones that occur over and over again. Hence the +current interest in developing large bodies of text in computer-readable +form in order to study the language. Several projects are engaged in +compiling, for example, 100 million words. HOCKEY described one with +which she was associated briefly at Oxford University involving +compilation of 100 million words of British English: about 10 percent of +that will contain detailed linguistic tagging encoded in SGML; it will +have word class taggings, with words identified as nouns, verbs, +adjectives, or other parts of speech. This tagging can then be used by +programs which will begin to learn a bit more about the structure of the +language, and then, can go to tag more text. + +HOCKEY said that the more that is tagged accurately, the more one can +refine the tagging process and thus the bigger body of text one can build +up with linguistic tagging incorporated into it. Hence, the more tagging +or annotation there is in the text, the more one may begin to learn about +language and the more it will help accomplish more intelligent OCR. She +recommended the development of software tools that will help one begin to +understand more about a text, which can then be applied to scanning +images of that text in that format and to using more intelligence to help +one interpret or understand the text. + +HOCKEY posited the need to think about common methods of text-encoding +for a long time to come, because building these large bodies of text is +extremely expensive and will only be done once. + +In the more general discussion on approaches to encoding that followed, +these points were made: + +BESSER identified the underlying problem with standards that all have to +struggle with in adopting a standard, namely, the tension between a very +highly defined standard that is very interchangeable but does not work +for everyone because something is lacking, and a standard that is less +defined, more open, more adaptable, but less interchangeable. Contending +that the way in which people use SGML is not sufficiently defined, BESSER +wondered 1) if people resist the TEI because they think it is too defined +in certain things they do not fit into, and 2) how progress with +interchangeability can be made without frightening people away. + +SPERBERG-McQUEEN replied that the published drafts of the TEI had met +with surprisingly little objection on the grounds that they do not allow +one to handle X or Y or Z. Particular concerns of the affiliated +projects have led, in practice, to discussions of how extensions are to +be made; the primary concern of any project has to be how it can be +represented locally, thus making interchange secondary. The TEI has +received much criticism based on the notion that everything in it is +required or even recommended, which, as it happens, is a misconception +from the beginning, because none of it is required and very little is +actually actively recommended for all cases, except that one document +one's source. + +SPERBERG-McQUEEN agreed with BESSER about this trade-off: all the +projects in a set of twenty TEI-conformant projects will not necessarily +tag the material in the same way. One result of the TEI will be that the +easiest problems will be solved--those dealing with the external form of +the information; but the problem that is hardest in interchange is that +one is not encoding what another wants, and vice versa. Thus, after +the adoption of a common notation, the differences in the underlying +conceptions of what is interesting about texts become more visible. +The success of a standard like the TEI will lie in the ability of +the recipient of interchanged texts to use some of what it contains +and to add the information that was not encoded that one wants, in a +layered way, so that texts can be gradually enriched and one does not +have to put in everything all at once. Hence, having a well-behaved +markup scheme is important. + +STEVENS followed up on the paradoxical analogy that BESSER alluded to in +the example of the MARC records, namely, the formats that are the same +except that they are different. STEVENS drew a parallel between +document-type definitions and MARC records for books and serials and maps, +where one has a tagging structure and there is a text-interchange. +STEVENS opined that the producers of the information will set the terms +for the standard (i.e., develop document-type definitions for the users +of their products), creating a situation that will be problematical for +an institution like the Library of Congress, which will have to deal with +the DTDs in the event that a multiplicity of them develops. Thus, +numerous people are seeking a standard but cannot find the tag set that +will be acceptable to them and their clients. SPERBERG-McQUEEN agreed +with this view, and said that the situation was in a way worse: attempting +to unify arbitrary DTDs resembled attempting to unify a MARC record with a +bibliographic record done according to the Prussian instructions. +According to STEVENS, this situation occurred very early in the process. + +WATERS recalled from early discussions on Project Open Book the concern +of many people that merely by producing images, POB was not really +enhancing intellectual access to the material. Nevertheless, not wishing +to overemphasize the opposition between imaging and full text, WATERS +stated that POB views getting the images as a first step toward possibly +converting to full text through character recognition, if the technology +is appropriate. WATERS also emphasized that encoding is involved even +with a set of images. + +SPERBERG-McQUEEN agreed with WATERS that one can create an SGML document +consisting wholly of images. At first sight, organizing graphic images +with an SGML document may not seem to offer great advantages, but the +advantages of the scheme WATERS described would be precisely that +ability to move into something that is more of a multimedia document: +a combination of transcribed text and page images. WEIBEL concurred in +this judgment, offering evidence from Project ADAPT, where a page is +divided into text elements and graphic elements, and in fact the text +elements are organized by columns and lines. These lines may be used as +the basis for distributing documents in a network environment. As one +develops software intelligent enough to recognize what those elements +are, it makes sense to apply SGML to an image initially, that may, in +fact, ultimately become more and more text, either through OCR or edited +OCR or even just through keying. For WATERS, the labor of composing the +document and saying this set of documents or this set of images belongs +to this document constitutes a significant investment. + +WEIBEL also made the point that the AAP tag sets, while not excessively +prescriptive, offer a common starting point; they do not define the +structure of the documents, though. They have some recommendations about +DTDs one could use as examples, but they do just suggest tag sets. For +example, the CORE project attempts to use the AAP markup as much as +possible, but there are clearly areas where structure must be added. +That in no way contradicts the use of AAP tag sets. + +SPERBERG-McQUEEN noted that the TEI prepared a long working paper early +on about the AAP tag set and what it lacked that the TEI thought it +needed, and a fairly long critique of the naming conventions, which has +led to a very different style of naming in the TEI. He stressed the +importance of the opposition between prescriptive markup, the kind that a +publisher or anybody can do when producing documents de novo, and +descriptive markup, in which one has to take what the text carrier +provides. In these particular tag sets it is easy to overemphasize this +opposition, because the AAP tag set is extremely flexible. Even if one +just used the DTDs, they allow almost anything to appear almost anywhere. + + ****** + +SESSION VI. COPYRIGHT ISSUES + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PETERS * Several cautions concerning copyright in an electronic +environment * Review of copyright law in the United States * The notion +of the public good and the desirability of incentives to promote it * +What copyright protects * Works not protected by copyright * The rights +of copyright holders * Publishers' concerns in today's electronic +environment * Compulsory licenses * The price of copyright in a digital +medium and the need for cooperation * Additional clarifications * Rough +justice oftentimes the outcome in numerous copyright matters * Copyright +in an electronic society * Copyright law always only sets up the +boundaries; anything can be changed by contract * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Marybeth PETERS, policy planning adviser to the Register of Copyrights, +Library of Congress, made several general comments and then opened the +floor to discussion of subjects of interest to the audience. + +Having attended several sessions in an effort to gain a sense of what +people did and where copyright would affect their lives, PETERS expressed +the following cautions: + + * If one takes and converts materials and puts them in new forms, + then, from a copyright point of view, one is creating something and + will receive some rights. + + * However, if what one is converting already exists, a question + immediately arises about the status of the materials in question. + + * Putting something in the public domain in the United States offers + some freedom from anxiety, but distributing it throughout the world + on a network is another matter, even if one has put it in the public + domain in the United States. Re foreign laws, very frequently a + work can be in the public domain in the United States but protected + in other countries. Thus, one must consider all of the places a + work may reach, lest one unwittingly become liable to being faced + with a suit for copyright infringement, or at least a letter + demanding discussion of what one is doing. + +PETERS reviewed copyright law in the United States. The U.S. +Constitution effectively states that Congress has the power to enact +copyright laws for two purposes: 1) to encourage the creation and +dissemination of intellectual works for the good of society as a whole; +and, significantly, 2) to give creators and those who package and +disseminate materials the economic rewards that are due them. + +Congress strives to strike a balance, which at times can become an +emotional issue. The United States has never accepted the notion of the +natural right of an author so much as it has accepted the notion of the +public good and the desirability of incentives to promote it. This state +of affairs, however, has created strains on the international level and +is the reason for several of the differences in the laws that we have. +Today the United States protects almost every kind of work that can be +called an expression of an author. The standard for gaining copyright +protection is simply originality. This is a low standard and means that +a work is not copied from something else, as well as shows a certain +minimal amount of authorship. One can also acquire copyright protection +for making a new version of preexisting material, provided it manifests +some spark of creativity. + +However, copyright does not protect ideas, methods, systems--only the way +that one expresses those things. Nor does copyright protect anything +that is mechanical, anything that does not involve choice, or criteria +concerning whether or not one should do a thing. For example, the +results of a process called declicking, in which one mechanically removes +impure sounds from old recordings, are not copyrightable. On the other +hand, the choice to record a song digitally and to increase the sound of +violins or to bring up the tympani constitutes the results of conversion +that are copyrightable. Moreover, if a work is protected by copyright in +the United States, one generally needs the permission of the copyright +owner to convert it. Normally, who will own the new--that is, converted- +-material is a matter of contract. In the absence of a contract, the +person who creates the new material is the author and owner. But people +do not generally think about the copyright implications until after the +fact. PETERS stressed the need when dealing with copyrighted works to +think about copyright in advance. One's bargaining power is much greater +up front than it is down the road. + +PETERS next discussed works not protected by copyright, for example, any +work done by a federal employee as part of his or her official duties is +in the public domain in the United States. The issue is not wholly free +of doubt concerning whether or not the work is in the public domain +outside the United States. Other materials in the public domain include: +any works published more than seventy-five years ago, and any work +published in the United States more than twenty-eight years ago, whose +copyright was not renewed. In talking about the new technology and +putting material in a digital form to send all over the world, PETERS +cautioned, one must keep in mind that while the rights may not be an +issue in the United States, they may be in different parts of the world, +where most countries previously employed a copyright term of the life of +the author plus fifty years. + +PETERS next reviewed the economics of copyright holding. Simply, +economic rights are the rights to control the reproduction of a work in +any form. They belong to the author, or in the case of a work made for +hire, the employer. The second right, which is critical to conversion, +is the right to change a work. The right to make new versions is perhaps +one of the most significant rights of authors, particularly in an +electronic world. The third right is the right to publish the work and +the right to disseminate it, something that everyone who deals in an +electronic medium needs to know. The basic rule is if a copy is sold, +all rights of distribution are extinguished with the sale of that copy. +The key is that it must be sold. A number of companies overcome this +obstacle by leasing or renting their product. These companies argue that +if the material is rented or leased and not sold, they control the uses +of a work. The fourth right, and one very important in a digital world, +is a right of public performance, which means the right to show the work +sequentially. For example, copyright owners control the showing of a +CD-ROM product in a public place such as a public library. The reverse +side of public performance is something called the right of public +display. Moral rights also exist, which at the federal level apply only +to very limited visual works of art, but in theory may apply under +contract and other principles. Moral rights may include the right of an +author to have his or her name on a work, the right of attribution, and +the right to object to distortion or mutilation--the right of integrity. + +The way copyright law is worded gives much latitude to activities such as +preservation; to use of material for scholarly and research purposes when +the user does not make multiple copies; and to the generation of +facsimile copies of unpublished works by libraries for themselves and +other libraries. But the law does not allow anyone to become the +distributor of the product for the entire world. In today's electronic +environment, publishers are extremely concerned that the entire world is +networked and can obtain the information desired from a single copy in a +single library. Hence, if there is to be only one sale, which publishers +may choose to live with, they will obtain their money in other ways, for +example, from access and use. Hence, the development of site licenses +and other kinds of agreements to cover what publishers believe they +should be compensated for. Any solution that the United States takes +today has to consider the international arena. + +Noting that the United States is a member of the Berne Convention and +subscribes to its provisions, PETERS described the permissions process. +She also defined compulsory licenses. A compulsory license, of which the +United States has had a few, builds into the law the right to use a work +subject to certain terms and conditions. In the international arena, +however, the ability to use compulsory licenses is extremely limited. +Thus, clearinghouses and other collectives comprise one option that has +succeeded in providing for use of a work. Often overlooked when one +begins to use copyrighted material and put products together is how +expensive the permissions process and managing it is. According to +PETERS, the price of copyright in a digital medium, whatever solution is +worked out, will include managing and assembling the database. She +strongly recommended that publishers and librarians or people with +various backgrounds cooperate to work out administratively feasible +systems, in order to produce better results. + +In the lengthy question-and-answer period that followed PETERS's +presentation, the following points emerged: + + * The Copyright Office maintains that anything mechanical and + totally exhaustive probably is not protected. In the event that + what an individual did in developing potentially copyrightable + material is not understood, the Copyright Office will ask about the + creative choices the applicant chose to make or not to make. As a + practical matter, if one believes she or he has made enough of those + choices, that person has a right to assert a copyright and someone + else must assert that the work is not copyrightable. The more + mechanical, the more automatic, a thing is, the less likely it is to + be copyrightable. + + * Nearly all photographs are deemed to be copyrightable, but no one + worries about them much, because everyone is free to take the same + image. Thus, a photographic copyright represents what is called a + "thin" copyright. The photograph itself must be duplicated, in + order for copyright to be violated. + + * The Copyright Office takes the position that X-rays are not + copyrightable because they are mechanical. It can be argued + whether or not image enhancement in scanning can be protected. One + must exercise care with material created with public funds and + generally in the public domain. An article written by a federal + employee, if written as part of official duties, is not + copyrightable. However, control over a scientific article written + by a National Institutes of Health grantee (i.e., someone who + receives money from the U.S. government), depends on NIH policy. If + the government agency has no policy (and that policy can be + contained in its regulations, the contract, or the grant), the + author retains copyright. If a provision of the contract, grant, or + regulation states that there will be no copyright, then it does not + exist. When a work is created, copyright automatically comes into + existence unless something exists that says it does not. + + * An enhanced electronic copy of a print copy of an older reference + work in the public domain that does not contain copyrightable new + material is a purely mechanical rendition of the original work, and + is not copyrightable. + + * Usually, when a work enters the public domain, nothing can remove + it. For example, Congress recently passed into law the concept of + automatic renewal, which means that copyright on any work published + between l964 and l978 does not have to be renewed in order to + receive a seventy-five-year term. But any work not renewed before + 1964 is in the public domain. + + * Concerning whether or not the United States keeps track of when + authors die, nothing was ever done, nor is anything being done at + the moment by the Copyright Office. + + * Software that drives a mechanical process is itself copyrightable. + If one changes platforms, the software itself has a copyright. The + World Intellectual Property Organization will hold a symposium 28 + March through 2 April l993, at Harvard University, on digital + technology, and will study this entire issue. If one purchases a + computer software package, such as MacPaint, and creates something + new, one receives protection only for that which has been added. + +PETERS added that often in copyright matters, rough justice is the +outcome, for example, in collective licensing, ASCAP (i.e., American +Society of Composers, Authors, and Publishers), and BMI (i.e., Broadcast +Music, Inc.), where it may seem that the big guys receive more than their +due. Of course, people ought not to copy a creative product without +paying for it; there should be some compensation. But the truth of the +world, and it is not a great truth, is that the big guy gets played on +the radio more frequently than the little guy, who has to do much more +until he becomes a big guy. That is true of every author, every +composer, everyone, and, unfortunately, is part of life. + +Copyright always originates with the author, except in cases of works +made for hire. (Most software falls into this category.) When an author +sends his article to a journal, he has not relinquished copyright, though +he retains the right to relinquish it. The author receives absolutely +everything. The less prominent the author, the more leverage the +publisher will have in contract negotiations. In order to transfer the +rights, the author must sign an agreement giving them away. + +In an electronic society, it is important to be able to license a writer +and work out deals. With regard to use of a work, it usually is much +easier when a publisher holds the rights. In an electronic era, a real +problem arises when one is digitizing and making information available. +PETERS referred again to electronic licensing clearinghouses. Copyright +ought to remain with the author, but as one moves forward globally in the +electronic arena, a middleman who can handle the various rights becomes +increasingly necessary. + +The notion of copyright law is that it resides with the individual, but +in an on-line environment, where a work can be adapted and tinkered with +by many individuals, there is concern. If changes are authorized and +there is no agreement to the contrary, the person who changes a work owns +the changes. To put it another way, the person who acquires permission +to change a work technically will become the author and the owner, unless +some agreement to the contrary has been made. It is typical for the +original publisher to try to control all of the versions and all of the +uses. Copyright law always only sets up the boundaries. Anything can be +changed by contract. + + ****** + +SESSION VII. CONCLUSION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GENERAL DISCUSSION * Two questions for discussion * Different emphases in +the Workshop * Bringing the text and image partisans together * +Desiderata in planning the long-term development of something * Questions +surrounding the issue of electronic deposit * Discussion of electronic +deposit as an allusion to the issue of standards * Need for a directory +of preservation projects in digital form and for access to their +digitized files * CETH's catalogue of machine-readable texts in the +humanities * What constitutes a publication in the electronic world? * +Need for LC to deal with the concept of on-line publishing * LC's Network +Development Office exploring the limits of MARC as a standard in terms +of handling electronic information * Magnitude of the problem and the +need for distributed responsibility in order to maintain and store +electronic information * Workshop participants to be viewed as a starting +point * Development of a network version of AM urged * A step toward AM's +construction of some sort of apparatus for network access * A delicate +and agonizing policy question for LC * Re the issue of electronic +deposit, LC urged to initiate a catalytic process in terms of distributed +responsibility * Suggestions for cooperative ventures * Commercial +publishers' fears * Strategic questions for getting the image and text +people to think through long-term cooperation * Clarification of the +driving force behind both the Perseus and the Cornell Xerox projects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In his role as moderator of the concluding session, GIFFORD raised two +questions he believed would benefit from discussion: 1) Are there enough +commonalities among those of us that have been here for two days so that +we can see courses of action that should be taken in the future? And, if +so, what are they and who might take them? 2) Partly derivative from +that, but obviously very dangerous to LC as host, do you see a role for +the Library of Congress in all this? Of course, the Library of Congress +holds a rather special status in a number of these matters, because it is +not perceived as a player with an economic stake in them, but are there +roles that LC can play that can help advance us toward where we are heading? + +Describing himself as an uninformed observer of the technicalities of the +last two days, GIFFORD detected three different emphases in the Workshop: +1) people who are very deeply committed to text; 2) people who are almost +passionate about images; and 3) a few people who are very committed to +what happens to the networks. In other words, the new networking +dimension, the accessibility of the processability, the portability of +all this across the networks. How do we pull those three together? + +Adding a question that reflected HOCKEY's comment that this was the +fourth workshop she had attended in the previous thirty days, FLEISCHHAUER +wondered to what extent this meeting had reinvented the wheel, or if it +had contributed anything in the way of bringing together a different group +of people from those who normally appear on the workshop circuit. + +HOCKEY confessed to being struck at this meeting and the one the +Electronic Pierce Consortium organized the previous week that this was a +coming together of people working on texts and not images. Attempting to +bring the two together is something we ought to be thinking about for the +future: How one can think about working with image material to begin +with, but structuring it and digitizing it in such a way that at a later +stage it can be interpreted into text, and find a common way of building +text and images together so that they can be used jointly in the future, +with the network support to begin there because that is how people will +want to access it. + +In planning the long-term development of something, which is what is +being done in electronic text, HOCKEY stressed the importance not only +of discussing the technical aspects of how one does it but particularly +of thinking about what the people who use the stuff will want to do. +But conversely, there are numerous things that people start to do with +electronic text or material that nobody ever thought of in the beginning. + +LESK, in response to the question concerning the role of the Library of +Congress, remarked the often suggested desideratum of having electronic +deposit: Since everything is now computer-typeset, an entire decade of +material that was machine-readable exists, but the publishers frequently +did not save it; has LC taken any action to have its copyright deposit +operation start collecting these machine-readable versions? In the +absence of PETERS, GIFFORD replied that the question was being +actively considered but that that was only one dimension of the problem. +Another dimension is the whole question of the integrity of the original +electronic document. It becomes highly important in science to prove +authorship. How will that be done? + +ERWAY explained that, under the old policy, to make a claim for a +copyright for works that were published in electronic form, including +software, one had to submit a paper copy of the first and last twenty +pages of code--something that represented the work but did not include +the entire work itself and had little value to anyone. As a temporary +measure, LC has claimed the right to demand electronic versions of +electronic publications. This measure entails a proactive role for the +Library to say that it wants a particular electronic version. Publishers +then have perhaps a year to submit it. But the real problem for LC is +what to do with all this material in all these different formats. Will +the Library mount it? How will it give people access to it? How does LC +keep track of the appropriate computers, software, and media? The situation +is so hard to control, ERWAY said, that it makes sense for each publishing +house to maintain its own archive. But LC cannot enforce that either. + +GIFFORD acknowledged LESK's suggestion that establishing a priority +offered the solution, albeit a fairly complicated one. But who maintains +that register?, he asked. GRABER noted that LC does attempt to collect a +Macintosh version and the IBM-compatible version of software. It does +not collect other versions. But while true for software, BYRUM observed, +this reply does not speak to materials, that is, all the materials that +were published that were on somebody's microcomputer or driver tapes +at a publishing office across the country. LC does well to acquire +specific machine-readable products selectively that were intended to be +machine-readable. Materials that were in machine-readable form at one time, +BYRUM said, would be beyond LC's capability at the moment, insofar as +attempting to acquire, organize, and preserve them are concerned--and +preservation would be the most important consideration. In this +connection, GIFFORD reiterated the need to work out some sense of +distributive responsibility for a number of these issues, which +inevitably will require significant cooperation and discussion. +Nobody can do it all. + +LESK suggested that some publishers may look with favor on LC beginning +to serve as a depository of tapes in an electronic manuscript standard. +Publishers may view this as a service that they did not have to perform +and they might send in tapes. However, SPERBERG-McQUEEN countered, +although publishers have had equivalent services available to them for a +long time, the electronic text archive has never turned away or been +flooded with tapes and is forever sending feedback to the depositor. +Some publishers do send in tapes. + +ANDRE viewed this discussion as an allusion to the issue of standards. +She recommended that the AAP standard and the TEI, which has already been +somewhat harmonized internationally and which also shares several +compatibilities with the AAP, be harmonized to ensure sufficient +compatibility in the software. She drew the line at saying LC ought to +be the locus or forum for such harmonization. + +Taking the group in a slightly different direction, but one where at +least in the near term LC might play a helpful role, LYNCH remarked the +plans of a number of projects to carry out preservation by creating +digital images that will end up in on-line or near-line storage at some +institution. Presumably, LC will link this material somehow to its +on-line catalog in most cases. Thus, it is in a digital form. LYNCH had +the impression that many of these institutions would be willing to make +those files accessible to other people outside the institution, provided +that there is no copyright problem. This desideratum will require +propagating the knowledge that those digitized files exist, so that they +can end up in other on-line catalogs. Although uncertain about the +mechanism for achieving this result, LYNCH said that it warranted +scrutiny because it seemed to be connected to some of the basic issues of +cataloging and distribution of records. It would be foolish, given the +amount of work that all of us have to do and our meager resources, to +discover multiple institutions digitizing the same work. Re microforms, +LYNCH said, we are in pretty good shape. + +BATTIN called this a big problem and noted that the Cornell people (who +had already departed) were working on it. At issue from the beginning +was to learn how to catalog that information into RLIN and then into +OCLC, so that it would be accessible. That issue remains to be resolved. +LYNCH rejoined that putting it into OCLC or RLIN was helpful insofar as +somebody who is thinking of performing preservation activity on that work +could learn about it. It is not necessarily helpful for institutions to +make that available. BATTIN opined that the idea was that it not only be +for preservation purposes but for the convenience of people looking for +this material. She endorsed LYNCH's dictum that duplication of this +effort was to be avoided by every means. + +HOCKEY informed the Workshop about one major current activity of CETH, +namely a catalogue of machine-readable texts in the humanities. Held on +RLIN at present, the catalogue has been concentrated on ASCII as opposed +to digitized images of text. She is exploring ways to improve the +catalogue and make it more widely available, and welcomed suggestions +about these concerns. CETH owns the records, which are not just +restricted to RLIN, and can distribute them however it wishes. + +Taking up LESK's earlier question, BATTIN inquired whether LC, since it +is accepting electronic files and designing a mechanism for dealing with +that rather than putting books on shelves, would become responsible for +the National Copyright Depository of Electronic Materials. Of course +that could not be accomplished overnight, but it would be something LC +could plan for. GIFFORD acknowledged that much thought was being devoted +to that set of problems and returned the discussion to the issue raised +by LYNCH--whether or not putting the kind of records that both BATTIN and +HOCKEY have been talking about in RLIN is not a satisfactory solution. +It seemed to him that RLIN answered LYNCH's original point concerning +some kind of directory for these kinds of materials. In a situation +where somebody is attempting to decide whether or not to scan this or +film that or to learn whether or not someone has already done so, LYNCH +suggested, RLIN is helpful, but it is not helpful in the case of a local, +on-line catalogue. Further, one would like to have her or his system be +aware that that exists in digital form, so that one can present it to a +patron, even though one did not digitize it, if it is out of copyright. +The only way to make those linkages would be to perform a tremendous +amount of real-time look-up, which would be awkward at best, or +periodically to yank the whole file from RLIN and match it against one's +own stuff, which is a nuisance. + +But where, ERWAY inquired, does one stop including things that are +available with Internet, for instance, in one's local catalogue? +It almost seems that that is LC's means to acquire access to them. +That represents LC's new form of library loan. Perhaps LC's new on-line +catalogue is an amalgamation of all these catalogues on line. LYNCH +conceded that perhaps that was true in the very long term, but was not +applicable to scanning in the short term. In his view, the totals cited +by Yale, 10,000 books over perhaps a four-year period, and 1,000-1,500 +books from Cornell, were not big numbers, while searching all over +creation for relatively rare occurrences will prove to be less efficient. +As GIFFORD wondered if this would not be a separable file on RLIN and +could be requested from them, BATTIN interjected that it was easily +accessible to an institution. SEVERTSON pointed out that that file, cum +enhancements, was available with reference information on CD-ROM, which +makes it a little more available. + +In HOCKEY's view, the real question facing the Workshop is what to put in +this catalogue, because that raises the question of what constitutes a +publication in the electronic world. (WEIBEL interjected that Eric Joule +in OCLC's Office of Research is also wrestling with this particular +problem, while GIFFORD thought it sounded fairly generic.) HOCKEY +contended that a majority of texts in the humanities are in the hands +of either a small number of large research institutions or individuals +and are not generally available for anyone else to access at all. +She wondered if these texts ought to be catalogued. + +After argument proceeded back and forth for several minutes over why +cataloguing might be a necessary service, LEBRON suggested that this +issue involved the responsibility of a publisher. The fact that someone +has created something electronically and keeps it under his or her +control does not constitute publication. Publication implies +dissemination. While it would be important for a scholar to let other +people know that this creation exists, in many respects this is no +different from an unpublished manuscript. That is what is being accessed +in there, except that now one is not looking at it in the hard-copy but +in the electronic environment. + +LEBRON expressed puzzlement at the variety of ways electronic publishing +has been viewed. Much of what has been discussed throughout these two +days has concerned CD-ROM publishing, whereas in the on-line environment +that she confronts, the constraints and challenges are very different. +Sooner or later LC will have to deal with the concept of on-line +publishing. Taking up the comment ERWAY made earlier about storing +copies, LEBRON gave her own journal as an example. How would she deposit +OJCCT for copyright?, she asked, because the journal will exist in the +mainframe at OCLC and people will be able to access it. Here the +situation is different, ownership versus access, and is something that +arises with publication in the on-line environment, faster than is +sometimes realized. Lacking clear answers to all of these questions +herself, LEBRON did not anticipate that LC would be able to take a role +in helping to define some of them for quite a while. + +GREENFIELD observed that LC's Network Development Office is attempting, +among other things, to explore the limits of MARC as a standard in terms +of handling electronic information. GREENFIELD also noted that Rebecca +GUENTHER from that office gave a paper to the American Society for +Information Science (ASIS) summarizing several of the discussion papers +that were coming out of the Network Development Office. GREENFIELD said +he understood that that office had a list-server soliciting just the kind +of feedback received today concerning the difficulties of identifying and +cataloguing electronic information. GREENFIELD hoped that everybody +would be aware of that and somehow contribute to that conversation. + +Noting two of LC's roles, first, to act as a repository of record for +material that is copyrighted in this country, and second, to make +materials it holds available in some limited form to a clientele that +goes beyond Congress, BESSER suggested that it was incumbent on LC to +extend those responsibilities to all the things being published in +electronic form. This would mean eventually accepting electronic +formats. LC could require that at some point they be in a certain +limited set of formats, and then develop mechanisms for allowing people +to access those in the same way that other things are accessed. This +does not imply that they are on the network and available to everyone. +LC does that with most of its bibliographic records, BESSER said, which +end up migrating to the utility (e.g., OCLC) or somewhere else. But just +as most of LC's books are available in some form through interlibrary +loan or some other mechanism, so in the same way electronic formats ought +to be available to others in some format, though with some copyright +considerations. BESSER was not suggesting that these mechanisms be +established tomorrow, only that they seemed to fall within LC's purview, +and that there should be long-range plans to establish them. + +Acknowledging that those from LC in the room agreed with BESSER +concerning the need to confront difficult questions, GIFFORD underscored +the magnitude of the problem of what to keep and what to select. GIFFORD +noted that LC currently receives some 31,000 items per day, not counting +electronic materials, and argued for much more distributed responsibility +in order to maintain and store electronic information. + +BESSER responded that the assembled group could be viewed as a starting +point, whose initial operating premise could be helping to move in this +direction and defining how LC could do so, for example, in areas of +standardization or distribution of responsibility. + +FLEISCHHAUER added that AM was fully engaged, wrestling with some of the +questions that pertain to the conversion of older historical materials, +which would be one thing that the Library of Congress might do. Several +points mentioned by BESSER and several others on this question have a +much greater impact on those who are concerned with cataloguing and the +networking of bibliographic information, as well as preservation itself. + +Speaking directly to AM, which he considered was a largely uncopyrighted +database, LYNCH urged development of a network version of AM, or +consideration of making the data in it available to people interested in +doing network multimedia. On account of the current great shortage of +digital data that is both appealing and unencumbered by complex rights +problems, this course of action could have a significant effect on making +network multimedia a reality. + +In this connection, FLEISCHHAUER reported on a fragmentary prototype in +LC's Office of Information Technology Services that attempts to associate +digital images of photographs with cataloguing information in ways that +work within a local area network--a step, so to say, toward AM's +construction of some sort of apparatus for access. Further, AM has +attempted to use standard data forms in order to help make that +distinction between the access tools and the underlying data, and thus +believes that the database is networkable. + +A delicate and agonizing policy question for LC, however, which comes +back to resources and unfortunately has an impact on this, is to find +some appropriate, honorable, and legal cost-recovery possibilities. A +certain skittishness concerning cost-recovery has made people unsure +exactly what to do. AM would be highly receptive to discussing further +LYNCH's offer to test or demonstrate its database in a network +environment, FLEISCHHAUER said. + +Returning the discussion to what she viewed as the vital issue of +electronic deposit, BATTIN recommended that LC initiate a catalytic +process in terms of distributed responsibility, that is, bring together +the distributed organizations and set up a study group to look at all +these issues and see where we as a nation should move. The broader +issues of how we deal with the management of electronic information will +not disappear, but only grow worse. + +LESK took up this theme and suggested that LC attempt to persuade one +major library in each state to deal with its state equivalent publisher, +which might produce a cooperative project that would be equitably +distributed around the country, and one in which LC would be dealing with +a minimal number of publishers and minimal copyright problems. + +GRABER remarked the recent development in the scientific community of a +willingness to use SGML and either deposit or interchange on a fairly +standardized format. He wondered if a similar movement was taking place +in the humanities. Although the National Library of Medicine found only +a few publishers to cooperate in a like venture two or three years ago, a +new effort might generate a much larger number willing to cooperate. + +KIMBALL recounted his unit's (Machine-Readable Collections Reading Room) +troubles with the commercial publishers of electronic media in acquiring +materials for LC's collections, in particular the publishers' fear that +they would not be able to cover their costs and would lose control of +their products, that LC would give them away or sell them and make +profits from them. He doubted that the publishing industry was prepared +to move into this area at the moment, given its resistance to allowing LC +to use its machine-readable materials as the Library would like. + +The copyright law now addresses compact disk as a medium, and LC can +request one copy of that, or two copies if it is the only version, and +can request copies of software, but that fails to address magazines or +books or anything like that which is in machine-readable form. + +GIFFORD acknowledged the thorny nature of this issue, which he illustrated +with the example of the cumbersome process involved in putting a copy of a +scientific database on a LAN in LC's science reading room. He also +acknowledged that LC needs help and could enlist the energies and talents +of Workshop participants in thinking through a number of these problems. + +GIFFORD returned the discussion to getting the image and text people to +think through together where they want to go in the long term. MYLONAS +conceded that her experience at the Pierce Symposium the previous week at +Georgetown University and this week at LC had forced her to reevaluate +her perspective on the usefulness of text as images. MYLONAS framed the +issues in a series of questions: How do we acquire machine-readable +text? Do we take pictures of it and perform OCR on it later? Is it +important to obtain very high-quality images and text, etc.? +FLEISCHHAUER agreed with MYLONAS's framing of strategic questions, adding +that a large institution such as LC probably has to do all of those +things at different times. Thus, the trick is to exercise judgment. The +Workshop had added to his and AM's considerations in making those +judgments. Concerning future meetings or discussions, MYLONAS suggested +that screening priorities would be helpful. + +WEIBEL opined that the diversity reflected in this group was a sign both +of the health and of the immaturity of the field, and more time would +have to pass before we convince one another concerning standards. + +An exchange between MYLONAS and BATTIN clarified the point that the +driving force behind both the Perseus and the Cornell Xerox projects was +the preservation of knowledge for the future, not simply for particular +research use. In the case of Perseus, MYLONAS said, the assumption was +that the texts would not be entered again into electronically readable +form. SPERBERG-McQUEEN added that a scanned image would not serve as an +archival copy for purposes of preservation in the case of, say, the Bill +of Rights, in the sense that the scanned images are effectively the +archival copies for the Cornell mathematics books. + + + *** *** *** ****** *** *** *** + + + Appendix I: PROGRAM + + + + WORKSHOP + ON + ELECTRONIC + TEXTS + + + + 9-10 June 1992 + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + +Tuesday, 9 June 1992 + +NATIONAL DEMONSTRATION LAB, ATRIUM, LIBRARY MADISON + +8:30 AM Coffee and Danish, registration + +9:00 AM Welcome + + Prosser Gifford, Director for Scholarly Programs, and Carl + Fleischhauer, Coordinator, American Memory, Library of + Congress + +9:l5 AM Session I. Content in a New Form: Who Will Use It and What + Will They Do? + + Broad description of the range of electronic information. + Characterization of who uses it and how it is or may be used. + In addition to a look at scholarly uses, this session will + include a presentation on use by students (K-12 and college) + and the general public. + + Moderator: James Daly + Avra Michelson, Archival Research and Evaluation Staff, + National Archives and Records Administration (Overview) + Susan H. Veccia, Team Leader, American Memory, User Evaluation, + and + Joanne Freeman, Associate Coordinator, American Memory, Library + of Congress (Beyond the scholar) + +10:30- +11:00 AM Break + +11:00 AM Session II. Show and Tell. + + Each presentation to consist of a fifteen-minute + statement/show; group discussion will follow lunch. + + Moderator: Jacqueline Hess, Director, National Demonstration + Lab + + 1. A classics project, stressing texts and text retrieval + more than multimedia: Perseus Project, Harvard + University + Elli Mylonas, Managing Editor + + 2. Other humanities projects employing the emerging norms of + the Text Encoding Initiative (TEI): Chadwyck-Healey's + The English Poetry Full Text Database and/or Patrologia + Latina Database + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + + 3. American Memory + Carl Fleischhauer, Coordinator, and + Ricky Erway, Associate Coordinator, Library of Congress + + 4. Founding Fathers example from Packard Humanities + Institute: The Papers of George Washington, University + of Virginia + Dorothy Twohig, Managing Editor, and/or + David Woodley Packard + + 5. An electronic medical journal offering graphics and + full-text searchability: The Online Journal of Current + Clinical Trials, American Association for the Advancement + of Science + Maria L. Lebron, Managing Editor + + 6. A project that offers facsimile images of pages but omits + searchable text: Cornell math books + Lynne K. Personius, Assistant Director, Cornell + Information Technologies for Scholarly Information + Sources, Cornell University + +12:30 PM Lunch (Dining Room A, Library Madison 620. Exhibits + available.) + +1:30 PM Session II. Show and Tell (Cont'd.). + +3:00- +3:30 PM Break + +3:30- +5:30 PM Session III. Distribution, Networks, and Networking: Options + for Dissemination. + + Published disks: University presses and public-sector + publishers, private-sector publishers + Computer networks + + Moderator: Robert G. Zich, Special Assistant to the Associate + Librarian for Special Projects, Library of Congress + Clifford A. Lynch, Director, Library Automation, University of + California + Howard Besser, School of Library and Information Science, + University of Pittsburgh + Ronald L. Larsen, Associate Director of Libraries for + Information Technology, University of Maryland at College + Park + Edwin B. Brownrigg, Executive Director, Memex Research + Institute + +6:30 PM Reception (Montpelier Room, Library Madison 619.) + + ****** + +Wednesday, 10 June 1992 + +DINING ROOM A, LIBRARY MADISON 620 + +8:30 AM Coffee and Danish + +9:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats. + + Moderator: William L. Hooton, Vice President of Operations, + I-NET + + A) Principal Methods for Image Capture of Text: + Direct scanning + Use of microform + + Anne R. Kenney, Assistant Director, Department of Preservation + and Conservation, Cornell University + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + Donald J. Waters, Head, Systems Office, Yale University Library + + B) Special Problems: + Bound volumes + Conservation + Reproducing printed halftones + + Carl Fleischhauer, Coordinator, American Memory, Library of + Congress + George Thoma, Chief, Communications Engineering Branch, + National Library of Medicine (NLM) + +10:30- +11:00 AM Break + +11:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats (Cont'd.). + + C) Image Standards and Implications for Preservation + + Jean Baronas, Senior Manager, Department of Standards and + Technology, Association for Information and Image Management + (AIIM) + Patricia Battin, President, The Commission on Preservation and + Access (CPA) + + D) Text Conversion: + OCR vs. rekeying + Standards of accuracy and use of imperfect texts + Service bureaus + + Stuart Weibel, Senior Research Specialist, Online Computer + Library Center, Inc. (OCLC) + Michael Lesk, Executive Director, Computer Science Research, + Bellcore + Ricky Erway, Associate Coordinator, American Memory, Library of + Congress + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + +12:30- +1:30 PM Lunch + +1:30 PM Session V. Approaches to Preparing Electronic Texts. + + Discussion of approaches to structuring text for the computer; + pros and cons of text coding, description of methods in + practice, and comparison of text-coding methods. + + Moderator: Susan Hockey, Director, Center for Electronic Texts + in the Humanities (CETH), Rutgers and Princeton Universities + David Woodley Packard + C.M. Sperberg-McQueen, Editor, Text Encoding Initiative (TEI), + University of Illinois-Chicago + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + +3:30- +4:00 PM Break + +4:00 PM Session VI. Copyright Issues. + + Marybeth Peters, Policy Planning Adviser to the Register of + Copyrights, Library of Congress + +5:00 PM Session VII. Conclusion. + + General discussion. + What topics were omitted or given short shrift that anyone + would like to talk about now? + Is there a "group" here? What should the group do next, if + anything? What should the Library of Congress do next, if + anything? + Moderator: Prosser Gifford, Director for Scholarly Programs, + Library of Congress + +6:00 PM Adjourn + + + *** *** *** ****** *** *** *** + + + Appendix II: ABSTRACTS + + +SESSION I + +Avra MICHELSON Forecasting the Use of Electronic Texts by + Social Sciences and Humanities Scholars + +This presentation explores the ways in which electronic texts are likely +to be used by the non-scientific scholarly community. Many of the +remarks are drawn from a report the speaker coauthored with Jeff +Rothenberg, a computer scientist at The RAND Corporation. + +The speaker assesses 1) current scholarly use of information technology +and 2) the key trends in information technology most relevant to the +research process, in order to predict how social sciences and humanities +scholars are apt to use electronic texts. In introducing the topic, +current use of electronic texts is explored broadly within the context of +scholarly communication. From the perspective of scholarly +communication, the work of humanities and social sciences scholars +involves five processes: 1) identification of sources, 2) communication +with colleagues, 3) interpretation and analysis of data, 4) dissemination +of research findings, and 5) curriculum development and instruction. The +extent to which computation currently permeates aspects of scholarly +communication represents a viable indicator of the prospects for +electronic texts. + +The discussion of current practice is balanced by an analysis of key +trends in the scholarly use of information technology. These include the +trends toward end-user computing and connectivity, which provide a +framework for forecasting the use of electronic texts through this +millennium. The presentation concludes with a summary of the ways in +which the nonscientific scholarly community can be expected to use +electronic texts, and the implications of that use for information +providers. + +Susan VECCIA and Joanne FREEMAN Electronic Archives for the Public: + Use of American Memory in Public and + School Libraries + +This joint discussion focuses on nonscholarly applications of electronic +library materials, specifically addressing use of the Library of Congress +American Memory (AM) program in a small number of public and school +libraries throughout the United States. AM consists of selected Library +of Congress primary archival materials, stored on optical media +(CD-ROM/videodisc), and presented with little or no editing. Many +collections are accompanied by electronic introductions and user's guides +offering background information and historical context. Collections +represent a variety of formats including photographs, graphic arts, +motion pictures, recorded sound, music, broadsides and manuscripts, +books, and pamphlets. + +In 1991, the Library of Congress began a nationwide evaluation of AM in +different types of institutions. Test sites include public libraries, +elementary and secondary school libraries, college and university +libraries, state libraries, and special libraries. Susan VECCIA and +Joanne FREEMAN will discuss their observations on the use of AM by the +nonscholarly community, using evidence gleaned from this ongoing +evaluation effort. + +VECCIA will comment on the overall goals of the evaluation project, and +the types of public and school libraries included in this study. Her +comments on nonscholarly use of AM will focus on the public library as a +cultural and community institution, often bridging the gap between formal +and informal education. FREEMAN will discuss the use of AM in school +libraries. Use by students and teachers has revealed some broad +questions about the use of electronic resources, as well as definite +benefits gained by the "nonscholar." Topics will include the problem of +grasping content and context in an electronic environment, the stumbling +blocks created by "new" technologies, and the unique skills and interests +awakened through use of electronic resources. + +SESSION II + +Elli MYLONAS The Perseus Project: Interactive Sources and + Studies in Classical Greece + +The Perseus Project (5) has just released Perseus 1.0, the first publicly +available version of its hypertextual database of multimedia materials on +classical Greece. Perseus is designed to be used by a wide audience, +comprised of readers at the student and scholar levels. As such, it must +be able to locate information using different strategies, and it must +contain enough detail to serve the different needs of its users. In +addition, it must be delivered so that it is affordable to its target +audience. [These problems and the solutions we chose are described in +Mylonas, "An Interface to Classical Greek Civilization," JASIS 43:2, +March 1992.] + +In order to achieve its objective, the project staff decided to make a +conscious separation between selecting and converting textual, database, +and image data on the one hand, and putting it into a delivery system on +the other. That way, it is possible to create the electronic data +without thinking about the restrictions of the delivery system. We have +made a great effort to choose system-independent formats for our data, +and to put as much thought and work as possible into structuring it so +that the translation from paper to electronic form will enhance the value +of the data. [A discussion of these solutions as of two years ago is in +Elli Mylonas, Gregory Crane, Kenneth Morrell, and D. Neel Smith, "The +Perseus Project: Data in the Electronic Age," in Accessing Antiquity: +The Computerization of Classical Databases, J. Solomon and T. Worthen +(eds.), University of Arizona Press, in press.] + +Much of the work on Perseus is focused on collecting and converting the +data on which the project is based. At the same time, it is necessary to +provide means of access to the information, in order to make it usable, +and them to investigate how it is used. As we learn more about what +students and scholars from different backgrounds do with Perseus, we can +adjust our data collection, and also modify the system to accommodate +them. In creating a delivery system for general use, we have tried to +avoid favoring any one type of use by allowing multiple forms of access +to and navigation through the system. + +The way text is handled exemplifies some of these principles. All text +in Perseus is tagged using SGML, following the guidelines of the Text +Encoding Initiative (TEI). This markup is used to index the text, and +process it so that it can be imported into HyperCard. No SGML markup +remains in the text that reaches the user, because currently it would be +too expensive to create a system that acts on SGML in real time. +However, the regularity provided by SGML is essential for verifying the +content of the texts, and greatly speeds all the processing performed on +them. The fact that the texts exist in SGML ensures that they will be +relatively easy to port to different hardware and software, and so will +outlast the current delivery platform. Finally, the SGML markup +incorporates existing canonical reference systems (chapter, verse, line, +etc.); indexing and navigation are based on these features. This ensures +that the same canonical reference will always resolve to the same point +within a text, and that all versions of our texts, regardless of delivery +platform (even paper printouts) will function the same way. + +In order to provide tools for users, the text is processed by a +morphological analyzer, and the results are stored in a database. +Together with the index, the Greek-English Lexicon, and the index of all +the English words in the definitions of the lexicon, the morphological +analyses comprise a set of linguistic tools that allow users of all +levels to work with the textual information, and to accomplish different +tasks. For example, students who read no Greek may explore a concept as +it appears in Greek texts by using the English-Greek index, and then +looking up works in the texts and translations, or scholars may do +detailed morphological studies of word use by using the morphological +analyses of the texts. Because these tools were not designed for any one +use, the same tools and the same data can be used by both students and +scholars. + +NOTES: + (5) Perseus is based at Harvard University, with collaborators at + several other universities. The project has been funded primarily + by the Annenberg/CPB Project, as well as by Harvard University, + Apple Computer, and others. It is published by Yale University + Press. Perseus runs on Macintosh computers, under the HyperCard + program. + +Eric CALALUCA + +Chadwyck-Healey embarked last year on two distinct yet related full-text +humanities database projects. + +The English Poetry Full-Text Database and the Patrologia Latina Database +represent new approaches to linguistic research resources. The size and +complexity of the projects present problems for electronic publishers, +but surmountable ones if they remain abreast of the latest possibilities +in data capture and retrieval software techniques. + +The issues which required address prior to the commencement of the +projects were legion: + + 1. Editorial selection (or exclusion) of materials in each + database + + 2. Deciding whether or not to incorporate a normative encoding + structure into the databases? + A. If one is selected, should it be SGML? + B. If SGML, then the TEI? + + 3. Deliver as CD-ROM, magnetic tape, or both? + + 4. Can one produce retrieval software advanced enough for the + postdoctoral linguist, yet accessible enough for unattended + general use? Should one try? + + 5. Re fair and liberal networking policies, what are the risks to + an electronic publisher? + + 6. How does the emergence of national and international education + networks affect the use and viability of research projects + requiring high investment? Do the new European Community + directives concerning database protection necessitate two + distinct publishing projects, one for North America and one for + overseas? + +From new notions of "scholarly fair use" to the future of optical media, +virtually every issue related to electronic publishing was aired. The +result is two projects which have been constructed to provide the quality +research resources with the fewest encumbrances to use by teachers and +private scholars. + +Dorothy TWOHIG + +In spring 1988 the editors of the papers of George Washington, John +Adams, Thomas Jefferson, James Madison, and Benjamin Franklin were +approached by classics scholar David Packard on behalf of the Packard +Humanities Foundation with a proposal to produce a CD-ROM edition of the +complete papers of each of the Founding Fathers. This electronic edition +will supplement the published volumes, making the documents widely +available to students and researchers at reasonable cost. We estimate +that our CD-ROM edition of Washington's Papers will be substantially +completed within the next two years and ready for publication. Within +the next ten years or so, similar CD-ROM editions of the Franklin, Adams, +Jefferson, and Madison papers also will be available. At the Library of +Congress's session on technology, I would like to discuss not only the +experience of the Washington Papers in producing the CD-ROM edition, but +the impact technology has had on these major editorial projects. +Already, we are editing our volumes with an eye to the material that will +be readily available in the CD-ROM edition. The completed electronic +edition will provide immense possibilities for the searching of documents +for information in a way never possible before. The kind of technical +innovations that are currently available and on the drawing board will +soon revolutionize historical research and the production of historical +documents. Unfortunately, much of this new technology is not being used +in the planning stages of historical projects, simply because many +historians are aware only in the vaguest way of its existence. At least +two major new historical editing projects are considering microfilm +editions, simply because they are not aware of the possibilities of +electronic alternatives and the advantages of the new technology in terms +of flexibility and research potential compared to microfilm. In fact, +too many of us in history and literature are still at the stage of +struggling with our PCs. There are many historical editorial projects in +progress presently, and an equal number of literary projects. While the +two fields have somewhat different approaches to textual editing, there +are ways in which electronic technology can be of service to both. + +Since few of the editors involved in the Founding Fathers CD-ROM editions +are technical experts in any sense, I hope to point out in my discussion +of our experience how many of these electronic innovations can be used +successfully by scholars who are novices in the world of new technology. +One of the major concerns of the sponsors of the multitude of new +scholarly editions is the limited audience reached by the published +volumes. Most of these editions are being published in small quantities +and the publishers' price for them puts them out of the reach not only of +individual scholars but of most public libraries and all but the largest +educational institutions. However, little attention is being given to +ways in which technology can bypass conventional publication to make +historical and literary documents more widely available. + +What attracted us most to the CD-ROM edition of The Papers of George +Washington was the fact that David Packard's aim was to make a complete +edition of all of the 135,000 documents we have collected available in an +inexpensive format that would be placed in public libraries, small +colleges, and even high schools. This would provide an audience far +beyond our present 1,000-copy, $45 published edition. Since the CD-ROM +edition will carry none of the explanatory annotation that appears in the +published volumes, we also feel that the use of the CD-ROM will lead many +researchers to seek out the published volumes. + +In addition to ignorance of new technical advances, I have found that too +many editors--and historians and literary scholars--are resistant and +even hostile to suggestions that electronic technology may enhance their +work. I intend to discuss some of the arguments traditionalists are +advancing to resist technology, ranging from distrust of the speed with +which it changes (we are already wondering what is out there that is +better than CD-ROM) to suspicion of the technical language used to +describe electronic developments. + +Maria LEBRON + +The Online Journal of Current Clinical Trials, a joint venture of the +American Association for the Advancement of Science (AAAS) and the Online +Computer Library Center, Inc. (OCLC), is the first peer-reviewed journal +to provide full text, tabular material, and line illustrations on line. +This presentation will discuss the genesis and start-up period of the +journal. Topics of discussion will include historical overview, +day-to-day management of the editorial peer review, and manuscript +tagging and publication. A demonstration of the journal and its features +will accompany the presentation. + +Lynne PERSONIUS + +Cornell University Library, Cornell Information Technologies, and Xerox +Corporation, with the support of the Commission on Preservation and +Access, and Sun Microsystems, Inc., have been collaborating in a project +to test a prototype system for recording brittle books as digital images +and producing, on demand, high-quality archival paper replacements. The +project goes beyond that, however, to investigate some of the issues +surrounding scanning, storing, retrieving, and providing access to +digital images in a network environment. + +The Joint Study in Digital Preservation began in January 1990. Xerox +provided the College Library Access and Storage System (CLASS) software, +a prototype 600-dots-per-inch (dpi) scanner, and the hardware necessary +to support network printing on the DocuTech printer housed in Cornell's +Computing and Communications Center (CCC). + +The Cornell staff using the hardware and software became an integral part +of the development and testing process for enhancements to the CLASS +software system. The collaborative nature of this relationship is +resulting in a system that is specifically tailored to the preservation +application. + +A digital library of 1,000 volumes (or approximately 300,000 images) has +been created and is stored on an optical jukebox that resides in CCC. +The library includes a collection of select mathematics monographs that +provides mathematics faculty with an opportunity to use the electronic +library. The remaining volumes were chosen for the library to test the +various capabilities of the scanning system. + +One project objective is to provide users of the Cornell library and the +library staff with the ability to request facsimiles of digitized images +or to retrieve the actual electronic image for browsing. A prototype +viewing workstation has been created by Xerox, with input into the design +by a committee of Cornell librarians and computer professionals. This +will allow us to experiment with patron access to the images that make up +the digital library. The viewing station provides search, retrieval, and +(ultimately) printing functions with enhancements to facilitate +navigation through multiple documents. + +Cornell currently is working to extend access to the digital library to +readers using workstations from their offices. This year is devoted to +the development of a network resident image conversion and delivery +server, and client software that will support readers who use Apple +Macintosh computers, IBM windows platforms, and Sun workstations. +Equipment for this development was provided by Sun Microsystems with +support from the Commission on Preservation and Access. + +During the show-and-tell session of the Workshop on Electronic Texts, a +prototype view station will be demonstrated. In addition, a display of +original library books that have been digitized will be available for +review with associated printed copies for comparison. The fifteen-minute +overview of the project will include a slide presentation that +constitutes a "tour" of the preservation digitizing process. + +The final network-connected version of the viewing station will provide +library users with another mechanism for accessing the digital library, +and will also provide the capability of viewing images directly. This +will not require special software, although a powerful computer with good +graphics will be needed. + +The Joint Study in Digital Preservation has generated a great deal of +interest in the library community. Unfortunately, or perhaps +fortunately, this project serves to raise a vast number of other issues +surrounding the use of digital technology for the preservation and use of +deteriorating library materials, which subsequent projects will need to +examine. Much work remains. + +SESSION III + +Howard BESSER Networking Multimedia Databases + +What do we have to consider in building and distributing databases of +visual materials in a multi-user environment? This presentation examines +a variety of concerns that need to be addressed before a multimedia +database can be set up in a networked environment. + +In the past it has not been feasible to implement databases of visual +materials in shared-user environments because of technological barriers. +Each of the two basic models for multi-user multimedia databases has +posed its own problem. The analog multimedia storage model (represented +by Project Athena's parallel analog and digital networks) has required an +incredibly complex (and expensive) infrastructure. The economies of +scale that make multi-user setups cheaper per user served do not operate +in an environment that requires a computer workstation, videodisc player, +and two display devices for each user. + +The digital multimedia storage model has required vast amounts of storage +space (as much as one gigabyte per thirty still images). In the past the +cost of such a large amount of storage space made this model a +prohibitive choice as well. But plunging storage costs are finally +making this second alternative viable. + +If storage no longer poses such an impediment, what do we need to +consider in building digitally stored multi-user databases of visual +materials? This presentation will examine the networking and +telecommunication constraints that must be overcome before such databases +can become commonplace and useful to a large number of people. + +The key problem is the vast size of multimedia documents, and how this +affects not only storage but telecommunications transmission time. +Anything slower than T-1 speed is impractical for files of 1 megabyte or +larger (which is likely to be small for a multimedia document). For +instance, even on a 56 Kb line it would take three minutes to transfer a +1-megabyte file. And these figures assume ideal circumstances, and do +not take into consideration other users contending for network bandwidth, +disk access time, or the time needed for remote display. Current common +telephone transmission rates would be completely impractical; few users +would be willing to wait the hour necessary to transmit a single image at +2400 baud. + +This necessitates compression, which itself raises a number of other +issues. In order to decrease file sizes significantly, we must employ +lossy compression algorithms. But how much quality can we afford to +lose? To date there has been only one significant study done of +image-quality needs for a particular user group, and this study did not +look at loss resulting from compression. Only after identifying +image-quality needs can we begin to address storage and network bandwidth +needs. + +Experience with X-Windows-based applications (such as Imagequery, the +University of California at Berkeley image database) demonstrates the +utility of a client-server topology, but also points to the limitation of +current software for a distributed environment. For example, +applications like Imagequery can incorporate compression, but current X +implementations do not permit decompression at the end user's +workstation. Such decompression at the host computer alleviates storage +capacity problems while doing nothing to address problems of +telecommunications bandwidth. + +We need to examine the effects on network through-put of moving +multimedia documents around on a network. We need to examine various +topologies that will help us avoid bottlenecks around servers and +gateways. Experience with applications such as these raise still broader +questions. How closely is the multimedia document tied to the software +for viewing it? Can it be accessed and viewed from other applications? +Experience with the MARC format (and more recently with the Z39.50 +protocols) shows how useful it can be to store documents in a form in +which they can be accessed by a variety of application software. + +Finally, from an intellectual-access standpoint, we need to address the +issue of providing access to these multimedia documents in +interdisciplinary environments. We need to examine terminology and +indexing strategies that will allow us to provide access to this material +in a cross-disciplinary way. + +Ronald LARSEN Directions in High-Performance Networking for + Libraries + +The pace at which computing technology has advanced over the past forty +years shows no sign of abating. Roughly speaking, each five-year period +has yielded an order-of-magnitude improvement in price and performance of +computing equipment. No fundamental hurdles are likely to prevent this +pace from continuing for at least the next decade. It is only in the +past five years, though, that computing has become ubiquitous in +libraries, affecting all staff and patrons, directly or indirectly. + +During these same five years, communications rates on the Internet, the +principal academic computing network, have grown from 56 kbps to 1.5 +Mbps, and the NSFNet backbone is now running 45 Mbps. Over the next five +years, communication rates on the backbone are expected to exceed 1 Gbps. +Growth in both the population of network users and the volume of network +traffic has continued to grow geometrically, at rates approaching 15 +percent per month. This flood of capacity and use, likened by some to +"drinking from a firehose," creates immense opportunities and challenges +for libraries. Libraries must anticipate the future implications of this +technology, participate in its development, and deploy it to ensure +access to the world's information resources. + +The infrastructure for the information age is being put in place. +Libraries face strategic decisions about their role in the development, +deployment, and use of this infrastructure. The emerging infrastructure +is much more than computers and communication lines. It is more than the +ability to compute at a remote site, send electronic mail to a peer +across the country, or move a file from one library to another. The next +five years will witness substantial development of the information +infrastructure of the network. + +In order to provide appropriate leadership, library professionals must +have a fundamental understanding of and appreciation for computer +networking, from local area networks to the National Research and +Education Network (NREN). This presentation addresses these +fundamentals, and how they relate to libraries today and in the near +future. + +Edwin BROWNRIGG Electronic Library Visions and Realities + +The electronic library has been a vision desired by many--and rejected by +some--since Vannevar Bush coined the term memex to describe an automated, +intelligent, personal information system. Variations on this vision have +included Ted Nelson's Xanadau, Alan Kay's Dynabook, and Lancaster's +"paperless library," with the most recent incarnation being the +"Knowledge Navigator" described by John Scully of Apple. But the reality +of library service has been less visionary and the leap to the electronic +library has eluded universities, publishers, and information technology +files. + +The Memex Research Institute (MemRI), an independent, nonprofit research +and development organization, has created an Electronic Library Program +of shared research and development in order to make the collective vision +more concrete. The program is working toward the creation of large, +indexed publicly available electronic image collections of published +documents in academic, special, and public libraries. This strategic +plan is the result of the first stage of the program, which has been an +investigation of the information technologies available to support such +an effort, the economic parameters of electronic service compared to +traditional library operations, and the business and political factors +affecting the shift from print distribution to electronic networked +access. + +The strategic plan envisions a combination of publicly searchable access +databases, image (and text) document collections stored on network "file +servers," local and remote network access, and an intellectual property +management-control system. This combination of technology and +information content is defined in this plan as an E-library or E-library +collection. Some participating sponsors are already developing projects +based on MemRI's recommended directions. + +The E-library strategy projected in this plan is a visionary one that can +enable major changes and improvements in academic, public, and special +library service. This vision is, though, one that can be realized with +today's technology. At the same time, it will challenge the political +and social structure within which libraries operate: in academic +libraries, the traditional emphasis on local collections, extending to +accreditation issues; in public libraries, the potential of electronic +branch and central libraries fully available to the public; and for +special libraries, new opportunities for shared collections and networks. + +The environment in which this strategic plan has been developed is, at +the moment, dominated by a sense of library limits. The continued +expansion and rapid growth of local academic library collections is now +clearly at an end. Corporate libraries, and even law libraries, are +faced with operating within a difficult economic climate, as well as with +very active competition from commercial information sources. For +example, public libraries may be seen as a desirable but not critical +municipal service in a time when the budgets of safety and health +agencies are being cut back. + +Further, libraries in general have a very high labor-to-cost ratio in +their budgets, and labor costs are still increasing, notwithstanding +automation investments. It is difficult for libraries to obtain capital, +startup, or seed funding for innovative activities, and those +technology-intensive initiatives that offer the potential of decreased +labor costs can provoke the opposition of library staff. + +However, libraries have achieved some considerable successes in the past +two decades by improving both their service and their credibility within +their organizations--and these positive changes have been accomplished +mostly with judicious use of information technologies. The advances in +computing and information technology have been well-chronicled: the +continuing precipitous drop in computing costs, the growth of the +Internet and private networks, and the explosive increase in publicly +available information databases. + +For example, OCLC has become one of the largest computer network +organizations in the world by creating a cooperative cataloging network +of more than 6,000 libraries worldwide. On-line public access catalogs +now serve millions of users on more than 50,000 dedicated terminals in +the United States alone. The University of California MELVYL on-line +catalog system has now expanded into an index database reference service +and supports more than six million searches a year. And, libraries have +become the largest group of customers of CD-ROM publishing technology; +more than 30,000 optical media publications such as those offered by +InfoTrac and Silver Platter are subscribed to by U.S. libraries. + +This march of technology continues and in the next decade will result in +further innovations that are extremely difficult to predict. What is +clear is that libraries can now go beyond automation of their order files +and catalogs to automation of their collections themselves--and it is +possible to circumvent the fiscal limitations that appear to obtain +today. + +This Electronic Library Strategic Plan recommends a paradigm shift in +library service, and demonstrates the steps necessary to provide improved +library services with limited capacities and operating investments. + +SESSION IV-A + +Anne KENNEY + +The Cornell/Xerox Joint Study in Digital Preservation resulted in the +recording of 1,000 brittle books as 600-dpi digital images and the +production, on demand, of high-quality and archivally sound paper +replacements. The project, which was supported by the Commission on +Preservation and Access, also investigated some of the issues surrounding +scanning, storing, retrieving, and providing access to digital images in +a network environment. + +Anne Kenney will focus on some of the issues surrounding direct scanning +as identified in the Cornell Xerox Project. Among those to be discussed +are: image versus text capture; indexing and access; image-capture +capabilities; a comparison to photocopy and microfilm; production and +cost analysis; storage formats, protocols, and standards; and the use of +this scanning technology for preservation purposes. + +The 600-dpi digital images produced in the Cornell Xerox Project proved +highly acceptable for creating paper replacements of deteriorating +originals. The 1,000 scanned volumes provided an array of image-capture +challenges that are common to nineteenth-century printing techniques and +embrittled material, and that defy the use of text-conversion processes. +These challenges include diminished contrast between text and background, +fragile and deteriorated pages, uneven printing, elaborate type faces, +faint and bold text adjacency, handwritten text and annotations, nonRoman +languages, and a proliferation of illustrated material embedded in text. +The latter category included high-frequency and low-frequency halftones, +continuous tone photographs, intricate mathematical drawings, maps, +etchings, reverse-polarity drawings, and engravings. + +The Xerox prototype scanning system provided a number of important +features for capturing this diverse material. Technicians used multiple +threshold settings, filters, line art and halftone definitions, +autosegmentation, windowing, and software-editing programs to optimize +image capture. At the same time, this project focused on production. +The goal was to make scanning as affordable and acceptable as +photocopying and microfilming for preservation reformatting. A +time-and-cost study conducted during the last three months of this +project confirmed the economic viability of digital scanning, and these +findings will be discussed here. + +From the outset, the Cornell Xerox Project was predicated on the use of +nonproprietary standards and the use of common protocols when standards +did not exist. Digital files were created as TIFF images which were +compressed prior to storage using Group 4 CCITT compression. The Xerox +software is MS DOS based and utilizes off-the shelf programs such as +Microsoft Windows and Wang Image Wizard. The digital library is designed +to be hardware-independent and to provide interchangeability with other +institutions through network connections. Access to the digital files +themselves is two-tiered: Bibliographic records for the computer files +are created in RLIN and Cornell's local system and access into the actual +digital images comprising a book is provided through a document control +structure and a networked image file-server, both of which will be +described. + +The presentation will conclude with a discussion of some of the issues +surrounding the use of this technology as a preservation tool (storage, +refreshing, backup). + +Pamela ANDRE and Judith ZIDAR + +The National Agricultural Library (NAL) has had extensive experience with +raster scanning of printed materials. Since 1987, the Library has +participated in the National Agricultural Text Digitizing Project (NATDP) +a cooperative effort between NAL and forty-five land grant university +libraries. An overview of the project will be presented, giving its +history and NAL's strategy for the future. + +An in-depth discussion of NATDP will follow, including a description of +the scanning process, from the gathering of the printed materials to the +archiving of the electronic pages. The type of equipment required for a +stand-alone scanning workstation and the importance of file management +software will be discussed. Issues concerning the images themselves will +be addressed briefly, such as image format; black and white versus color; +gray scale versus dithering; and resolution. + +Also described will be a study currently in progress by NAL to evaluate +the usefulness of converting microfilm to electronic images in order to +improve access. With the cooperation of Tuskegee University, NAL has +selected three reels of microfilm from a collection of sixty-seven reels +containing the papers, letters, and drawings of George Washington Carver. +The three reels were converted into 3,500 electronic images using a +specialized microfilm scanner. The selection, filming, and indexing of +this material will be discussed. + +Donald WATERS + +Project Open Book, the Yale University Library's effort to convert 10, +000 books from microfilm to digital imagery, is currently in an advanced +state of planning and organization. The Yale Library has selected a +major vendor to serve as a partner in the project and as systems +integrator. In its proposal, the successful vendor helped isolate areas +of risk and uncertainty as well as key issues to be addressed during the +life of the project. The Yale Library is now poised to decide what +material it will convert to digital image form and to seek funding, +initially for the first phase and then for the entire project. + +The proposal that Yale accepted for the implementation of Project Open +Book will provide at the end of three phases a conversion subsystem, +browsing stations distributed on the campus network within the Yale +Library, a subsystem for storing 10,000 books at 200 and 600 dots per +inch, and network access to the image printers. Pricing for the system +implementation assumes the existence of Yale's campus ethernet network +and its high-speed image printers, and includes other requisite hardware +and software, as well as system integration services. Proposed operating +costs include hardware and software maintenance, but do not include +estimates for the facilities management of the storage devices and image +servers. + +Yale selected its vendor partner in a formal process, partly funded by +the Commission for Preservation and Access. Following a request for +proposal, the Yale Library selected two vendors as finalists to work with +Yale staff to generate a detailed analysis of requirements for Project +Open Book. Each vendor used the results of the requirements analysis to +generate and submit a formal proposal for the entire project. This +competitive process not only enabled the Yale Library to select its +primary vendor partner but also revealed much about the state of the +imaging industry, about the varying, corporate commitments to the markets +for imaging technology, and about the varying organizational dynamics +through which major companies are responding to and seeking to develop +these markets. + +Project Open Book is focused specifically on the conversion of images +from microfilm to digital form. The technology for scanning microfilm is +readily available but is changing rapidly. In its project requirements, +the Yale Library emphasized features of the technology that affect the +technical quality of digital image production and the costs of creating +and storing the image library: What levels of digital resolution can be +achieved by scanning microfilm? How does variation in the quality of +microfilm, particularly in film produced to preservation standards, +affect the quality of the digital images? What technologies can an +operator effectively and economically apply when scanning film to +separate two-up images and to control for and correct image +imperfections? How can quality control best be integrated into +digitizing work flow that includes document indexing and storage? + +The actual and expected uses of digital images--storage, browsing, +printing, and OCR--help determine the standards for measuring their +quality. Browsing is especially important, but the facilities available +for readers to browse image documents is perhaps the weakest aspect of +imaging technology and most in need of development. As it defined its +requirements, the Yale Library concentrated on some fundamental aspects +of usability for image documents: Does the system have sufficient +flexibility to handle the full range of document types, including +monographs, multi-part and multivolume sets, and serials, as well as +manuscript collections? What conventions are necessary to identify a +document uniquely for storage and retrieval? Where is the database of +record for storing bibliographic information about the image document? +How are basic internal structures of documents, such as pagination, made +accessible to the reader? How are the image documents physically +presented on the screen to the reader? + +The Yale Library designed Project Open Book on the assumption that +microfilm is more than adequate as a medium for preserving the content of +deteriorated library materials. As planning in the project has advanced, +it is increasingly clear that the challenge of digital image technology +and the key to the success of efforts like Project Open Book is to +provide a means of both preserving and improving access to those +deteriorated materials. + +SESSION IV-B + +George THOMA + +In the use of electronic imaging for document preservation, there are +several issues to consider, such as: ensuring adequate image quality, +maintaining substantial conversion rates (through-put), providing unique +identification for automated access and retrieval, and accommodating +bound volumes and fragile material. + +To maintain high image quality, image processing functions are required +to correct the deficiencies in the scanned image. Some commercially +available systems include these functions, while some do not. The +scanned raw image must be processed to correct contrast deficiencies-- +both poor overall contrast resulting from light print and/or dark +background, and variable contrast resulting from stains and +bleed-through. Furthermore, the scan density must be adequate to allow +legibility of print and sufficient fidelity in the pseudo-halftoned gray +material. Borders or page-edge effects must be removed for both +compactibility and aesthetics. Page skew must be corrected for aesthetic +reasons and to enable accurate character recognition if desired. +Compound images consisting of both two-toned text and gray-scale +illustrations must be processed appropriately to retain the quality of +each. + +SESSION IV-C + +Jean BARONAS + +Standards publications being developed by scientists, engineers, and +business managers in Association for Information and Image Management +(AIIM) standards committees can be applied to electronic image management +(EIM) processes including: document (image) transfer, retrieval and +evaluation; optical disk and document scanning; and document design and +conversion. When combined with EIM system planning and operations, +standards can assist in generating image databases that are +interchangeable among a variety of systems. The applications of +different approaches for image-tagging, indexing, compression, and +transfer often cause uncertainty concerning EIM system compatibility, +calibration, performance, and upward compatibility, until standard +implementation parameters are established. The AIIM standards that are +being developed for these applications can be used to decrease the +uncertainty, successfully integrate imaging processes, and promote "open +systems." AIIM is an accredited American National Standards Institute +(ANSI) standards developer with more than twenty committees comprised of +300 volunteers representing users, vendors, and manufacturers. The +standards publications that are developed in these committees have +national acceptance and provide the basis for international harmonization +in the development of new International Organization for Standardization +(ISO) standards. + +This presentation describes the development of AIIM's EIM standards and a +new effort at AIIM, a database on standards projects in a wide framework +of imaging industries including capture, recording, processing, +duplication, distribution, display, evaluation, and preservation. The +AIIM Imagery Database will cover imaging standards being developed by +many organizations in many different countries. It will contain +standards publications' dates, origins, related national and +international projects, status, key words, and abstracts. The ANSI Image +Technology Standards Board requested that such a database be established, +as did the ISO/International Electrotechnical Commission Joint Task Force +on Imagery. AIIM will take on the leadership role for the database and +coordinate its development with several standards developers. + +Patricia BATTIN + + Characteristics of standards for digital imagery: + + * Nature of digital technology implies continuing volatility. + + * Precipitous standard-setting not possible and probably not + desirable. + + * Standards are a complex issue involving the medium, the + hardware, the software, and the technical capacity for + reproductive fidelity and clarity. + + * The prognosis for reliable archival standards (as defined by + librarians) in the foreseeable future is poor. + + Significant potential and attractiveness of digital technology as a + preservation medium and access mechanism. + + Productive use of digital imagery for preservation requires a + reconceptualizing of preservation principles in a volatile, + standardless world. + + Concept of managing continuing access in the digital environment + rather than focusing on the permanence of the medium and long-term + archival standards developed for the analog world. + + Transition period: How long and what to do? + + * Redefine "archival." + + * Remove the burden of "archival copy" from paper artifacts. + + * Use digital technology for storage, develop management + strategies for refreshing medium, hardware and software. + + * Create acid-free paper copies for transition period backup + until we develop reliable procedures for ensuring continuing + access to digital files. + +SESSION IV-D + +Stuart WEIBEL The Role of SGML Markup in the CORE Project (6) + +The emergence of high-speed telecommunications networks as a basic +feature of the scholarly workplace is driving the demand for electronic +document delivery. Three distinct categories of electronic +publishing/republishing are necessary to support access demands in this +emerging environment: + + 1.) Conversion of paper or microfilm archives to electronic format + 2.) Conversion of electronic files to formats tailored to + electronic retrieval and display + 3.) Primary electronic publishing (materials for which the + electronic version is the primary format) + +OCLC has experimental or product development activities in each of these +areas. Among the challenges that lie ahead is the integration of these +three types of information stores in coherent distributed systems. + +The CORE (Chemistry Online Retrieval Experiment) Project is a model for +the conversion of large text and graphics collections for which +electronic typesetting files are available (category 2). The American +Chemical Society has made available computer typography files dating from +1980 for its twenty journals. This collection of some 250 journal-years +is being converted to an electronic format that will be accessible +through several end-user applications. + +The use of Standard Generalized Markup Language (SGML) offers the means +to capture the structural richness of the original articles in a way that +will support a variety of retrieval, navigation, and display options +necessary to navigate effectively in very large text databases. + +An SGML document consists of text that is marked up with descriptive tags +that specify the function of a given element within the document. As a +formal language construct, an SGML document can be parsed against a +document-type definition (DTD) that unambiguously defines what elements +are allowed and where in the document they can (or must) occur. This +formalized map of article structure allows the user interface design to +be uncoupled from the underlying database system, an important step +toward interoperability. Demonstration of this separability is a part of +the CORE project, wherein user interface designs born of very different +philosophies will access the same database. + +NOTES: + (6) The CORE project is a collaboration among Cornell University's + Mann Library, Bell Communications Research (Bellcore), the American + Chemical Society (ACS), the Chemical Abstracts Service (CAS), and + OCLC. + +Michael LESK The CORE Electronic Chemistry Library + +A major on-line file of chemical journal literature complete with +graphics is being developed to test the usability of fully electronic +access to documents, as a joint project of Cornell University, the +American Chemical Society, the Chemical Abstracts Service, OCLC, and +Bellcore (with additional support from Sun Microsystems, Springer-Verlag, +DigitaI Equipment Corporation, Sony Corporation of America, and Apple +Computers). Our file contains the American Chemical Society's on-line +journals, supplemented with the graphics from the paper publication. The +indexing of the articles from Chemical Abstracts Documents is available +in both image and text format, and several different interfaces can be +used. Our goals are (1) to assess the effectiveness and acceptability of +electronic access to primary journals as compared with paper, and (2) to +identify the most desirable functions of the user interface to an +electronic system of journals, including in particular a comparison of +page-image display with ASCII display interfaces. Early experiments with +chemistry students on a variety of tasks suggest that searching tasks are +completed much faster with any electronic system than with paper, but +that for reading all versions of the articles are roughly equivalent. + +Pamela ANDRE and Judith ZIDAR + +Text conversion is far more expensive and time-consuming than image +capture alone. NAL's experience with optical character recognition (OCR) +will be related and compared with the experience of having text rekeyed. +What factors affect OCR accuracy? How accurate does full text have to be +in order to be useful? How do different users react to imperfect text? +These are questions that will be explored. For many, a service bureau +may be a better solution than performing the work inhouse; this will also +be discussed. + +SESSION VI + +Marybeth PETERS + +Copyright law protects creative works. Protection granted by the law to +authors and disseminators of works includes the right to do or authorize +the following: reproduce the work, prepare derivative works, distribute +the work to the public, and publicly perform or display the work. In +addition, copyright owners of sound recordings and computer programs have +the right to control rental of their works. These rights are not +unlimited; there are a number of exceptions and limitations. + +An electronic environment places strains on the copyright system. +Copyright owners want to control uses of their work and be paid for any +use; the public wants quick and easy access at little or no cost. The +marketplace is working in this area. Contracts, guidelines on electronic +use, and collective licensing are in use and being refined. + +Issues concerning the ability to change works without detection are more +difficult to deal with. Questions concerning the integrity of the work +and the status of the changed version under the copyright law are to be +addressed. These are public policy issues which require informed +dialogue. + + + *** *** *** ****** *** *** *** + + + Appendix III: DIRECTORY OF PARTICIPANTS + + +PRESENTERS: + + Pamela Q.J. Andre + Associate Director, Automation + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 + Fax: (301) 504-7473 + E-mail: INTERNET: PANDRE@ASRR.ARSUSDA.GOV + + Jean Baronas, Senior Manager + Department of Standards and Technology + Association for Information and Image Management (AIIM) + 1100 Wayne Avenue, Suite 1100 + Silver Spring, MD 20910 + Phone: (301) 587-8202 + Fax: (301) 587-2711 + + Patricia Battin, President + The Commission on Preservation and Access + 1400 16th Street, N.W. + Suite 740 + Washington, DC 20036-2217 + Phone: (202) 939-3400 + Fax: (202) 939-3407 + E-mail: CPA@GWUVM.BITNET + + Howard Besser + Centre Canadien d'Architecture + (Canadian Center for Architecture) + 1920, rue Baile + Montreal, Quebec H3H 2S6 + CANADA + Phone: (514) 939-7001 + Fax: (514) 939-7020 + E-mail: howard@lis.pitt.edu + + Edwin B. Brownrigg, Executive Director + Memex Research Institute + 422 Bonita Avenue + Roseville, CA 95678 + Phone: (916) 784-2298 + Fax: (916) 786-7559 + E-mail: BITNET: MEMEX@CALSTATE.2 + + Eric M. Calaluca, Vice President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + James Daly + 4015 Deepwood Road + Baltimore, MD 21218-1404 + Phone: (410) 235-0763 + + Ricky Erway, Associate Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Carl Fleischhauer, Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Joanne Freeman + 2000 Jefferson Park Avenue, No. 7 + Charlottesville, VA 22903 + + Prosser Gifford + Director for Scholarly Programs + Library of Congress + Phone: (202) 707-1517 + Fax: (202) 707-9898 + E-mail: pgif@seq1.loc.gov + + Jacqueline Hess, Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Susan Hockey, Director + Center for Electronic Texts in the Humanities (CETH) + Alexander Library + Rutgers University + 169 College Avenue + New Brunswick, NJ 08903 + Phone: (908) 932-1384 + Fax: (908) 932-1386 + E-mail: hockey@zodiac.rutgers.edu + + William L. Hooton, Vice President + Business & Technical Development + Imaging & Information Systems Group + I-NET + 6430 Rockledge Drive, Suite 400 + Bethesda, MD 208l7 + Phone: (301) 564-6750 + Fax: (513) 564-6867 + + Anne R. Kenney, Associate Director + Department of Preservation and Conservation + 701 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-6875 + Fax: (607) 255-9346 + E-mail: LYDY@CORNELLA.BITNET + + Ronald L. Larsen + Associate Director for Information Technology + University of Maryland at College Park + Room B0224, McKeldin Library + College Park, MD 20742-7011 + Phone: (301) 405-9194 + Fax: (301) 314-9865 + E-mail: rlarsen@libr.umd.edu + + Maria L. Lebron, Managing Editor + The Online Journal of Current Clinical Trials + l333 H Street, N.W. + Washington, DC 20005 + Phone: (202) 326-6735 + Fax: (202) 842-2868 + E-mail: PUBSAAAS@GWUVM.BITNET + + Michael Lesk, Executive Director + Computer Science Research + Bell Communications Research, Inc. + Rm 2A-385 + 445 South Street + Morristown, NJ 07960-l9l0 + Phone: (201) 829-4070 + Fax: (201) 829-5981 + E-mail: lesk@bellcore.com (Internet) or bellcore!lesk (uucp) + + Clifford A. Lynch + Director, Library Automation + University of California, + Office of the President + 300 Lakeside Drive, 8th Floor + Oakland, CA 94612-3350 + Phone: (510) 987-0522 + Fax: (510) 839-3573 + E-mail: calur@uccmvsa + + Avra Michelson + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, D.C. 20408 + Phone: (202) 501-5544 + Fax: (202) 501-5533 + E-mail: tmi@cu.nih.gov + + Elli Mylonas, Managing Editor + Perseus Project + Department of the Classics + Harvard University + 319 Boylston Hall + Cambridge, MA 02138 + Phone: (617) 495-9025, (617) 495-0456 (direct) + Fax: (617) 496-8886 + E-mail: Elli@IKAROS.Harvard.EDU or elli@wjh12.harvard.edu + + David Woodley Packard + Packard Humanities Institute + 300 Second Street, Suite 201 + Los Altos, CA 94002 + Phone: (415) 948-0150 (PHI) + Fax: (415) 948-5793 + + Lynne K. Personius, Assistant Director + Cornell Information Technologies for + Scholarly Information Sources + 502 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-3393 + Fax: (607) 255-9346 + E-mail: JRN@CORNELLC.BITNET + + Marybeth Peters + Policy Planning Adviser to the + Register of Copyrights + Library of Congress + Office LM 403 + Phone: (202) 707-8350 + Fax: (202) 707-8366 + + C. Michael Sperberg-McQueen + Editor, Text Encoding Initiative + Computer Center (M/C 135) + University of Illinois at Chicago + Box 6998 + Chicago, IL 60680 + Phone: (312) 413-0317 + Fax: (312) 996-6834 + E-mail: u35395@uicvm..cc.uic.edu or u35395@uicvm.bitnet + + George R. Thoma, Chief + Communications Engineering Branch + National Library of Medicine + 8600 Rockville Pike + Bethesda, MD 20894 + Phone: (301) 496-4496 + Fax: (301) 402-0341 + E-mail: thoma@lhc.nlm.nih.gov + + Dorothy Twohig, Editor + The Papers of George Washington + 504 Alderman Library + University of Virginia + Charlottesville, VA 22903-2498 + Phone: (804) 924-0523 + Fax: (804) 924-4337 + + Susan H. Veccia, Team leader + American Memory, User Evaluation + Library of Congress + American Memory Evaluation Project + Phone: (202) 707-9104 + Fax: (202) 707-3764 + E-mail: svec@seq1.loc.gov + + Donald J. Waters, Head + Systems Office + Yale University Library + New Haven, CT 06520 + Phone: (203) 432-4889 + Fax: (203) 432-7231 + E-mail: DWATERS@YALEVM.BITNET or DWATERS@YALEVM.YCC.YALE.EDU + + Stuart Weibel, Senior Research Scientist + OCLC + 6565 Frantz Road + Dublin, OH 43017 + Phone: (614) 764-608l + Fax: (614) 764-2344 + E-mail: INTERNET: Stu@rsch.oclc.org + + Robert G. Zich + Special Assistant to the Associate Librarian + for Special Projects + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + E-mail: rzic@seq1.loc.gov + + Judith A. Zidar, Coordinator + National Agricultural Text Digitizing Program + Information Systems Division + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 or 504-5853 + Fax: (301) 504-7473 + E-mail: INTERNET: JZIDAR@ASRR.ARSUSDA.GOV + + +OBSERVERS: + + Helen Aguera, Program Officer + Division of Research + Room 318 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, D.C. 20506 + Phone: (202) 786-0358 + Fax: (202) 786-0243 + + M. Ellyn Blanton, Deputy Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Charles M. Dollar + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5532 + Fax: (202) 501-5512 + + Jeffrey Field, Deputy to the Director + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0570 + Fax: (202) 786-0243 + + Lorrin Garson + American Chemical Society + Research and Development Department + 1155 16th Street, N.W. + Washington, D.C. 20036 + Phone: (202) 872-4541 + Fax: E-mail: INTERNET: LRG96@ACS.ORG + + William M. Holmes, Jr. + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5540 + Fax: (202) 501-5512 + E-mail: WHOLMES@AMERICAN.EDU + + Sperling Martin + Information Resource Management + 20030 Doolittle Street + Gaithersburg, MD 20879 + Phone: (301) 924-1803 + + Michael Neuman, Director + The Center for Text and Technology + Academic Computing Center + 238 Reiss Science Building + Georgetown University + Washington, DC 20057 + Phone: (202) 687-6096 + Fax: (202) 687-6003 + E-mail: neuman@guvax.bitnet, neuman@guvax.georgetown.edu + + Barbara Paulson, Program Officer + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0577 + Fax: (202) 786-0243 + + Allen H. Renear + Senior Academic Planning Analyst + Brown University Computing and Information Services + 115 Waterman Street + Campus Box 1885 + Providence, R.I. 02912 + Phone: (401) 863-7312 + Fax: (401) 863-7329 + E-mail: BITNET: Allen@BROWNVM or + INTERNET: Allen@brownvm.brown.edu + + Susan M. Severtson, President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + Frank Withrow + U.S. Department of Education + 555 New Jersey Avenue, N.W. + Washington, DC 20208-5644 + Phone: (202) 219-2200 + Fax: (202) 219-2106 + + +(LC STAFF) + + Linda L. Arret + Machine-Readable Collections Reading Room LJ 132 + (202) 707-1490 + + John D. Byrum, Jr. + Descriptive Cataloging Division LM 540 + (202) 707-5194 + + Mary Jane Cavallo + Science and Technology Division LA 5210 + (202) 707-1219 + + Susan Thea David + Congressional Research Service LM 226 + (202) 707-7169 + + Robert Dierker + Senior Adviser for Multimedia Activities LM 608 + (202) 707-6151 + + William W. Ellis + Associate Librarian for Science and Technology LM 611 + (202) 707-6928 + + Ronald Gephart + Manuscript Division LM 102 + (202) 707-5097 + + James Graber + Information Technology Services LM G51 + (202) 707-9628 + + Rich Greenfield + American Memory LM 603 + (202) 707-6233 + + Rebecca Guenther + Network Development LM 639 + (202) 707-5092 + + Kenneth E. Harris + Preservation LM G21 + (202) 707-5213 + + Staley Hitchcock + Manuscript Division LM 102 + (202) 707-5383 + + Bohdan Kantor + Office of Special Projects LM 612 + (202) 707-0180 + + John W. Kimball, Jr + Machine-Readable Collections Reading Room LJ 132 + (202) 707-6560 + + Basil Manns + Information Technology Services LM G51 + (202) 707-8345 + + Sally Hart McCallum + Network Development LM 639 + (202) 707-6237 + + Dana J. Pratt + Publishing Office LM 602 + (202) 707-6027 + + Jane Riefenhauser + American Memory LM 603 + (202) 707-6233 + + William Z. Schenck + Collections Development LM 650 + (202) 707-7706 + + Chandru J. Shahani + Preservation Research and Testing Office (R&T) LM G38 + (202) 707-5607 + + William J. Sittig + Collections Development LM 650 + (202) 707-7050 + + Paul Smith + Manuscript Division LM 102 + (202) 707-5097 + + James L. Stevens + Information Technology Services LM G51 + (202) 707-9688 + + Karen Stuart + Manuscript Division LM 130 + (202) 707-5389 + + Tamara Swora + Preservation Microfilming Office LM G05 + (202) 707-6293 + + Sarah Thomas + Collections Cataloging LM 642 + (202) 707-5333 + + + END + ************************************************************* + +Note: This file has been edited for use on computer networks. This +editing required the removal of diacritics, underlining, and fonts such +as italics and bold. + +kde 11/92 + +[A few of the italics (when used for emphasis) were replaced by CAPS mh] + +*End of The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC ETEXTS + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/data/paper-100k.pdf b/internal-complibs/zlib-ng-2.1.1-beta2/test/data/paper-100k.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b3325e4a2bb578419d6c7fa412aaa78d493ff274 GIT binary patch literal 102400 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 f+ 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 +#include +#include + +#include "test_shared_ng.h" + +#define TESTFILE "foo.gz" + +static const char dictionary[] = "hello"; +static unsigned long dictId = 0; /* Adler32 value of the dictionary */ + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + + +void test_compress (unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen); +void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen); +void test_deflate (unsigned char *compr, size_t comprLen); +void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params); +void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_flush (unsigned char *compr, z_uintmax_t *comprLen); +void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_dict_deflate (unsigned char *compr, size_t comprLen); +void test_dict_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +int main (int argc, char *argv[]); + + +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *format, ...) { + va_list va; + + va_start(va, format); + vfprintf(stderr, format, va); + va_end(va); + + exit(1); +} + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) \ + error("%s error: %d\n", msg, err); \ +} + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen) { + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + err = PREFIX(compress)(compr, &comprLen, (const unsigned char*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) + error("bad uncompress\n"); + else + printf("uncompress(): %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + size_t read; + size_t len = strlen(hello)+1; + gzFile file; + z_off64_t pos; + z_off64_t comprLen; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(fname, "wb"); + if (file == NULL) + error("gzopen error\n"); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + if (PREFIX(gzputs)(file, "ello") != 4) + error("gzputs err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8) + error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err)); + /* Write string null-teriminator using gzseek */ + if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0) + error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file)); + /* Write hello, hello! using gzfwrite using best compression level */ + if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) + error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzfwrite)(hello, len, 1, file) == 0) + error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err)); + /* Flush compressed bytes to file */ + if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK) + error("gzflush err: %s\n", PREFIX(gzerror)(file, &err)); + comprLen = PREFIX(gzoffset)(file); + if (comprLen <= 0) + error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(fname, "rb"); + if (file == NULL) + error("gzopen error\n"); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len)) + error("gzread err: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello)) + error("bad gzread: %s\n", (char*)uncompr); + else + printf("gzread(): %s\n", (char*)uncompr); + /* Check position at the end of the gz file */ + if (PREFIX(gzeof)(file) != 1) + error("gzeof err: not reporting end of stream\n"); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + if (pos != 6 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + if (PREFIX(gzgetc)(file) != ' ') + error("gzgetc error\n"); + if (PREFIX(gzungetc)(' ', file) != ' ') + error("gzungetc error\n"); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) /* " hello!" */ + error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello + 6)) + error("bad gzgets after gzseek\n"); + else + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + if (pos != 14 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + /* Check position not at end of file */ + if (PREFIX(gzeof)(file) != 0) + error("gzeof err: reporting end of stream\n"); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file); + if (strcmp((const char *)uncompr, hello) != 0) + error("bad gzgets\n"); + else + printf("gzgets(): %s\n", (char*)uncompr); + pos = PREFIX(gzoffset)(file); + if (pos < 0 || pos != (comprLen + 10)) + error("gzoffset err: wrong offset at end\n"); + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + if (err == 0) + error("gzerror err: no error returned\n"); + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + if (err != 0) + error("gzclearerr err: not zero %d\n", err); + + PREFIX(gzclose)(file); + + if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR) + error("gzclose unexpected return when handle null\n"); + Z_UNUSED(read); +#endif +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) + error("bad inflate\n"); + else + printf("inflate(): %s\n", (char *)uncompr); +} + +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) + error("deflate not greedy\n"); + + /* Feed in already compressed data and switch to no compression: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_BEST_SPEED) + error("Expected compression level Z_BEST_SPEED, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + } + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_NO_COMPRESSION) + error("Expected compression level Z_NO_COMPRESSION, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + } + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + diff) + error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + else + printf("large_inflate(): OK\n"); +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_uintmax_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +#ifdef ZLIBNG_ENABLE_TESTS +/* =========================================================================== + * Test inflateSync() + * We expect a certain compressed block layout, so skip this with the original zlib. + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen-2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("inflate should report Z_STREAM_END\n"); + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} +#endif + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.adler = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + uint8_t check_dictionary[MAX_DICTIONARY_SIZE]; + uint32_t check_dictionary_len = 0; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + d_stream.adler = 0; + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) + error("unexpected dictionary"); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (check_dictionary_len < sizeof(dictionary)) + error("bad dictionary length\n"); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0) + error("bad dictionary\n"); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strncmp((char*)uncompr, hello, sizeof(hello))) + error("bad inflate with dict\n"); + else + printf("inflate with dictionary: %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflateBound() with small buffers + */ +void test_deflate_bound(void) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + int estimateLen = 0; + unsigned char *outBuf = NULL; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + c_stream.avail_in = len; + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_out = 0; + c_stream.next_out = outBuf; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + /* calculate actual output length and update structure */ + estimateLen = PREFIX(deflateBound)(&c_stream, len); + outBuf = malloc(estimateLen); + + if (outBuf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimateLen; + c_stream.next_out = outBuf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) { + printf("deflateBound(): OK\n"); + } else { + CHECK_ERR(err, "deflate"); + } + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(outBuf); +} + +/* =========================================================================== + * Test deflateCopy() with small buffers + */ +void test_deflate_copy(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + CHECK_ERR(err, "deflate_copy"); + + if (c_stream.state->status == c_stream_copy.state->status) { + printf("deflate_copy(): OK\n"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd original"); + + err = PREFIX(deflateEnd)(&c_stream_copy); + CHECK_ERR(err, "deflateEnd copy"); +} + +/* =========================================================================== + * Test deflateGetDictionary() with small buffers + */ +void test_deflate_get_dict(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned char *dictNew = NULL; + unsigned int *dictLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + + dictNew = calloc(256, 1); + dictLen = (unsigned int *)calloc(4, 1); + err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen); + + CHECK_ERR(err, "deflateGetDictionary"); + if (err == Z_OK) { + printf("deflateGetDictionary(): %s\n", dictNew); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(dictNew); + free(dictLen); +} + +/* =========================================================================== + * Test deflatePending() with small buffers + */ +void test_deflate_pending(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int *bits = calloc(256, 1); + unsigned *ped = calloc(256, 1); + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + CHECK_ERR(err, "deflatePending"); + + if (*bits >= 0 && *bits <= 7) { + printf("deflatePending(): OK\n"); + } else { + printf("deflatePending(): error\n"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(bits); + free(ped); +} + +/* =========================================================================== + * Test deflatePrime() wrapping gzip around deflate stream + */ +void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + PREFIX3(stream) d_stream; /* decompression stream */ + int err; + size_t len = strlen(hello)+1; + uint32_t crc = 0; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + CHECK_ERR(err, "deflatePrime"); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + CHECK_ERR(err, "deflatePrime"); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + CHECK_ERR(err, "deflatePrime"); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + CHECK_ERR(err, "deflatePrime"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)comprLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + CHECK_ERR(err, "deflate"); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len); + err = deflate_prime_32(&c_stream, crc); + CHECK_ERR(err, "deflatePrime"); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)len); + CHECK_ERR(err, "deflatePrime"); + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncomprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + CHECK_ERR(err, "inflateInit"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_BUF_ERROR) { + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((const char *)uncompr, hello) != 0) + error("bad deflatePrime\n"); + if (err == Z_OK) + printf("deflatePrime(): OK\n"); +} + +/* =========================================================================== + * Test deflateSetHeader() with small buffers + */ +void test_deflate_set_header(unsigned char *compr, size_t comprLen) { + PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header))); + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + + if (head == NULL) + error("out of memory\n"); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + CHECK_ERR(err, "deflateSetHeader"); + if (err == Z_OK) { + printf("deflateSetHeader(): OK\n"); + } + PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(head); +} + +/* =========================================================================== + * Test deflateTune() with small buffers + */ +void test_deflate_tune(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain); + CHECK_ERR(err, "deflateTune"); + if (err == Z_OK) { + printf("deflateTune(): OK\n"); + } + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ +int main(int argc, char *argv[]) { + unsigned char *compr, *uncompr; + z_uintmax_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + z_uintmax_t uncomprLen = comprLen; + static const char* myVersion = PREFIX2(VERSION); + + if (zVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zVersion(), PREFIX2(VERSION)) != 0) { + fprintf(stderr, "warning: different zlib version linked: %s\n", zVersion()); + } + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); + + compr = (unsigned char*)calloc((unsigned int)comprLen, 1); + uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == NULL || uncompr == NULL) + error("out of memory\n"); + + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + +#ifndef ZLIB_COMPAT + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); +#endif + + test_flush(compr, &comprLen); +#ifdef ZLIBNG_ENABLE_TESTS + test_sync(compr, comprLen, uncompr, uncomprLen); +#endif + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + test_deflate_bound(); + test_deflate_copy(compr, comprLen); + test_deflate_get_dict(compr, comprLen); + test_deflate_set_header(compr, comprLen); + test_deflate_tune(compr, comprLen); + test_deflate_pending(compr, comprLen); + test_deflate_prime(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/CMakeLists.txt new file mode 100644 index 000000000..27a04c0e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.5.1) + +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + enable_language(CXX) + + if(DEFINED ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE_FOUND ON) + else() + find_library(FUZZING_ENGINE "FuzzingEngine") + endif() +endif() + +set(FUZZERS + fuzzer_checksum + fuzzer_compress + fuzzer_example_small + fuzzer_example_large + fuzzer_example_flush + fuzzer_example_dict + ) + +if(WITH_GZFILEOP) + list(APPEND FUZZERS fuzzer_minigzip) +endif() + +foreach(FUZZER ${FUZZERS}) + add_executable(${FUZZER} ${FUZZER}.c) + + if(NOT FUZZING_ENGINE_FOUND) + target_sources(${FUZZER} PRIVATE standalone_fuzz_target_runner.c) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(${FUZZER} zlibstatic) + else() + target_link_libraries(${FUZZER} zlib) + endif() + + if(FUZZING_ENGINE_FOUND) + target_link_libraries(${FUZZER} ${FUZZING_ENGINE}) + endif() + + if(ZLIB_ENABLE_TESTS) + file(GLOB FUZZER_TEST_FILES ${PROJECT_SOURCE_DIR}/*) + set(FUZZER_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${FUZZER_TEST_FILES}) + add_test(NAME ${FUZZER} COMMAND ${FUZZER_COMMAND}) + endif() +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_checksum.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_checksum.c new file mode 100644 index 000000000..cedd284db --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_checksum.c @@ -0,0 +1,81 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + uint32_t crc0 = PREFIX(crc32)(0L, NULL, 0); + uint32_t crc1 = crc0; + uint32_t crc2 = crc0; + uint32_t adler0 = PREFIX(adler32)(0L, NULL, 0); + uint32_t adler1 = adler0; + uint32_t adler2 = adler0; + uint32_t combine1, combine2; + /* Checksum with a buffer of size equal to the first byte in the input. */ + uint32_t buffSize = data[0]; + uint32_t offset = 0; + uint32_t op; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + /* Make sure the buffer has at least a byte. */ + if (buffSize == 0) + ++buffSize; + + /* CRC32 */ + op = PREFIX(crc32_combine_gen)(buffSize); + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) { + uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize); + uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op); + crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize); + assert(crc1 == crc4); + Z_UNUSED(crc1); + Z_UNUSED(crc4); + } + crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize); + + crc2 = PREFIX(crc32_z)(crc2, data, dataLen); + + assert(crc1 == crc2); + Z_UNUSED(crc1); + Z_UNUSED(crc2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine)(crc1, crc1, (z_off_t)dataLen); + assert(combine1 == combine2); + + /* Fast CRC32 combine. */ + op = PREFIX(crc32_combine_gen)((z_off_t)dataLen); + combine1 = PREFIX(crc32_combine_op)(crc1, crc2, op); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + + /* Adler32 */ + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) + adler1 = PREFIX(adler32_z)(adler1, data + offset, buffSize); + adler1 = PREFIX(adler32_z)(adler1, data + offset, dataLen % buffSize); + + adler2 = PREFIX(adler32_z)(adler2, data, dataLen); + + assert(adler1 == adler2); + Z_UNUSED(adler1); + Z_UNUSED(adler2); + combine1 = PREFIX(adler32_combine)(adler1, adler2, (z_off_t)dataLen); + combine2 = PREFIX(adler32_combine)(adler1, adler1, (z_off_t)dataLen); + assert(combine1 == combine2); + Z_UNUSED(combine1); + Z_UNUSED(combine2); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_compress.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_compress.c new file mode 100644 index 000000000..71cdf99ec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_compress.c @@ -0,0 +1,82 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +static const uint8_t *data; +static size_t dataLen; + +static void check_compress_level(uint8_t *compr, z_size_t comprLen, + uint8_t *uncompr, z_size_t uncomprLen, + int level) { + PREFIX(compress2)(compr, &comprLen, data, dataLen, level); + PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + + /* Make sure compress + uncompress gives back the input data. */ + assert(dataLen == uncomprLen); + assert(0 == memcmp(data, uncompr, dataLen)); +} + +#define put_byte(s, i, c) {s[i] = (unsigned char)(c);} + +static void write_zlib_header(uint8_t *s) { + unsigned level_flags = 0; /* compression level (0..3) */ + unsigned w_bits = 8; /* window size log2(w_size) (8..16) */ + unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8; + header |= (level_flags << 6); + + header += 31 - (header % 31); + + /* s is guaranteed to be longer than 2 bytes. */ + put_byte(s, 0, (header >> 8)); + put_byte(s, 1, (header & 0xff)); +} + +static void check_decompress(uint8_t *compr, size_t comprLen) { + /* We need to write a valid zlib header of size two bytes. Copy the input data + in a larger buffer. Do not modify the input data to avoid libFuzzer error: + fuzz target overwrites its const input. */ + size_t copyLen = dataLen + 2; + uint8_t *copy = (uint8_t *)malloc(copyLen); + memcpy(copy + 2, data, dataLen); + write_zlib_header(copy); + + PREFIX(uncompress)(compr, &comprLen, copy, copyLen); + free(copy); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + /* compressBound does not provide enough space for low compression levels. */ + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + check_compress_level(compr, comprLen, uncompr, uncomprLen, 1); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 3); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 6); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 7); + + check_decompress(compr, comprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_dict.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_dict.c new file mode 100644 index 000000000..053a3e101 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_dict.c @@ -0,0 +1,164 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int dictionaryLen = 0; +static unsigned long dictId; /* Adler32 value of the dictionary */ + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char **compr, size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int level = data[0] % 11 - 1; /* [-1..9] + compression levels + #define Z_NO_COMPRESSION 0 + #define Z_BEST_SPEED 1 + #define Z_BEST_COMPRESSION 9 + #define Z_DEFAULT_COMPRESSION (-1) */ + + int method = Z_DEFLATED; /* The deflate compression method (the only one + supported in this version) */ + int windowBits = 8 + data[(dataLen > 1) ? 1:0] % 8; /* The windowBits parameter is the base + two logarithm of the window size (the size of the history buffer). It + should be in the range 8..15 for this version of the library. */ + int memLevel = 1 + data[(dataLen > 2) ? 2:0] % 9; /* memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. */ + int strategy = data[(dataLen > 3) ? 3:0] % 5; /* [0..4] + #define Z_FILTERED 1 + #define Z_HUFFMAN_ONLY 2 + #define Z_RLE 3 + #define Z_FIXED 4 + #define Z_DEFAULT_STRATEGY 0 */ + + /* deflate would fail for no-compression or for speed levels. */ + if (level == 0 || level == 1) + level = -1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit2)(&c_stream, level, method, windowBits, memLevel, + strategy); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)( + &c_stream, (const unsigned char *)data, dictionaryLen); + CHECK_ERR(err, "deflateSetDictionary"); + + /* deflateBound does not provide enough space for low compression levels. */ + *comprLen = 100 + 2 * PREFIX(deflateBound)(&c_stream, (unsigned long)dataLen); + *compr = (uint8_t *)calloc(1, *comprLen); + + dictId = c_stream.adler; + c_stream.next_out = *compr; + c_stream.avail_out = (unsigned int)(*comprLen); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.avail_in = (uint32_t)dataLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate dict should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + unsigned char *uncompr; + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + uncompr = (uint8_t *)calloc(1, dataLen); + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)dataLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = PREFIX(inflateSetDictionary)( + &d_stream, (const unsigned char *)data, dictionaryLen); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } + + free(uncompr); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 0; + uint8_t *compr; + + /* Discard inputs larger than 100Kb. */ + static size_t kMaxSize = 100 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + + /* Set up the contents of the dictionary. The size of the dictionary is + intentionally selected to be of unusual size. To help cover more corner + cases, the size of the dictionary is read from the input data. */ + dictionaryLen = data[0]; + if (dictionaryLen > dataLen) + dictionaryLen = (unsigned int)dataLen; + + test_dict_deflate(&compr, &comprLen); + test_dict_inflate(compr, comprLen); + + free(compr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_flush.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_flush.c new file mode 100644 index 000000000..baa6988e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_flush.c @@ -0,0 +1,119 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate flush 1"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate flush 2"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen - 2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "inflate should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + // This test requires at least 3 bytes of input data. + if (size <= 3 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_large.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_large.c new file mode 100644 index 000000000..411459721 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_large.c @@ -0,0 +1,137 @@ +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 1"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 2"); + + /* Switch back to compressing mode: */ + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 3"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate large should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2 * uncomprLen + diff) { + fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 100 + 3 * size; + size_t uncomprLen = comprLen; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 512Kb. */ + static size_t kMaxSize = 512 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_small.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_small.c new file mode 100644 index 000000000..e59c72083 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_example_small.c @@ -0,0 +1,118 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned long len = (unsigned long)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate small 1"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "deflate small 2"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = PREFIX(compressBound)(size); + size_t uncomprLen = size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_minigzip.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_minigzip.c new file mode 100644 index 000000000..819148d2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/fuzzer_minigzip.c @@ -0,0 +1,325 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 /* read buffer size */ +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static const char *prog = "minigzip_fuzzer"; + +void error (const char *msg); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode); +void file_uncompress (char *file); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + /* Clear out the contents of buf before reading from the file to avoid + MemorySanitizer: use-of-uninitialized-value warnings. */ + memset(buf, 0, sizeof(buf)); + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) error(PREFIX(gzerror)(out, &err)); + } + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int err; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(PREFIX(gzerror)(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char buf[BUFLENW]; + int len; + int err; + + for (;;) { + len = PREFIX(gzread)(in, buf, sizeof(buf)); + if (len < 0) error (PREFIX(gzerror)(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + char *inFileName = "minigzip_fuzzer.out"; + char *outFileName = "minigzip_fuzzer.out.gz"; + char outmode[20]; + FILE *in; + char buf[BUFLEN]; + uint32_t offset = 0; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + in = fopen(inFileName, "wb"); + if (fwrite(data, 1, (unsigned)dataLen, in) != dataLen) + error("failed fwrite"); + if (fclose(in)) + error("failed fclose"); + + memset(outmode, 0, sizeof(outmode)); + snprintf(outmode, sizeof(outmode), "%s", "wb"); + + /* Compression level: [0..9]. */ + outmode[2] = '0' + (data[0] % 10); + + switch (data[dataLen-1] % 6) { + default: + case 0: + outmode[3] = 0; + break; + case 1: + /* compress with Z_FILTERED */ + outmode[3] = 'f'; + break; + case 2: + /* compress with Z_HUFFMAN_ONLY */ + outmode[3] = 'h'; + break; + case 3: + /* compress with Z_RLE */ + outmode[3] = 'R'; + break; + case 4: + /* compress with Z_FIXED */ + outmode[3] = 'F'; + break; + case 5: + /* direct */ + outmode[3] = 'T'; + break; + } + + file_compress(inFileName, outmode); + + /* gzopen does not support reading in direct mode */ + if (outmode[3] == 'T') + inFileName = outFileName; + else + file_uncompress(outFileName); + + /* Check that the uncompressed file matches the input data. */ + in = fopen(inFileName, "rb"); + if (in == NULL) { + perror(inFileName); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + for (;;) { + int len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) + break; + assert(0 == memcmp(data + offset, buf, len)); + offset += len; + } + + if (fclose(in)) + error("failed fclose"); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/standalone_fuzz_target_runner.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/standalone_fuzz_target_runner.c new file mode 100644 index 000000000..810a56072 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/fuzz/standalone_fuzz_target_runner.c @@ -0,0 +1,37 @@ +#include +#include + +#include "zbuild.h" + +extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); + +int main(int argc, char **argv) { + int i; + fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1); + + for (i = 1; i < argc; i++) { + size_t len, n_read, err; + unsigned char *buf; + FILE *f = fopen(argv[i], "rb+"); + if (!f) { + /* Failed to open this file: it may be a directory. */ + fprintf(stderr, "Skipping: %s\n", argv[i]); + continue; + } + fprintf(stderr, "Running: %s %s\n", argv[0], argv[i]); + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + buf = (unsigned char *)malloc(len); + n_read = fread(buf, 1, len, f); + assert(n_read == len); + LLVMFuzzerTestOneInput(buf, len); + free(buf); + err = fclose(f); + assert(err == 0); + Z_UNUSED(err); + fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/gh1235.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/gh1235.c new file mode 100644 index 000000000..7bf8738f3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/gh1235.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "zutil.h" + +int main(void) { + unsigned char plain[32]; + unsigned char compressed[130]; + PREFIX3(stream) strm; + z_size_t bound; + z_size_t bytes; + + for (int i = 0; i <= 32; i++) { + memset(plain, 6, i); + memset(&strm, 0, sizeof(strm)); + PREFIX(deflateInit2)(&strm, 0, 8, 31, 1, Z_DEFAULT_STRATEGY); + bound = PREFIX(deflateBound)(&strm, i); + strm.next_in = plain; + strm.next_out = compressed; + strm.avail_in = i; + strm.avail_out = sizeof(compressed); + if (PREFIX(deflate)(&strm, Z_FINISH) != Z_STREAM_END) return -1; + if (strm.avail_in != 0) return -1; + printf("bytes = %2i, deflateBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)strm.total_out); + if (bound < strm.total_out) return -1; + if (PREFIX(deflateEnd)(&strm) != Z_OK) return -1; + } + for (int i = 0; i <= 32; i++) { + bytes = sizeof(compressed); + for (int j = 0; j < i; j++) { + plain[j] = j; + } + bound = PREFIX(compressBound)(i); + if (PREFIX(compress2)(compressed, &bytes, plain, i, 1) != Z_OK) return -1; + printf("bytes = %2i, compressBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)bytes); + if (bytes > bound) return -1; + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/infcover.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/infcover.c new file mode 100644 index 000000000..6606d222a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/infcover.c @@ -0,0 +1,686 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#undef NDEBUG +#include +#include + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + PREFIX3(stream) strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +static void *mem_alloc(void *mem, unsigned count, unsigned size) { + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +static void mem_free(void *mem, void *ptr) { + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +static void mem_setup(PREFIX3(stream) *strm) { + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +static void mem_limit(PREFIX3(stream) *strm, size_t limit) { + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +static void mem_used(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " allocated\n", prefix, (uint64_t)zone->total); +} + +/* show the high water allocation in bytes */ +static void mem_high(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " high water mark\n", prefix, (uint64_t)zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +static void mem_done(PREFIX3(stream) *strm, char *prefix) { + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %" PRIu64 " bytes in %d blocks not freed\n", + prefix, (uint64_t)zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = NULL; + strm->zalloc = NULL; + strm->zfree = NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can be delimited by any non-hex character, + where the delimiters are ignored except when a single hex digit is followed + by a delimiter, where that single digit writes a byte. The returned data is + allocated and must eventually be freed. NULL is returned if out of memory. + If the length is not needed, then len can be NULL. */ +static unsigned char *h2b(const char *hex, unsigned *len) { + unsigned char *in, *re; + unsigned next, val; + size_t inlen; + + inlen = (strlen(hex) + 1) >> 1; + assert(inlen != 0); /* tell static analyzer we won't call malloc(0) */ + in = malloc(inlen); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + assert(next != 0); /* tell static analyzer we won't call realloc(in, 0) */ + re = realloc(in, next); + return re == NULL ? in : re; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err) { + int ret; + unsigned have; + unsigned char *in, *out; + PREFIX3(stream) strm, copy; + PREFIX(gz_header) head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = PREFIX(inflateGetHeader)(&strm, &head); + assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = PREFIX(inflateSetDictionary)(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_OK); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(ret == Z_BUF_ERROR); + } + ret = PREFIX(inflateCopy)(©, &strm); + assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = PREFIX(inflateReset2)(&strm, -8); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, what); + Z_UNUSED(err); +} + +/* cover all of the lines in inflate.c up to inflate() */ +static void cover_support(void) { + int ret; + PREFIX3(stream) strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = PREFIX(inflatePrime)(&strm, 5, 31); assert(ret == Z_OK); + ret = PREFIX(inflatePrime)(&strm, -1, 0); assert(ret == Z_OK); + ret = PREFIX(inflateSetDictionary)(&strm, NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + +#ifdef ZLIB_COMPAT + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit_)(&strm, &PREFIX2(VERSION)[1], (int)sizeof(PREFIX3(stream))); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); +#endif + + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +static void cover_wrap(void) { + int ret; + PREFIX3(stream) strm, copy; + unsigned char dict[257]; + + ret = PREFIX(inflate)(NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(NULL); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateCopy)(NULL, NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = PREFIX(inflateSetDictionary)(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = PREFIX(inflatePrime)(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_DATA_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_OK); + (void)PREFIX(inflateSyncPoint)(&strm); + ret = PREFIX(inflateCopy)(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = PREFIX(inflateUndermine)(&strm, 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + assert(ret == Z_OK); +#else + assert(ret == Z_DATA_ERROR); +#endif + (void)PREFIX(inflateMark)(&strm); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +static unsigned pull(void *desc, z_const unsigned char **buf) { + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((PREFIX3(stream) *)desc)->state; + if (state != NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +static int push(void *desc, unsigned char *buf, unsigned len) { + buf += len; + Z_UNUSED(buf); + return desc != NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +static void cover_back(void) { + int ret; + PREFIX3(stream) strm; + unsigned char win[32768]; + +#ifdef ZLIB_COMPAT + ret = PREFIX(inflateBackInit_)(NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); +#endif + + ret = PREFIX(inflateBackInit)(NULL, 0, win); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBack)(NULL, NULL, NULL, NULL, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = PREFIX(inflateBack)(&strm, pull, &strm, push, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +static int try(char *hex, char *id, int err) { + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + PREFIX3(stream) strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateEnd)(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret != Z_STREAM_ERROR); + if (err && ret != Z_BUF_ERROR) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateBackEnd)(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +static void cover_inflate(void) { + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 0); +#else + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); +#endif + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +static void cover_trees(void) { + int ret; + unsigned bits; + uint16_t lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (uint16_t)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); + Z_UNUSED(ret); +} + +/* cover remaining inffast.c decoding and window copying */ +static void cover_fast(void) { + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +static void cover_cve_2022_37434(void) { + inf("1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51", "wtf", 13, 47, 12, Z_OK); +} + +int main(void) { + fprintf(stderr, "%s\n", zVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + cover_cve_2022_37434(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/minideflate.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/minideflate.c new file mode 100644 index 000000000..987e6121b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/minideflate.c @@ -0,0 +1,359 @@ +/* minideflate.c -- test deflate/inflate under specific conditions + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#include +#include + +#include "zutil.h" + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +# ifdef _MSC_VER +# define strcasecmp _stricmp +# endif +#else +# include +# define SET_BINARY_MODE(file) +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +/* Default read/write i/o buffer size based on GZBUFSIZE */ +#define BUFSIZE 131072 + +/* =========================================================================== + * deflate() using specialized parameters + */ +void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t level, + int32_t window_bits, int32_t mem_level, int32_t strategy, int32_t flush) { + PREFIX3(stream) c_stream; /* compression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + c_stream.zalloc = NULL; + c_stream.zfree = NULL; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + + err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy); + CHECK_ERR(err, "deflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + c_stream.next_in = (z_const uint8_t *)read_buf; + c_stream.avail_in = read; + + do { + err = PREFIX(deflate)(&c_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + } while (c_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + c_stream.avail_in = 0; + do { + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (c_stream.next_out != write_buf) { + fwrite(write_buf, 1, c_stream.next_out - write_buf, fout); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(read_buf); + free(write_buf); +} + +/* =========================================================================== + * inflate() using specialized parameters + */ +void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t window_bits, + int32_t flush) { + PREFIX3(stream) d_stream; /* decompression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + d_stream.zalloc = NULL; + d_stream.zfree = NULL; + d_stream.opaque = (void *)0; + d_stream.total_in = 0; + d_stream.total_out = 0; + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + + err = PREFIX(inflateInit2)(&d_stream, window_bits); + CHECK_ERR(err, "inflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + d_stream.next_in = (z_const uint8_t *)read_buf; + d_stream.avail_in = read; + + do { + err = PREFIX(inflate)(&d_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + } while (d_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + d_stream.avail_in = 0; + do { + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (d_stream.next_out != write_buf) { + fwrite(write_buf, 1, d_stream.next_out - write_buf, fout); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + free(read_buf); + free(write_buf); +} + +void show_help(void) { + printf("Usage: minideflate [-c][-d][-k] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input file\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -m : memory level (1 to 8)\n" \ + " -w : window bits..\n" \ + " : -1 to -15 for raw deflate\n" + " : 0 to 15 for deflate (adler32)\n" + " : 16 to 31 for gzip (crc32)\n" + " -s : flush type (0 to 5)\n" \ + " -r : read buffer size\n" \ + " -t : write buffer size\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char **argv) { + int32_t i; + int32_t mem_level = DEF_MEM_LEVEL; + int32_t window_bits = INT32_MAX; + int32_t strategy = Z_DEFAULT_STRATEGY; + int32_t level = Z_DEFAULT_COMPRESSION; + int32_t read_buf_size = BUFSIZE; + int32_t write_buf_size = BUFSIZE; + int32_t flush = Z_NO_FLUSH; + uint8_t copyout = 0; + uint8_t uncompr = 0; + uint8_t keep = 0; + FILE *fin = stdin; + FILE *fout = stdout; + + + if (argc == 1) { + show_help(); + return 64; /* EX_USAGE */ + } + + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc)) + mem_level = atoi(argv[++i]); + else if ((strcmp(argv[i], "-w") == 0) && (i + 1 < argc)) + window_bits = atoi(argv[++i]); + else if ((strcmp(argv[i], "-r") == 0) && (i + 1 < argc)) + read_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-t") == 0) && (i + 1 < argc)) + write_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-s") == 0) && (i + 1 < argc)) + flush = atoi(argv[++i]); + else if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-f") == 0) + strategy = Z_FILTERED; + else if (strcmp(argv[i], "-F") == 0) + strategy = Z_FIXED; + else if (strcmp(argv[i], "-h") == 0) + strategy = Z_HUFFMAN_ONLY; + else if (strcmp(argv[i], "-R") == 0) + strategy = Z_RLE; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i][1] - '0'; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else + break; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + if (i != argc) { + fin = fopen(argv[i], "rb+"); + if (fin == NULL) { + fprintf(stderr, "Failed to open file: %s\n", argv[i]); + exit(1); + } + if (!copyout) { + char *out_file = (char *)calloc(1, strlen(argv[i]) + 6); + if (out_file == NULL) { + fprintf(stderr, "Not enough memory\n"); + exit(1); + } + strcat(out_file, argv[i]); + if (!uncompr) { + if (window_bits < 0) { + strcat(out_file, ".zraw"); + } else if (window_bits > MAX_WBITS) { + strcat(out_file, ".gz"); + } else { + strcat(out_file, ".z"); + } + } else { + char *out_ext = strrchr(out_file, '.'); + if (out_ext != NULL) { + if (strcasecmp(out_ext, ".zraw") == 0 && window_bits == INT32_MAX) { + fprintf(stderr, "Must specify window bits for raw deflate stream\n"); + exit(1); + } + *out_ext = 0; + } + } + fout = fopen(out_file, "wb"); + if (fout == NULL) { + fprintf(stderr, "Failed to open file: %s\n", out_file); + exit(1); + } + free(out_file); + } + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (uncompr) { + inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush); + } else { + deflate_params(fin, fout, read_buf_size, write_buf_size, level, window_bits, mem_level, strategy, flush); + } + + if (fin != stdin) { + fclose(fin); + if (!copyout && !keep) { + unlink(argv[i]); + } + } + if (fout != stdout) { + fclose(fout); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/minigzip.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/minigzip.c new file mode 100644 index 000000000..d55f5086b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/minigzip.c @@ -0,0 +1,378 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include + +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#ifndef BUFLEN +# define BUFLEN 16384 /* read buffer size */ +#endif +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static char *prog; + +void error (const char *msg); +void gz_fatal (gzFile file); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode, int keep); +void file_uncompress (char *file, int keep); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Display last error message of gzFile, close it and exit + */ + +void gz_fatal(gzFile file) { + int err; + fprintf(stderr, "%s: %s\n", prog, PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char *buf; + int len; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + buf = (char *)calloc(BUFLEN, 1); + if (buf == NULL) { + perror("out of memory"); + exit(1); + } + + for (;;) { + len = (int)fread(buf, 1, BUFLEN, in); + if (ferror(in)) { + free(buf); + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) gz_fatal(out); + } + free(buf); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, buf, (unsigned)buf_len); + + if (len != (int)buf_len) gz_fatal(out); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char *buf = (char *)malloc(BUFLENW); + int len; + + if (buf == NULL) error("out of memory"); + + for (;;) { + len = PREFIX(gzread)(in, buf, BUFLENW); + if (len < 0) { + free(buf); + gz_fatal(in); + } + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + free(buf); + error("failed fwrite"); + } + } + free(buf); + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode, int keep) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + if (!keep) + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file, int keep) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + if (!keep) + unlink(infile); +} + +void show_help(void) { + printf("Usage: minigzip [-c] [-d] [-k] [-f|-h|-R|-F|-T] [-A] [-0 to -9] [files...]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input files\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -T : stored raw\n" \ + " -A : auto detect type\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char *argv[]) { + int copyout = 0; + int uncompr = 0; + int keep = 0; + int i = 0; + gzFile file; + char *bname, outmode[20]; + char *strategy = ""; + char *level = "6"; + char *type = "b"; + + prog = argv[i]; + bname = strrchr(argv[i], '/'); + if (bname) + bname++; + else + bname = argv[i]; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-A") == 0) + type = ""; + else if (argv[i][0] == '-' && (argv[i][1] == 'f' || argv[i][1] == 'h' || + argv[i][1] == 'R' || argv[i][1] == 'F' || argv[i][1] == 'T') && argv[i][2] == 0) + strategy = argv[i] + 1; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i] + 1; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else { + break; + } + } + + snprintf(outmode, sizeof(outmode), "w%s%s%s", type, strategy, level); + + if (i == argc) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = PREFIX(gzdopen)(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = PREFIX(gzopen)(argv[i], "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, argv[i]); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(argv[i], keep); + } + } else { + if (copyout) { + FILE * in = fopen(argv[i], "rb"); + + if (in == NULL) { + perror(argv[i]); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(argv[i], outmode, keep); + } + } + } while (++i < argc); + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/pigz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/test/pigz/CMakeLists.txt new file mode 100644 index 000000000..bc6830ae2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/pigz/CMakeLists.txt @@ -0,0 +1,211 @@ +# CMakeLists.txt -- Build madler/pigz against zlib variant + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# By default pigz will be linked against the system zlib and +# pthread libraries if installed. + +# For compilation on Windows download and use shim: +# https://github.com/zlib-ng/pigzbench/tree/master/pigz/win + +# Optional Variables +# WITH_CODE_COVERAGE - Enable code coverage reporting +# WITH_THREADS - Enable threading support +# PIGZ_ENABLE_TESTS - Enable adding unit tests +# PIGZ_VERSION - Set the version of pigz to build +# ZLIB_ROOT - Path to the zlib source directory +# PTHREADS4W_ROOT - Path to pthreads4w source directory on Windows. +# If not specified then threading will be disabled. + +cmake_minimum_required(VERSION 3.11) + +include(CheckCCompilerFlag) +include(FeatureSummary) +include(FetchContent) + +include(../../cmake/detect-coverage.cmake) + +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_THREADS "Enable threading support" ON) +option(PIGZ_ENABLE_TESTS "Build unit tests" ON) +option(PIGZ_VERSION "Set the version of pigz to build" "") + +project(pigz LANGUAGES C) + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Compiler definitions +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_definitions(-fno-caret-diagnostics) +elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5.0) + add_definitions(-Wno-unused-result) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8.0) + add_definitions(-fno-diagnostics-show-caret) + endif() +elseif(WIN32) + add_definitions(-D_TIMESPEC_DEFINED) + if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + endif() +endif() + +# Fetch pigz source code from official repository +if(PIGZ_VERSION STREQUAL "") + set(PIGZ_TAG master) +else() + set(PIGZ_TAG ${PIGZ_VERSION}) +endif() +FetchContent_Declare(pigz + GIT_REPOSITORY https://github.com/madler/pigz.git + GIT_TAG ${PIGZ_TAG}) + +FetchContent_GetProperties(pigz) +if(NOT pigz_POPULATED) + FetchContent_Populate(pigz) +endif() + +set(PIGZ_SRCS + ${pigz_SOURCE_DIR}/pigz.c + ${pigz_SOURCE_DIR}/try.c) + +set(PIGZ_HDRS + ${pigz_SOURCE_DIR}/try.h) + +add_executable(${PROJECT_NAME} ${PIGZ_SRCS} ${PIGZ_HDRS}) +add_definitions(-DNOZOPFLI) +if(WIN32) + target_include_directories(${PROJECT_NAME} PRIVATE win) +endif() + +# Find and link against pthreads or pthreads4w +if(WITH_THREADS) + if(WIN32) + if(DEFINED PTHREADS4W_ROOT) + set(CLEANUP_STYLE VC) + set(PTHREADS4W_VERSION 3) + + add_subdirectory(${PTHREADS4W_ROOT} ${PTHREADS4W_ROOT} EXCLUDE_FROM_ALL) + target_link_libraries(${PROJECT_NAME} pthreadVC3) + target_include_directories(${PROJECT_NAME} PRIVATE ${PTHREADS4W_ROOT}) + else() + message(WARNING "Missing pthreads4w root directory") + set(WITH_THREADS OFF) + endif() + else() + find_package(Threads REQUIRED) + target_link_libraries(${PROJECT_NAME} Threads::Threads) + if(NOT APPLE) + target_link_libraries(${PROJECT_NAME} m) + endif() + endif() +endif() + +# Disable threading support +if(NOT WITH_THREADS) + add_definitions(-DNOTHREAD) +else() + set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY SOURCES + ${pigz_SOURCE_DIR}/yarn.c + ${pigz_SOURCE_DIR}/yarn.h) +endif() + +# Find and link against zlib +if(NOT DEFINED ZLIB_ROOT) + find_package(Zlib REQUIRED) +endif() + +set(ZLIB_COMPAT ON) +set(ZLIB_ENABLE_TESTS OFF) + +add_subdirectory(${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib EXCLUDE_FROM_ALL) + +if(NOT DEFINED BUILD_SHARED_LIBS OR NOT BUILD_SHARED_LIBS) + set(ZLIB_TARGET zlibstatic) +else() + set(ZLIB_TARGET zlib) +endif() + +target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib) +target_link_libraries(${PROJECT_NAME} ${ZLIB_TARGET}) + +if(NOT SKIP_INSTALL_BINARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${PROJECT_NAME} DESTINATION "bin") +endif() + +# Add unit tests +if(PIGZ_ENABLE_TESTS) + enable_testing() + + set(PIGZ_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + + macro(test_pigz name path) + # Construct compression arguments for pigz + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id pigz-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${PIGZ_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/compress-and-verify.cmake) + endif() + endmacro() + + set(TEST_CONFIGS + -U # RLE compression + #-H # Z_HUFFMAN_ONLY (broken in 2.6) + -0 # No compression + -1 # Deflate quick + -4 # Deflate medium (lazy matches) + -6 # Deflate medium + -9 # Deflate slow + ) + + file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) + + foreach(TEST_FILE_PATH ${TEST_FILE_PATHS}) + if("${TEST_FILE_PATH}" MATCHES ".gz$" OR "${TEST_FILE_PATH}" MATCHES ".out$" OR + "${TEST_FILE_PATH}" MATCHES "/.git/" OR "${TEST_FILE_PATH}" MATCHES ".md$") + continue() + endif() + foreach(TEST_CONFIG ${TEST_CONFIGS}) + get_filename_component(TEST_NAME ${TEST_FILE_PATH} NAME) + if (TEST_NAME STREQUAL "") + continue() + endif() + test_pigz(${TEST_NAME} ${TEST_FILE_PATH} ${TEST_CONFIG}) + endforeach() + endforeach() + + set(GH979_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + -d -k -f ${CMAKE_CURRENT_SOURCE_DIR}/../GH-979/pigz-2.6.tar.gz) + add_test(NAME GH-979 COMMAND ${GH979_COMMAND}) +endif() + +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_THREADS WITH_THREADS "Enable threading support") +add_feature_info(PIGZ_ENABLE_TESTS PIGZ_ENABLE_TESTS "Build unit tests") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/pkgcheck.sh b/internal-complibs/zlib-ng-2.1.1-beta2/test/pkgcheck.sh new file mode 100644 index 000000000..87a4e61ef --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/pkgcheck.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +usage() { + cat <<"_EOF_" +Usage: sh test/pkgcheck.sh [--zlib-compat] + +Verifies that the various build systems produce identical results on a Unixlike system. +If --zlib-compat, tests with zlib compatible builds. + +To build the 32 bit version for the current 64 bit arch: + +$ sudo apt install ninja-build diffoscope gcc-multilib +$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-m32" CFLAGS=-m32 LDFLAGS=-m32 +$ sh test/pkgcheck.sh + +To cross-build, install the appropriate qemu and gcc packages, +and set the environment variables used by configure or cmake. +On Ubuntu, for example (values taken from .github/workflows/pkgconf.yml): + +arm HF: +$ sudo apt install ninja-build diffoscope qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross +$ export CHOST=arm-linux-gnueabihf +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +aarch64: +$ sudo apt install ninja-build diffoscope qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross +$ export CHOST=aarch64-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +ppc (32 bit big endian): +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross +$ export CHOST=powerpc-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake" + +ppc64le: +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross +$ export CHOST=powerpc64le-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake" + +then: +$ export CC=${CHOST}-gcc +$ sh test/pkgcheck.sh [--zlib-compat] + +Note: on Mac, you may also need to do 'sudo xcode-select -r' to get cmake to match configure/make's behavior (i.e. omit -isysroot). +_EOF_ +} + +set -ex + +# Caller can also set CMAKE_ARGS or CONFIGURE_ARGS if desired +CMAKE_ARGS="-DCMAKE_INSTALL_LIBDIR=lib ${CMAKE_ARGS}" +CONFIGURE_ARGS=${CONFIGURE_ARGS} + +case "$1" in +--zlib-compat) + suffix="" + CMAKE_ARGS="$CMAKE_ARGS -DZLIB_COMPAT=ON" + CONFIGURE_ARGS="$CONFIGURE_ARGS --zlib-compat" + ;; +"") + suffix="-ng" + ;; +*) + echo "Unknown arg '$1'" + usage + exit 1 + ;; +esac + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps +# Probably only needed on older systems (ubuntu 14.04, BSD?) +export SOURCE_DATE_EPOCH=0 +case $(uname) in +Darwin) + # Tell Apple's ar etc. to use zero timestamps + export ZERO_AR_DATE=1 + # What CPU are we running on, exactly? + sysctl -n machdep.cpu.brand_string + sysctl -n machdep.cpu.features + sysctl -n machdep.cpu.leaf7_features + sysctl -n machdep.cpu.extfeatures + ;; +esac + +# Use same compiler for make and cmake builds +if test "$CC"x = ""x +then + if clang --version + then + export CC=clang + elif gcc --version + then + export CC=gcc + fi +fi + +# New build system +# Happens to delete top-level zconf.h +# (which itself is a bug, https://github.com/madler/zlib/issues/162 ) +# which triggers another bug later in configure, +# https://github.com/madler/zlib/issues/499 +rm -rf btmp2 pkgtmp2 +mkdir btmp2 pkgtmp2 +export DESTDIR=$(pwd)/pkgtmp2 +cd btmp2 + cmake -G Ninja ${CMAKE_ARGS} .. + ninja -v + ninja install +cd .. + +# Original build system +rm -rf btmp1 pkgtmp1 +mkdir btmp1 pkgtmp1 +export DESTDIR=$(pwd)/pkgtmp1 +cd btmp1 + case $(uname) in + Darwin) + export LDFLAGS="-Wl,-headerpad_max_install_names" + ;; + esac + ../configure $CONFIGURE_ARGS + make -j2 + make install +cd .. + +repack_ar() { + if ! cmp --silent pkgtmp1/usr/local/lib/libz$suffix.a pkgtmp2/usr/local/lib/libz$suffix.a + then + echo "libz$suffix.a does not match. Probably filenames differ (.o vs .c.o). Unpacking and renaming..." + # Note: %% is posix shell syntax meaning "Remove Largest Suffix Pattern", see + # https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 + cd pkgtmp1; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; cd .. + cd pkgtmp2; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; for a in *.c.o; do mv $a ${a%%.c.o}.o; done; cd .. + # Also, remove __.SYMDEF SORTED if present, as it has those funky .c.o names embedded in it. + rm -f pkgtmp[12]/__.SYMDEF\ SORTED + fi +} + +case $(uname) in +Darwin) + # Remove the build uuid. + dylib1=$(find pkgtmp1 -type f -name '*.dylib*') + dylib2=$(find pkgtmp2 -type f -name '*.dylib*') + strip -x -no_uuid "$dylib1" + strip -x -no_uuid "$dylib2" + ;; +esac + +# The ar on newer systems defaults to -D (i.e. deterministic), +# but FreeBSD 12.1, Debian 8, and Ubuntu 14.04 seem to not do that. +# I had trouble passing -D safely to the ar inside CMakeLists.txt, +# so punt and unpack the archive if needed before comparing. +# Also, cmake uses different .o suffix anyway... +repack_ar + +if diff -Nur pkgtmp1 pkgtmp2 +then + echo pkgcheck-cmake-bits-identical PASS +else + echo pkgcheck-cmake-bits-identical FAIL + dylib1=$(find pkgtmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + dylib2=$(find pkgtmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + diffoscope $dylib1 $dylib2 | cat + exit 1 +fi + +rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +# any failure would have caused an early exit already +echo "pkgcheck: PASS" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/switchlevels.c b/internal-complibs/zlib-ng-2.1.1-beta2/test/switchlevels.c new file mode 100644 index 000000000..a065dbcff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/switchlevels.c @@ -0,0 +1,167 @@ +/* Compresses a user-specified number of chunks from stdin into stdout as a single gzip stream. + * Each chunk is compressed with a user-specified level. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +static int read_all(unsigned char *buf, size_t size) { + size_t total_read = 0; + while (total_read < size) { + size_t n_read = fread(buf + total_read, 1, size - total_read, stdin); + if (ferror(stdin)) { + perror("fread\n"); + return 1; + } + if (n_read == 0) { + fprintf(stderr, "Premature EOF\n"); + return 1; + } + total_read += n_read; + } + return 0; +} + +static int write_all(unsigned char *buf, size_t size) { + size_t total_written = 0; + while (total_written < size) { + size_t n_written = fwrite(buf + total_written, 1, size - total_written, stdout); + if (ferror(stdout)) { + perror("fwrite\n"); + return 1; + } + total_written += n_written; + } + return 0; +} + +static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last) { + int ret = 1; + int err = 0; + unsigned long compsize; + unsigned char *buf; + + if (size <= 0) { + fprintf(stderr, "compress_chunk() invalid size %d\n", size); + goto done; + } + if (level < 0 || level > 9) { + fprintf(stderr, "compress_chunk() invalid level %d\n", level); + goto done; + } + + compsize = PREFIX(deflateBound)(strm, size); + buf = malloc(size + compsize); + if (buf == NULL) { + fprintf(stderr, "Out of memory\n"); + goto done; + } + if (read_all(buf, size) != 0) { + goto free_buf; + } + + /* Provide only output buffer to deflateParams(). It might need some space to flush the leftovers from the last + * deflate(), but we don't want it to compress anything new. */ + strm->next_in = NULL; + strm->avail_in = 0; + strm->next_out = buf + size; + strm->avail_out = compsize; + err = PREFIX(deflateParams)(strm, level, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateParams() failed with code %d\n", err); + goto free_buf; + } + + /* Provide input buffer to deflate(). */ + strm->next_in = buf; + strm->avail_in = size; + err = PREFIX(deflate)(strm, last ? Z_FINISH : Z_SYNC_FLUSH); + if ((!last && err != Z_OK) || (last && err != Z_STREAM_END)) { + fprintf(stderr, "deflate() failed with code %d\n", err); + goto free_buf; + } + if (strm->avail_in != 0) { + fprintf(stderr, "deflate() did not consume %d bytes of input\n", strm->avail_in); + goto free_buf; + } + if (write_all(buf + size, compsize - strm->avail_out) != 0) { + goto free_buf; + } + ret = 0; + +free_buf: + free(buf); +done: + return ret; +} + +void show_help(void) +{ + printf("Usage: switchlevels [-w bits] level1 size1 [level2 size2 ...]\n\n" \ + " -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n\n"); +} + +int main(int argc, char **argv) { + int ret = EXIT_FAILURE; + int err = 0; + int size = 0; + int level = Z_DEFAULT_COMPRESSION; + int level_arg = 1; + int window_bits = MAX_WBITS + 16; + PREFIX3(stream) strm; + + + if ((argc == 1) || (argc == 2 && strcmp(argv[1], "--help") == 0)) { + show_help(); + return 0; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + memset(&strm, 0, sizeof(strm)); + + for (int i = 1; i < argc - 1; i++) { + if (strcmp(argv[i], "-w") == 0 && i+1 < argc) { + window_bits = atoi(argv[++i]); + } else { + level_arg = i; + level = atoi(argv[i]); + break; + } + } + + err = PREFIX(deflateInit2)(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateInit() failed with code %d\n", err); + goto done; + } + + for (int i = level_arg; i < argc - 1; i += 2) { + level = atoi(argv[i]); + size = atoi(argv[i + 1]); + if (compress_chunk(&strm, level, size, i + 2 >= argc - 1) != 0) { + goto deflate_end; + } + } + ret = EXIT_SUCCESS; + +deflate_end: + PREFIX(deflateEnd)(&strm); +done: + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_adler32.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_adler32.cc new file mode 100644 index 000000000..4dfe63f20 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_adler32.cc @@ -0,0 +1,386 @@ +/* test_adler32.c -- unit test for adler32 in the zlib compression library + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + uint32_t adler; + const uint8_t *buf; + uint32_t len; + uint32_t expect; +} adler32_test; + +static const uint8_t long_string[5552] = { + 'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q', + 'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k', + 'A','x','N','Q','R','k','d','V','5','y','n','U','N','W','Q','Y','i','W','5','9','R','p','D','C','x','p','u','h','C','a','m','r', + 'z','n','z','A','d','J','6','u','N','e','r','x','7','Q','3','v','V','h','H','S','H','S','f','K','f','e','E','T','9','J','f','K', + 'w','t','x','J','2','y','7','B','x','X','X','p','G','b','T','g','3','k','U','6','E','Z','M','t','J','q','v','n','S','T','6','x', + '5','x','4','P','z','p','M','F','V','b','d','m','f','G','n','J','m','w','z','K','8','a','q','E','D','e','b','3','h','B','V','g', + 'y','3','P','L','5','8','r','z','X','b','Q','g','H','7','L','c','Z','B','3','C','4','y','t','u','k','z','h','v','C','Y','p','p', + '8','H','v','5','X','w','4','L','R','V','V','4','U','C','8','4','T','E','a','N','Z','S','7','U','u','z','f','H','p','P','J','u', + 'Y','Z','h','T','6','e','v','z','V','F','h','u','y','H','b','k','J','M','f','3','6','g','y','L','E','W','t','B','B','d','d','9', + 'u','M','Z','k','F','G','f','h','q','k','5','k','f','r','M','7','c','M','7','y','n','u','8','b','d','7','Q','f','E','m','F','K', + 'x','W','f','B','2','F','8','5','q','z','y','3','R','i','U','m','X','k','h','N','J','y','B','C','h','u','x','4','f','k','J','5', + '6','X','T','W','h','8','J','4','m','K','p','N','3','g','C','g','A','E','e','Z','x','A','P','2','E','4','t','Q','5','X','Y','j', + '6','m','b','h','G','a','v','6','t','v','6','C','M','G','P','u','B','C','A','V','b','2','9','d','2','c','5','a','b','X','w','V', + 'G','6','a','7','c','8','G','6','K','U','Q','m','w','P','V','5','N','x','b','v','x','E','N','C','A','N','t','v','N','B','z','X', + 'B','R','q','U','n','i','A','Q','d','m','a','D','7','Y','f','3','J','8','Y','m','w','Z','b','w','r','H','q','E','j','c','u','E', + 'i','i','S','b','n','G','P','a','F','j','c','R','D','D','G','F','v','i','a','i','M','7','B','e','w','m','L','E','F','2','Y','4', + '4','7','Y','C','t','y','q','7','2','V','G','m','m','E','e','V','u','m','L','p','R','X','W','z','V','K','E','k','p','V','r','J', + 'd','N','3','t','i','u','S','V','w','2','w','U','Q','3','F','q','4','h','q','k','B','7','R','X','B','F','Q','Z','b','b','4','E', + 'K','v','T','B','w','k','V','C','x','d','K','g','N','S','u','k','p','9','z','w','c','y','U','M','V','E','2','Y','P','F','h','9', + 'T','y','h','w','b','9','P','w','G','c','W','W','k','j','J','Q','N','B','U','G','6','9','U','b','v','a','N','9','N','C','G','n', + 'x','R','6','9','Q','C','h','e','j','P','U','h','U','R','i','4','T','B','W','5','w','m','J','p','e','7','r','9','t','c','9','Z', + 'j','p','r','F','C','e','U','P','x','T','A','N','7','6','a','i','y','e','w','F','C','X','H','Y','G','C','q','q','m','A','t','7', + 'z','u','D','S','L','U','C','f','7','e','t','G','V','F','u','c','x','5','M','7','N','i','M','6','h','2','n','H','S','h','K','M', + 'd','T','z','X','d','x','x','4','q','z','d','D','a','2','X','r','p','r','R','m','U','U','y','S','H','c','a','F','e','Z','a','U', + 'P','9','V','J','e','q','j','Y','M','x','e','v','K','7','M','P','N','2','b','6','f','P','h','H','4','U','X','k','n','f','Q','M', + '9','9','a','J','N','e','w','y','f','F','P','p','a','F','Y','a','M','L','W','i','T','M','B','3','U','v','X','v','G','p','7','a', + 'f','u','4','S','y','X','9','g','g','b','B','G','c','i','M','U','n','m','a','7','q','f','9','n','Q','2','V','L','6','e','T','R', + '2','4','9','d','6','Q','B','Y','q','2','4','9','G','Q','E','b','Y','5','u','2','T','Q','G','L','5','n','4','Y','2','y','G','F', + 'j','c','8','M','G','L','e','3','a','N','v','A','A','W','t','R','S','2','i','D','R','8','j','d','Q','3','6','C','V','M','e','w', + 'j','U','Z','w','M','4','b','m','8','J','P','Q','L','P','R','c','r','b','V','C','3','N','8','K','4','d','W','D','N','U','A','A', + '2','J','p','b','D','d','p','j','N','C','k','A','j','B','a','c','u','v','L','X','U','B','4','U','X','W','e','C','b','C','u','d', + 'A','v','U','z','P','t','D','e','5','y','Y','c','x','K','4','7','j','e','e','D','M','5','K','B','Q','6','d','p','T','T','R','j', + 'M','E','E','M','r','N','6','8','7','q','x','F','S','x','E','U','4','d','B','6','5','W','C','e','m','J','e','5','j','w','V','J', + 'w','v','d','7','v','f','K','u','m','8','h','W','T','e','Q','j','M','8','R','Y','d','B','R','2','r','F','j','7','d','E','q','V', + 'k','e','j','P','9','3','X','R','p','R','b','A','v','7','4','A','M','2','k','r','E','7','X','3','7','k','5','c','B','7','W','5', + 'u','J','B','Q','R','2','V','7','h','Q','h','9','g','G','y','c','c','x','M','z','7','G','2','J','w','v','j','5','9','E','b','k', + 'z','W','T','C','b','4','K','R','X','T','k','V','S','G','2','j','d','6','y','E','4','P','H','K','w','a','m','F','Z','x','9','j', + 'i','2','d','X','u','a','4','a','M','z','8','p','p','z','g','t','H','5','Y','L','Q','c','R','F','m','E','n','G','X','d','f','7', + 'x','8','j','g','J','z','D','S','a','S','h','y','5','h','Y','N','p','w','Y','W','h','E','N','v','8','Q','D','W','Z','k','f','e', + 'r','Z','D','7','R','D','T','2','H','X','z','G','X','f','v','E','z','P','v','U','H','e','4','R','W','U','x','t','t','4','w','p', + 'r','z','K','9','f','g','h','P','r','f','v','k','h','c','e','5','8','a','L','F','J','M','G','R','a','N','q','S','g','W','e','7', + 'R','K','R','A','B','z','6','v','S','p','w','n','e','x','k','E','r','j','f','Y','x','8','9','z','e','T','6','E','G','v','9','f', + 'D','A','N','v','y','U','7','D','M','2','E','5','W','G','6','b','9','q','g','Y','F','f','k','q','Q','E','x','Y','C','R','G','6', + 'R','h','4','J','d','U','D','b','9','b','8','r','f','V','d','g','b','2','z','Z','d','m','X','v','j','Y','d','w','K','8','G','r', + 'v','j','N','y','c','h','u','5','z','g','J','H','a','Z','b','z','G','C','r','P','f','y','P','6','F','P','h','7','9','w','7','y', + 'R','3','n','E','h','G','D','4','m','Y','E','q','k','a','f','a','R','B','q','t','W','E','T','p','H','7','k','X','2','d','X','6', + 'W','n','H','m','w','M','i','Y','M','E','F','5','R','p','p','y','c','b','q','R','9','Y','t','T','7','w','u','K','M','Q','z','n', + 'P','7','g','x','6','R','4','x','N','v','w','M','6','j','K','v','7','a','Y','4','a','M','6','n','z','3','E','2','V','N','4','i', + 'E','f','u','W','J','W','e','8','3','Q','e','a','F','P','c','3','P','k','i','z','d','q','m','q','M','a','d','8','D','3','F','M', + 'e','d','E','j','z','V','e','d','z','H','D','J','8','X','g','E','i','u','c','7','A','w','S','J','2','A','e','8','r','q','C','m', + '9','9','a','g','2','y','y','P','M','e','8','3','T','r','m','8','j','v','r','p','M','Z','Y','g','a','9','2','d','H','B','m','9', + '4','6','a','Z','V','u','S','H','g','3','X','h','i','N','3','B','S','E','k','9','k','2','9','R','A','i','3','L','X','M','B','S', + '4','S','F','F','F','w','u','d','M','T','9','K','B','7','R','U','R','8','D','8','T','5','U','t','E','R','x','n','x','h','v','k', + 'B','N','k','E','U','T','t','p','r','u','Z','h','t','E','4','i','P','z','f','z','q','M','p','f','A','K','2','D','t','j','f','c', + 'Y','E','N','M','x','k','g','7','T','U','2','c','d','V','g','2','z','L','i','j','Y','q','b','T','A','y','v','a','t','N','5','t', + 'Z','5','n','D','a','y','G','n','P','x','V','k','M','8','t','J','Z','G','g','5','9','R','h','P','P','J','N','X','p','G','J','p', + '2','y','A','v','d','G','U','z','3','V','M','y','q','U','N','M','Y','p','B','Z','U','h','j','q','z','q','x','w','7','d','J','Q', + 'u','F','q','3','m','9','c','Q','W','d','6','7','b','V','M','7','P','j','r','k','9','h','R','z','m','b','i','B','u','E','L','9', + 'k','v','h','h','W','2','K','e','M','U','Q','p','A','Q','Y','J','G','E','T','U','L','f','q','G','4','z','K','K','y','a','U','W', + 'K','D','P','c','N','D','V','S','Y','6','T','p','R','y','y','J','a','T','J','W','Q','9','p','F','P','X','y','k','9','z','z','4', + 'G','d','a','z','X','n','h','4','J','P','W','V','D','r','U','m','a','8','a','b','X','F','J','X','L','4','S','X','5','W','p','W', + 'h','y','x','B','f','d','C','X','w','7','r','g','V','T','H','a','i','4','N','v','c','w','n','2','3','A','i','A','J','9','N','c', + 'z','7','n','n','3','n','h','n','i','R','i','b','E','h','k','U','c','c','U','6','f','x','q','N','y','H','M','e','J','B','U','B', + 'r','g','a','8','V','a','G','V','y','u','c','c','v','C','H','W','y','g','z','Q','2','4','k','S','m','f','e','G','H','v','Q','3', + 'P','e','f','S','V','P','c','U','e','3','P','x','d','c','7','c','f','g','D','w','2','t','q','y','g','2','Q','V','4','K','a','Q', + 'g','B','b','L','x','9','m','a','K','4','i','x','g','Q','M','9','W','N','2','w','p','v','2','k','B','y','9','k','A','c','f','Z', + 'D','R','A','S','d','v','w','f','f','q','t','K','3','j','x','D','G','P','n','u','r','v','U','k','A','2','d','R','N','T','G','4', + 'B','g','k','t','h','7','J','k','F','A','C','g','W','g','J','F','z','S','Q','c','v','M','b','D','e','H','Q','S','j','v','G','E', + 'R','k','f','i','P','E','F','N','6','y','p','b','t','M','c','Q','B','7','g','w','J','7','3','d','V','E','m','z','6','6','P','P', + 'd','i','r','J','H','D','H','J','r','b','n','v','z','W','e','u','g','B','u','Z','2','m','D','5','h','F','X','B','2','r','6','w', + 'u','Y','4','N','X','K','a','v','V','3','j','B','r','r','C','c','w','R','g','S','8','V','b','F','2','N','M','c','K','8','Y','E', + 'E','N','K','X','K','V','B','x','n','Q','p','a','q','f','k','t','z','Y','E','P','Z','y','n','a','c','B','V','a','x','b','d','X', + 'r','d','8','P','H','F','v','r','V','5','g','J','w','6','i','h','d','d','p','J','c','c','Y','S','q','W','m','U','5','G','b','H', + 'N','z','E','Z','K','E','y','M','c','G','i','d','w','Z','D','N','N','w','S','t','g','y','a','Y','b','H','e','M','N','f','Y','Y', + '7','a','9','b','M','U','k','a','V','k','C','n','a','k','U','H','A','M','i','v','k','t','a','d','i','3','F','d','5','2','A','p', + 'U','c','J','U','R','h','G','d','A','Y','v','q','X','c','w','r','x','4','j','3','4','b','F','d','a','L','N','J','3','Z','g','6', + 'W','Q','R','u','P','t','M','A','3','F','6','y','K','Y','G','2','t','v','u','p','w','b','G','S','K','5','p','4','d','E','w','6', + 'g','t','V','4','b','2','n','b','Z','3','3','f','m','d','2','c','a','m','j','X','U','E','D','6','6','F','w','H','9','7','Z','Y', + 'd','X','C','K','i','g','p','F','Y','n','2','b','F','4','R','u','V','k','f','d','J','i','a','b','X','H','7','v','K','a','Q','i', + 'W','M','j','M','i','a','i','n','F','h','r','q','4','w','x','m','4','q','y','F','8','w','i','4','D','B','A','L','B','U','u','K', + 'v','K','n','a','Q','i','e','k','v','Q','U','5','w','Q','c','r','A','6','M','w','y','g','n','e','v','K','7','W','u','2','y','f', + 'Q','u','e','r','y','a','w','V','p','f','Q','z','C','u','i','i','9','S','P','q','L','r','C','H','S','3','E','p','8','S','m','Q', + 'S','K','r','V','b','J','R','m','w','c','n','Q','N','Q','4','M','u','f','X','S','f','U','Z','x','U','4','j','K','4','G','z','X', + '7','Q','j','R','h','i','G','m','q','c','V','T','x','U','a','E','b','Q','q','E','i','F','K','7','K','i','R','J','5','Y','F','V', + 'B','7','R','8','M','i','f','j','Z','w','j','b','B','u','p','N','Y','r','S','r','f','h','E','J','T','B','P','R','D','V','K','A', + 'Z','A','R','j','z','f','B','i','Y','L','F','G','V','Y','w','R','C','P','G','m','9','7','C','5','e','y','w','N','K','N','a','Q', + 'j','a','W','3','2','f','G','w','n','M','6','F','u','K','8','g','8','M','G','r','e','9','Z','z','y','2','G','U','k','G','6','m', + 'A','D','4','n','b','8','a','q','S','m','S','6','5','R','5','D','5','S','B','g','X','T','8','Q','V','d','A','n','g','y','8','a', + 'h','7','K','9','H','D','J','F','w','G','4','w','T','J','F','f','i','8','X','e','B','J','K','H','7','V','y','X','7','E','8','S', + 'A','d','b','w','S','8','Y','a','J','d','j','E','V','J','T','E','U','R','5','7','V','M','E','v','D','3','z','5','r','k','z','v', + 'e','m','A','7','P','8','j','X','E','f','Q','q','8','D','g','y','8','j','A','e','B','c','c','M','z','k','2','c','q','v','v','y', + 'Q','y','h','g','p','v','M','m','m','C','G','D','k','8','u','T','n','Q','H','G','H','f','b','J','j','5','X','c','i','7','7','q', + 'b','R','8','b','b','z','f','f','h','Y','Q','7','u','B','X','e','i','j','M','q','C','T','M','v','t','J','J','w','b','F','v','J', + 'm','e','2','u','e','8','L','V','G','q','A','j','m','7','m','g','m','5','i','r','p','p','U','y','F','6','f','b','u','6','q','L', + 'M','E','t','V','W','C','t','e','p','w','a','n','w','y','X','h','8','e','G','C','H','q','r','X','G','9','c','h','7','k','8','M', + 'G','b','a','m','Y','Q','w','8','J','z','a','F','r','4','W','M','j','P','q','a','z','U','y','u','3','b','Z','f','Y','5','7','g', + 'N','M','h','M','a','3','C','K','6','6','f','a','p','i','f','q','k','T','i','z','w','f','Z','c','H','L','X','g','6','m','g','r', + 'w','Y','u','K','8','L','p','8','P','R','A','R','A','b','Z','V','a','x','V','c','G','A','H','t','Y','6','P','T','L','W','N','z', + 'g','z','k','d','E','v','C','t','Z','M','Z','K','4','w','9','5','D','W','f','U','8','5','u','6','b','5','B','8','g','y','C','E', + 'Q','z','e','9','p','N','S','P','D','D','f','x','k','Z','4','R','v','X','V','k','p','b','n','t','c','F','R','e','x','9','C','D', + 'J','2','6','f','Z','D','w','J','R','j','j','9','b','w','N','N','p','R','f','Z','z','j','F','r','Q','e','F','x','f','t','V','V', + 'A','y','J','G','W','Z','H','r','D','5','M','u','H','V','L','N','U','V','X','z','j','9','r','v','e','d','R','c','u','V','x','r', + 'c','6','k','L','h','q','w','U','W','Q','g','G','F','C','t','E','a','D','h','x','9','5','P','R','Z','E','M','5','f','4','2','t', + 'A','6','f','r','X','G','X','Y','B','8','G','E','n','B','v','x','f','M','R','f','B','z','Y','3','2','q','z','G','t','P','C','6', + '6','r','z','J','r','c','n','d','6','h','e','w','D','D','h','V','L','u','i','b','5','K','d','S','y','9','N','p','E','r','D','k', + 'B','z','u','v','d','Q','p','K','5','m','J','r','b','Y','Z','7','p','M','J','F','E','q','x','f','E','K','U','U','4','f','a','6', + 'g','5','a','q','D','U','8','F','y','R','a','P','5','5','x','z','6','V','T','P','D','m','y','7','U','5','C','A','7','Q','h','w', + 'r','6','x','g','Q','i','b','K','F','p','B','X','Q','h','i','E','r','C','z','v','x','W','Q','6','p','6','b','M','K','V','x','u', + 'k','d','R','S','k','Q','p','n','h','d','Q','Y','x','n','x','5','K','t','5','w','A','5','p','k','F','z','W','p','j','U','y','V', + 'x','G','m','y','L','A','X','H','G','A','a','J','5','E','P','q','E','U','7','p','6','A','9','n','d','G','D','g','i','h','t','W', + 'b','c','E','2','P','d','y','J','M','u','4','g','P','S','X','J','v','w','3','v','D','q','U','i','U','T','q','E','Y','5','2','t', + 'b','j','P','2','j','D','9','y','i','B','5','Y','3','X','L','w','m','V','X','z','X','r','Z','d','H','L','A','H','k','R','X','5', + 'i','L','m','q','3','p','a','G','P','j','g','h','R','P','Y','U','z','M','5','R','M','A','E','Q','V','c','w','r','4','M','S','k', + 'N','D','i','R','R','x','t','q','T','i','u','N','K','R','x','Z','K','a','g','G','y','9','c','j','J','S','9','3','H','T','f','F', + 'q','6','D','W','F','K','h','e','p','p','b','q','N','k','A','C','m','y','u','B','J','v','q','D','e','j','e','b','2','w','R','t', + 'J','N','j','F','T','A','8','L','m','X','i','T','g','j','c','V','4','V','h','2','h','R','p','2','9','k','c','c','G','D','h','z', + 't','i','h','t','W','R','n','Y','i','8','u','6','G','9','T','P','9','9','J','P','Y','R','h','X','K','z','h','L','W','r','C','U', + '2','L','T','k','2','m','6','W','L','P','T','Z','z','t','i','H','5','G','w','t','E','v','z','k','b','H','b','b','W','W','u','b', + 'i','h','C','Q','n','H','N','u','5','u','K','X','r','M','W','U','3','Y','k','P','2','k','x','f','x','C','w','z','z','b','G','8', + 'y','W','e','j','v','2','v','r','t','q','z','p','Y','d','w','6','Z','D','J','L','9','F','z','G','U','4','a','8','H','6','U','a', + 'q','7','y','Q','J','v','m','D','P','S','j','q','v','t','n','t','g','j','3','t','8','f','K','K','7','b','W','d','F','i','N','K', + 'a','R','V','V','V','v','m','A','Q','2','y','j','c','t','f','k','j','7','X','y','j','b','U','F','w','W','3','9','6','A','S','J', + 'p','q','2','Z','7','L','p','b','7','b','5','i','p','r','r','h','P','M','h','j','c','y','e','u','h','B','d','9','9','u','f','d', + 'g','u','p','w','u','9','S','c','L','U','g','A','y','V','F','V','6','D','D','X','i','V','m','u','Y','P','J','v','L','T','A','F', + 'M','Q','H','Z','6','v','8','p','A','L','P','z','C','V','a','C','h','X','j','W','8','G','z','j','d','M','4','u','x','w','H','g', + 'V','q','K','z','b','g','2','3','D','N','y','G','X','F','T','v','T','L','y','v','L','9','g','c','C','R','8','L','A','7','Y','N', + 't','n','R','6','b','n','m','9','i','h','t','T','F','a','V','N','J','J','3','J','q','p','W','7','b','T','G','r','M','k','a','7', + 'D','H','v','y','T','A','C','U','P','u','q','L','R','Y','4','q','h','y','f','F','J','x','K','7','N','B','v','3','a','Z','M','t', + 'U','x','8','9','V','E','t','j','K','r','u','Y','Y','A','u','w','Y','2','y','Q','z','S','n','J','B','2','t','X','x','K','z','g', + '6','d','n','i','7','Z','N','F','Q','6','w','N','r','b','k','d','W','X','S','t','c','U','m','6','4','2','e','w','6','x','Z','a', + 'Q','A','7','4','h','H','z','r','e','J','q','j','w','4','q','c','i','R','4','x','n','r','j','r','P','g','E','7','t','k','b','Z', + 'r','A','b','d','g','i','G','V','D','E','U','L','b','J','U','q','2','S','K','m','A','U','L','k','Q','4','N','p','k','G','C','6', + 'R','Z','B','y','B','B','j','y','x','L','d','h','L','G','6','x','H','z','T','5','d','Y','4','2','m','q','Q','y','H','6','c','N', + 'u','m','U','v','i','Y','Z','7','4','L','K','F','b','v','2','Y','h','x','8','a','R','w','q','x','E','a','T','y','m','C','2','Q', + 'U','T','D','Q','v','u','M','9','D','8','r','8','b','m','p','E','7','C','T','9','B','A','G','k','b','G','z','Z','G','L','N','k', + 'h','3','k','J','e','f','d','x','F','8','W','K','7','T','6','h','H','V','C','h','P','u','H','e','v','w','z','P','K','r','D','G', + 'X','Z','B','X','f','H','Q','4','e','D','y','W','Z','6','4','K','A','e','a','F','S','N','h','x','S','W','J','c','E','P','g','j', + 'a','w','T','m','Z','X','E','P','Y','R','M','2','R','2','X','N','F','X','Y','W','x','z','p','J','g','n','D','4','i','p','6','N', + 'r','9','G','k','E','h','T','h','U','h','x','B','Q','9','H','7','w','U','P','Q','d','G','6','q','p','j','j','v','C','a','X','J', + 'N','G','Y','w','f','H','C','x','F','k','z','3','9','r','h','8','7','5','V','i','V','C','R','q','x','N','2','2','i','W','F','U', + '7','T','H','f','z','E','a','n','u','Q','t','U','Y','G','t','3','A','m','r','6','d','f','e','n','e','z','F','u','U','N','8','m', + 'h','p','R','N','S','H','6','6','V','M','S','t','q','P','E','i','u','y','g','8','L','Q','Y','Y','G','e','W','W','C','G','y','b', + 'y','t','u','P','R','P','5','m','N','K','B','Z','w','f','t','k','x','3','L','b','q','d','w','S','G','E','h','R','F','4','q','e', + '5','6','F','2','n','q','T','R','y','f','n','Y','h','2','F','u','x','M','i','i','h','w','G','C','Z','v','i','C','a','X','U','C', + 'Y','8','d','h','R','x','V','n','v','G','i','D','a','U','p','U','a','e','b','F','w','P','d','X','n','K','h','9','H','r','b','g', + '2','f','m','X','k','m','q','6','n','5','b','G','H','d','R','9','D','U','c','r','Z','Y','W','S','Z','x','p','t','x','y','4','k', + 'j','F','U','t','C','i','e','i','b','p','e','4','C','z','h','3','3','5','Q','P','n','G','i','A','8','c','Q','z','B','a','V','4', + '2','B','2','z','u','u','3','i','L','w','y','g','K','H','k','y','2','B','b','e','5','e','4','e','U','4','z','n','P','z','a','c', + 'E','f','u','M','G','C','g','z','j','4','E','7','R','t','D','K','c','t','p','g','W','H','C','H','J','Q','J','c','F','5','4','W', + 'K','7','j','h','A','T','K','z','t','S','f','f','j','C','c','8','n','7','c','T','U','R','Q','E','7','A','W','Z','z','K','5','j', + '2','H','k','a','j','g','g','W','w','4','T','A','9','J','U','e','S','N','P','K','d','k','L','Q','G','Z','e','W','i','H','u','j', + 'C','z','4','E','2','v','5','L','u','9','Z','a','9','A','b','C','M','G','X','B','C','2','Y','Z','e','U','n','E','5','Y','n','y', + 'F','h','H','p','9','j','Y','F','V','w','Y','r','8','Q','f','C','J','4','T','t','z','Q','N','M','e','7','4','3','y','E','M','m', + 'b','S','c','h','w','a','X','E','d','E','z','t','h','9','k','p','A','k','K','H','x','q','K','Z','B','u','a','9','3','U','U','u', + '8','E','D','v','y','k','W','Y','X','k','r','R','D','X','n','Q','V','d','e','D','g','x','E','V','Y','w','k','m','K','r','H','D', + 't','2','6','N','U','g','3','t','B','9','t','u','M','D','z','Y','K','z','K','r','V','5','i','e','p','M','d','t','w','6','a','f', + 'f','W','k','L','i','g','M','V','M','Y','b','x','e','4','h','h','Y','g','w','Z','m','e','e','6','R','W','M','x','G','y','V','n', + '6','e','g','A','g','K','a','N','7','p','a','u','E','4','6','M','t','X','h','g','b','j','p','5','x','x','B','P','3','J','M','7', + 'j','Z','P','y','e','Q','Z','e','t','j','3','t','F','V','x','m','b','b','B','y','J','L','L','9','3','R','a','5','j','S','V','t', + 'e','2','6','m','H','w','r','w','r','6','Q','3','x','z','m','A','d','x','t','E','H','c','Z','x','c','P','j','r','u','U','W','k', + '6','g','X','g','n','f','n','7','H','M','B','t','v','6','v','x','g','M','f','e','2','w','m','y','d','H','S','q','c','K','U','H', + '2','X','h','d','p','Q','7','J','X','i','X','f','a','z','V','A','F','2','8','z','v','h','C','h','e','4','g','z','w','z','h','q', + 'p','6','B','n','m','8','h','W','U','7','z','h','T','6','J','f','4','Z','n','Q','W','z','2','N','4','t','g','7','u','4','X','2', + 'C','F','L','n','J','n','m','j','3','P','3','Y','e','J','R','A','H','e','R','D','z','7','u','X','Y','y','D','w','J','m','G','U', + 'P','H','5','S','d','a','F','F','Y','c','M','f','3','3','L','v','V','B','U','C','A','d','N','H','Q','h','7','8','4','r','p','G', + 'v','M','D','H','7','e','E','r','i','K','Q','i','B','D','M','Z','p','c','R','G','u','c','H','a','N','k','E','f','9','R','7','x', + '6','3','5','u','x','3','h','v','p','6','q','r','j','u','f','W','T','q','P','n','Y','L','B','6','U','w','P','2','T','W','R','g', + '2','3','3','e','N','V','a','j','b','e','4','T','u','J','u','u','F','B','D','G','H','x','x','k','5','G','e','3','4','B','m','L', + 'S','b','i','t','T','p','M','D','Z','A','A','i','r','J','p','4','H','U','A','G','y','d','Q','5','U','R','F','8','q','a','S','H', + 'n','5','z','9','g','3','u','R','H','m','G','m','b','p','c','L','Z','Y','u','m','i','K','A','Q','R','T','X','G','t','b','8','7', + '7','6','w','M','N','f','R','G','r','L','m','q','n','7','5','k','X','8','g','u','K','7','Y','w','K','q','U','e','W','A','r','i', + 'Z','a','p','q','L','5','P','u','n','t','y','G','x','C','N','X','q','P','r','U','v','A','r','r','q','e','f','c','z','M','7','N', + '6','a','z','Z','a','t','f','p','4','v','J','Y','j','h','M','D','t','k','A','B','p','Q','A','y','x','X','7','p','S','8','m','M', + 'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'}; + +static const adler32_test tests[] = { + {0x1, (const uint8_t *)0x0, 0, 0x1}, + {0x1, (const uint8_t *)"", 1, 0x10001}, + {0x1, (const uint8_t *)"a", 1, 0x620062}, + {0x1, (const uint8_t *)"abacus", 6, 0x8400270}, + {0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4}, + {0x1, (const uint8_t *)"campfire", 8, 0xea10348}, + {0x1, (const uint8_t *)"delta", 5, 0x61a020b}, + {0x1, (const uint8_t *)"executable", 10, 0x16fa0423}, + {0x1, (const uint8_t *)"file", 4, 0x41401a1}, + {0x1, (const uint8_t *)"greatest", 8, 0xefa0360}, + {0x1, (const uint8_t *)"inverter", 8, 0xf6f0370}, + {0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286}, + {0x1, (const uint8_t *)"karate", 6, 0x8a50279}, + {0x1, (const uint8_t *)"landscape", 9, 0x126a03ac}, + {0x1, (const uint8_t *)"machine", 7, 0xb5302d6}, + {0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca}, + {0x1, (const uint8_t *)"oblivion", 8, 0xf220363}, + {0x1, (const uint8_t *)"panama", 6, 0x8a1026f}, + {0x1, (const uint8_t *)"quest", 5, 0x6970233}, + {0x1, (const uint8_t *)"resource", 8, 0xf8d0369}, + {0x1, (const uint8_t *)"secret", 6, 0x8d10287}, + {0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366}, + {0x1, (const uint8_t *)"vector", 6, 0x8fb0294}, + {0x1, (const uint8_t *)"walrus", 6, 0x918029f}, + {0x1, (const uint8_t *)"xeno", 4, 0x45e01bb}, + {0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5}, + {0x1, (const uint8_t *)"zero", 4, 0x46e01c1}, + {0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d}, + {0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f}, + {0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e}, + {0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650}, + {0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690}, + {0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609}, + {0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703}, + {0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7}, + {0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698}, + {0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6}, + {0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c}, + {0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9}, + {0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769}, + {0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5}, + {0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750}, + {0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414}, + {0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405}, + {0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423}, + {0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421}, + {0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b}, + {0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d}, + {0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a}, + {0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d}, + {0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417}, + {0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412}, + {0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420}, + {0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419}, + {0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f}, + {0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f}, + {0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417}, + {0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841}, + {0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751}, + {0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a}, + {0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815}, + {0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661}, + {0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3}, + {0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb}, + {0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680}, + {0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f}, + {0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee}, + {0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92}, + {0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96}, + {0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8}, + {0x1, (const uint8_t *)long_string, 5552, 0x8b81718f}, + {0x7a30360d, (const uint8_t *)0x0, 0, 0x1}, + {0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee}, + {0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea}, + {0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da}, + {0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5}, + {0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44}, + {0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521}, + {0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2}, + {0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a}, + {0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01}, + {0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9}, + {0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4}, + {0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d}, + {0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024}, + {0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b}, + {0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb}, + {0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb}, + {0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f}, + {0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92}, + {0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5}, + {0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390}, + {0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39}, + {0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c}, + {0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516}, + {0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b}, + {0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4}, + {0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00}, + {0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b}, + {0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8}, + {0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c}, + {0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f}, + {0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f}, + {0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd}, + {0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446}, + {0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148}, + {0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc}, + {0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284}, + {0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706}, + {0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a}, + {0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db}, + {0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8}, + {0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd}, + {0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4}, + {0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218}, + {0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38}, + {0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8}, + {0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af}, + {0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c}, + {0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda}, + {0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006}, + {0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c}, + {0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4}, + {0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b}, + {0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3}, + {0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3}, + {0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a}, + {0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0}, + {0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8}, + {0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8}, + {0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54}, + {0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e}, + {0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c}, + {0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c}, + {0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9}, + {0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652}, + {0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e}, + {0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664}, + {0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911}, + {0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73}, + {0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8}, + {0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2}, +}; + +class adler32_variant : public ::testing::TestWithParam { +public: + void hash(adler32_test param, adler32_func adler32) { + uint32_t adler = adler32((uint32_t)param.adler, param.buf, param.len); + EXPECT_EQ(adler, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests)); + +#define TEST_ADLER32(name, func, support_flag) \ + TEST_P(adler32_variant, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_ADLER32(c, adler32_c, 1) + +#ifdef ARM_NEON +TEST_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon) +#elif defined(POWER8_VSX) +TEST_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(PPC_VMX) +TEST_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec) +#endif + +#ifdef X86_SSSE3 +TEST_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3) +#endif +#ifdef X86_AVX2 +TEST_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2) +#endif +#ifdef X86_AVX512 +TEST_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512) +#endif +#ifdef X86_AVX512VNNI +TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni) +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_aligned_alloc.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_aligned_alloc.cc new file mode 100644 index 000000000..07f99a9da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_aligned_alloc.cc @@ -0,0 +1,48 @@ +/* test_aligned_alloc.cc - Test zng_alloc_aligned and zng_free_aligned */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil.h" +} + +#include + +#include "test_shared.h" + +void *zng_calloc_unaligned(void *opaque, unsigned items, unsigned size) { + uint8_t *pointer = (uint8_t *)calloc(1, (items * size) + 2); + Z_UNUSED(opaque); + if (pointer == NULL) + return pointer; + /* Store whether or not our allocation is aligned */ + *pointer = ((uint64_t)(intptr_t)pointer + 1) % 2 == 0; + pointer++; + if (*pointer) { + /* Return pointer that is off by one */ + pointer++; + } + return (void *)pointer; +} + +void zng_cfree_unaligned(void *opaque, void *ptr) { + uint8_t *pointer = (uint8_t *)ptr; + Z_UNUSED(opaque); + pointer--; + /* Get whether or not our original memory pointer was aligned */ + if (*pointer) { + /* Return original aligned pointer to free() */ + pointer--; + } + free(pointer); +} + +TEST(zalloc, aligned_64) { + void *return_ptr = PREFIX3(alloc_aligned)(zng_calloc_unaligned, 0, 1, 100, 64); + ASSERT_TRUE(return_ptr != NULL); + EXPECT_EQ((intptr_t)return_ptr % 64, 0); + PREFIX3(free_aligned)(zng_cfree_unaligned, 0, return_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256.cc new file mode 100644 index 000000000..0e656da37 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256.cc @@ -0,0 +1,83 @@ +/* test_compare256.cc -- compare256 unit tests + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +#include "test_shared.h" + +#define MAX_COMPARE_SIZE (256) + + +/* Ensure that compare256 returns the correct match length */ +static inline void compare256_match_check(compare256_func compare256) { + int32_t match_len, i; + uint8_t *str1; + uint8_t *str2; + + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + + for (i = 0; i <= MAX_COMPARE_SIZE; i++) { + if (i < MAX_COMPARE_SIZE) + str2[i] = 0; + + match_len = compare256(str1, str2); + EXPECT_EQ(match_len, i); + + if (i < MAX_COMPARE_SIZE) + str2[i] = 'a'; + } + + zng_free(str1); + zng_free(str2); +} + +#define TEST_COMPARE256(name, func, support_flag) \ + TEST(compare256, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + compare256_match_check(func); \ + } + +TEST_COMPARE256(c, compare256_c, 1) + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +TEST_COMPARE256(unaligned_16, compare256_unaligned_16, 1) +#ifdef HAVE_BUILTIN_CTZ +TEST_COMPARE256(unaligned_32, compare256_unaligned_32, 1) +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(unaligned_64, compare256_unaligned_64, 1) +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2) +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2) +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon) +#endif +#ifdef POWER9 +TEST_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00) +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256_rle.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256_rle.cc new file mode 100644 index 000000000..da60d6f97 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compare256_rle.cc @@ -0,0 +1,63 @@ +/* test_compare256_rle.cc -- compare256_rle unit tests + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "compare256_rle.h" +} + +#include + +#define MAX_COMPARE_SIZE (256) + +/* Ensure that compare256_rle returns the correct match length */ +static inline void compare256_rle_match_check(compare256_rle_func compare256_rle) { + int32_t match_len, i; + uint8_t str1[] = {'a', 'a', 0}; + uint8_t *str2; + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + + for (i = 0; i <= MAX_COMPARE_SIZE; i++) { + if (i < MAX_COMPARE_SIZE) + str2[i] = 0; + + match_len = compare256_rle(str1, str2); + EXPECT_EQ(match_len, i); + + if (i < MAX_COMPARE_SIZE) + str2[i] = 'a'; + } + + zng_free(str2); +} + +#define TEST_COMPARE256_RLE(name, func, support_flag) \ + TEST(compare256_rle, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + compare256_rle_match_check(func); \ + } + +TEST_COMPARE256_RLE(c, compare256_rle_c, 1) + +#ifdef UNALIGNED_OK +TEST_COMPARE256_RLE(unaligned_16, compare256_rle_unaligned_16, 1) +#ifdef HAVE_BUILTIN_CTZ +TEST_COMPARE256_RLE(unaligned_32, compare256_rle_unaligned_32, 1) +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256_RLE(unaligned_64, compare256_rle_unaligned_64, 1) +#endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress.cc new file mode 100644 index 000000000..e069b69d3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress.cc @@ -0,0 +1,33 @@ +/* test_compress.cc - Test compress() and uncompress() using hello world string */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic) { + uint8_t compr[128], uncompr[128]; + z_uintmax_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = PREFIX(compress)(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_bound.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_bound.cc new file mode 100644 index 000000000..b83b59f4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_bound.cc @@ -0,0 +1,59 @@ +/* test_compress_bound.cc - Test compressBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +class compress_bound_variant : public testing::TestWithParam { +public: + void estimate(int32_t level) { + z_size_t estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t dest[128]; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + + /* buffer with values for worst case compression */ + for (int32_t j = 0; j < MAX_LENGTH; j++) { + uncompressed[j] = (uint8_t)j; + } + + for (z_size_t i = 0; i < MAX_LENGTH; i++) { + z_uintmax_t dest_len = sizeof(dest); + + /* calculate actual output length */ + estimate_len = PREFIX(compressBound)(i); + + err = PREFIX(compress2)(dest, &dest_len, uncompressed, i, level); + EXPECT_EQ(err, Z_OK); + EXPECT_GE(estimate_len, dest_len) << + "level: " << level << "\n" << + "length: " << i; + } + + free(uncompressed); + } +}; + +TEST_P(compress_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(compress_bound, compress_bound_variant, + testing::Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_dual.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_dual.cc new file mode 100644 index 000000000..a92ab4be3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_compress_dual.cc @@ -0,0 +1,28 @@ +/* test_compress_dual.cc - Test linking against both zlib and zlib-ng */ + +#include "zlib.h" + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic_zlib) { + Byte compr[128], uncompr[128]; + uLong compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = compress(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cpu_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cpu_features.h new file mode 100644 index 000000000..1bb4b13a0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cpu_features.h @@ -0,0 +1,8 @@ +#ifndef TEST_CPU_FEATURES_H +#define TEST_CPU_FEATURES_H + +#include "cpu_features.h" + +extern struct cpu_features test_cpu_features; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_crc32.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_crc32.cc new file mode 100644 index 000000000..f194b4ccf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_crc32.cc @@ -0,0 +1,222 @@ +/* test_crc32.cc -- crc32 unit test + * Copyright (C) 2019-2021 IBM Corporation + * Authors: Rogerio Alves + * Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + unsigned long crc; + const uint8_t *buf; + size_t len; + unsigned long expect; +} crc32_test; + +static const crc32_test tests[] = { + {0x0, (const uint8_t *)0x0, 0, 0x0}, + {0xffffffff, (const uint8_t *)0x0, 0, 0x0}, + {0x0, (const uint8_t *)0x0, 255, 0x0}, /* BZ 174799. */ + {0x0, (const uint8_t *)0x0, 256, 0x0}, + {0x0, (const uint8_t *)0x0, 257, 0x0}, + {0x0, (const uint8_t *)0x0, 32767, 0x0}, + {0x0, (const uint8_t *)0x0, 32768, 0x0}, + {0x0, (const uint8_t *)0x0, 32769, 0x0}, + {0x0, (const uint8_t *)"", 0, 0x0}, + {0xffffffff, (const uint8_t *)"", 0, 0xffffffff}, + {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b}, + {0x0, (const uint8_t *)"backlog", 7, 0x269205}, + {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8}, + {0x0, (const uint8_t *)"delta", 5, 0x9643fed9}, + {0x0, (const uint8_t *)"executable", 10, 0xd68eda01}, + {0x0, (const uint8_t *)"file", 4, 0x8c9f3610}, + {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd}, + {0x0, (const uint8_t *)"hello", 5, 0x3610a686}, + {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9}, + {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69}, + {0x0, (const uint8_t *)"karate", 6, 0x890be0e2}, + {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b}, + {0x0, (const uint8_t *)"machine", 7, 0x1505df84}, + {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39}, + {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77}, + {0x0, (const uint8_t *)"panama", 6, 0x66b8979c}, + {0x0, (const uint8_t *)"quest", 5, 0x4317f817}, + {0x0, (const uint8_t *)"resource", 8, 0xbc91f416}, + {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5}, + {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c}, + {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b}, + {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b}, + {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97}, + {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444}, + {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5}, + {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a}, + {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1}, + {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e}, + {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76}, + {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a}, + {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d}, + {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5}, + {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11}, + {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac}, + {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb}, + {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9}, + {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37}, + {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0}, + {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29}, + {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8}, + {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192}, + {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0}, + {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7}, + {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546}, + {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c}, + {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca}, + {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7}, + {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5}, + {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba}, + {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8}, + {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662}, + {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2}, + {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b}, + {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937}, + {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f}, + {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4}, + {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4}, + {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631}, + {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99}, + {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac}, + {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9}, + {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf}, + {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac}, + {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388}, + {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d}, + {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5}, + {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9}, + {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777}, + {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048}, + {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84}, + {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1}, + {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca}, + {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1}, + {0xdc712e2, (const uint8_t *)"executable", 10, 0x761b4254}, + {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b}, + {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b}, + {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5}, + {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109}, + {0xab058a2, (const uint8_t *)"karate", 6, 0xc5591f41}, + {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644}, + {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636}, + {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb}, + {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b}, + {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4}, + {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36}, + {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925}, + {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db}, + {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8}, + {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d}, + {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef}, + {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5}, + {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38}, + {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127}, + {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0}, + {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274}, + {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870}, + {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd}, + {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc}, + {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178}, + {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070}, + {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0}, + {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72}, + {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620}, + {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d}, + {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24}, + {0x3275b9f, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df}, + {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30}, + {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9}, + {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7}, + {0xe75b214, (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d}, + {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7}, + {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7}, + {0x54b8e14, (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2}, + {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461}, + {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a}, + {0xbe92385, (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12}, + {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c}, + {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1}, + {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2}, + {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1}, + {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83}, + {0x75770fc, (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81}, + {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404}, + {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010}, + {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3}, + {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f}, + {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de}, + {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59}, + {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f}, + {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac}, + {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66}, + {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7}, + {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a}, + {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060}, + {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312}, + {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912}, + {0xc45aef77, (const uint8_t *) + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B} +}; + +class crc32_variant : public ::testing::TestWithParam { +public: + void hash(crc32_test param, crc32_func crc32) { + uint32_t crc = 0; + if (param.buf != NULL) { + if (param.len) { + crc = crc32(param.crc, param.buf, param.len); + } else { + crc = param.crc; + } + } + EXPECT_EQ(crc, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests)); + +#define TEST_CRC32(name, func, support_flag) \ + TEST_P(crc32_variant, name) { \ + if (!(support_flag)) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_CRC32(braid, PREFIX(crc32_braid), 1) + +#ifdef ARM_ACLE +TEST_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32) +#elif defined(POWER8_VSX_CRC32) +TEST_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(S390_CRC32_VX) +TEST_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx) +#elif defined(X86_PCLMULQDQ_CRC) +TEST_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq) +# ifdef X86_VPCLMULQDQ_CRC +TEST_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512 && test_cpu_features.x86.has_vpclmulqdq)) +# endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cve-2003-0107.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cve-2003-0107.cc new file mode 100644 index 000000000..9d9e5b00d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_cve-2003-0107.cc @@ -0,0 +1,28 @@ +// https://www.securityfocus.com/archive/1/312869 --- originally by Richard Kettlewell +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if !defined(_WIN32) && defined(ZLIB_COMPAT) +TEST(gzip, cve_2003_0107) { + gzFile f; + int ret; + + f = gzopen("/dev/null", "w"); + EXPECT_TRUE(f != NULL); + + ret = gzprintf(f, "%10240s", ""); + printf("gzprintf -> %d\n", ret); + ret = gzclose(f); + printf("gzclose -> %d [%d]\n", ret, errno); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_bound.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_bound.cc new file mode 100644 index 000000000..c86d4e00b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_bound.cc @@ -0,0 +1,99 @@ +/* test_deflate_bound.cc - Test deflateBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +typedef struct { + int32_t level; + int32_t window_size; + int32_t mem_level; + bool after_init; +} deflate_bound_test; + +static const deflate_bound_test tests[] = { + {0, MAX_WBITS + 16, 1, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, false}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, false}, +}; + +class deflate_bound_variant : public testing::TestWithParam { +public: + void estimate(deflate_bound_test param) { + PREFIX3(stream) c_stream; + int estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t *out_buf = NULL; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + memset(uncompressed, 'a', MAX_LENGTH); + + for (int32_t i = 0; i < MAX_LENGTH; i++) { + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.avail_in = i; + c_stream.next_in = (z_const unsigned char *)uncompressed; + c_stream.avail_out = 0; + c_stream.next_out = out_buf; + + if (!param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + + err = PREFIX(deflateInit2)(&c_stream, param.level, Z_DEFLATED, + param.window_size, param.mem_level, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* calculate actual output length and update structure */ + if (param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + out_buf = (uint8_t *)malloc(estimate_len); + + if (out_buf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimate_len; + c_stream.next_out = out_buf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END) << + "level: " << param.level << "\n" << + "window_size: " << param.window_size << "\n" << + "mem_level: " << param.mem_level << "\n" << + "after_init: " << param.after_init << "\n" << + "length: " << i; + + free(out_buf); + out_buf = NULL; + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + } + + free(uncompressed); + } +}; + +TEST_P(deflate_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(deflate_bound, deflate_bound_variant, testing::ValuesIn(tests)); diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_concurrency.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_concurrency.cc new file mode 100644 index 000000000..1297aee64 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_concurrency.cc @@ -0,0 +1,170 @@ +/* Test deflate() on concurrently modified next_in. + * + * Plain zlib does not document that this is supported, but in practice it tolerates this, and QEMU live migration is + * known to rely on this. Make sure zlib-ng tolerates this as well. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +#include "zlib.h" +#else +#include "zlib-ng.h" +#endif + +#include + +#include +#include +#include +#include + +static uint8_t buf[8 * 1024]; +static uint8_t zbuf[4 * 1024]; +static uint8_t tmp[8 * 1024]; + +/* Thread that increments all bytes in buf by 1. */ +class Mutator { + enum class State { + PAUSED, + RUNNING, + STOPPED, + }; + +public: + Mutator() + : m_state(State::PAUSED), m_target_state(State::PAUSED), + m_thread(&Mutator::run, this) {} + ~Mutator() { + transition(State::STOPPED); + m_thread.join(); + } + + void pause() { + transition(State::PAUSED); + } + + void resume() { + transition(State::RUNNING); + } + +private: + void run() { + while (true) { + m_state.store(m_target_state); + if (m_state == State::PAUSED) + continue; + if (m_state == State::STOPPED) + break; + for (uint8_t & i: buf) + i++; + } + } + + void transition(State target_state) { + m_target_state = target_state; + while (m_state != target_state) { + } + } + + std::atomic m_state, m_target_state; + std::thread m_thread; +}; + +TEST(deflate, concurrency) { +#ifdef S390_DFLTCC_DEFLATE + GTEST_SKIP() << "Known to be broken with S390_DFLTCC_DEFLATE"; +#endif + + /* Create reusable mutator and streams. */ + Mutator mutator; + + PREFIX3(stream) dstrm; + memset(&dstrm, 0, sizeof(dstrm)); + int err = PREFIX(deflateInit2)(&dstrm, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + PREFIX3(stream) istrm; + memset(&istrm, 0, sizeof(istrm)); + err = PREFIX(inflateInit2)(&istrm, -15); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Iterate for a certain amount of time. */ + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < deadline) { + /* Start each iteration with a fresh stream state. */ + err = PREFIX(deflateReset)(&dstrm); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + err = PREFIX(inflateReset)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Mutate and compress the first half of buf concurrently. + * Decompress and throw away the results, which are unpredictable. + */ + mutator.resume(); + dstrm.next_in = buf; + dstrm.avail_in = sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << istrm.msg; + } + } + + /* Stop mutation and compress the second half of buf. + * Decompress and check that the result matches. + */ + mutator.pause(); + dstrm.next_in = buf + sizeof(buf) / 2; + dstrm.avail_in = sizeof(buf) - sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_FINISH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, dstrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + size_t orig_total_out = istrm.total_out; + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, istrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << istrm.msg; + size_t concurrent_size = sizeof(buf) - sizeof(buf) / 2; + if (istrm.total_out > concurrent_size) { + size_t tmp_offset, buf_offset, size; + if (orig_total_out >= concurrent_size) { + tmp_offset = 0; + buf_offset = orig_total_out - concurrent_size; + size = istrm.total_out - orig_total_out; + } else { + tmp_offset = concurrent_size - orig_total_out; + buf_offset = 0; + size = istrm.total_out - concurrent_size; + } + ASSERT_EQ(0, memcmp(tmp + tmp_offset, buf + sizeof(buf) / 2 + buf_offset, size)); + } + } + } + } + + err = PREFIX(inflateEnd)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + err = PREFIX(deflateEnd)(&dstrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_copy.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_copy.cc new file mode 100644 index 000000000..4adc9be96 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_copy.cc @@ -0,0 +1,60 @@ +/* test_deflate_copy.cc - Test deflateCopy() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "deflate.h" + +#include "test_shared.h" + +#include + +TEST(deflate, copy) { + PREFIX3(stream) c_stream, c_stream_copy; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&c_stream_copy, 0, sizeof(c_stream_copy)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(c_stream.state->status, c_stream_copy.state->status); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream_copy); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_dict.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_dict.cc new file mode 100644 index 000000000..781c70db2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_dict.cc @@ -0,0 +1,54 @@ +/* test_deflate_dict.cc - Test deflateGetDictionary() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, dictionary) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + uint32_t compr_len = sizeof(compr); + uint8_t *dict_new = NULL; + uint32_t *dict_len; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + dict_new = (uint8_t *)calloc(256, 1); + ASSERT_TRUE(dict_new != NULL); + dict_len = (uint32_t *)calloc(4, 1); + ASSERT_TRUE(dict_len != NULL); + + err = PREFIX(deflateGetDictionary)(&c_stream, dict_new, dict_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(dict_new); + free(dict_len); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_hash_head_0.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_hash_head_0.cc new file mode 100644 index 000000000..cbf601038 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_hash_head_0.cc @@ -0,0 +1,83 @@ +/* Generated by fuzzing - test hash_head == 0 handling. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, hash_head_0) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY); + EXPECT_EQ(err, Z_OK); + + unsigned char next_in[9698]; + memset(next_in, 0x30, sizeof(next_in)); + next_in[8193] = 0x00; + next_in[8194] = 0x00; + next_in[8195] = 0x00; + next_in[8199] = 0x8a; + strm.next_in = next_in; + unsigned char next_out[21572]; + strm.next_out = next_out; + + strm.avail_in = 0; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 3, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 6728; + strm.avail_out = 2696; + err = PREFIX(deflate(&strm, Z_SYNC_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 15; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 9, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 1453; + strm.avail_out = 1348; + err = PREFIX(deflate(&strm, Z_FULL_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in); + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_header.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_header.cc new file mode 100644 index 000000000..0d1b7d044 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_header.cc @@ -0,0 +1,71 @@ +/* test_deflate_header.cc - Test deflateSetHeader() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, header) { + PREFIX3(stream) c_stream; + PREFIX(gz_header) *head; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + head = (PREFIX(gz_header) *)calloc(1, sizeof(PREFIX(gz_header))); + ASSERT_TRUE(head != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + EXPECT_EQ(err, Z_OK); + + PREFIX(deflateBound)(&c_stream, (unsigned long)compr_len); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + /* Check CRC32. */ + EXPECT_EQ(c_stream.adler, 0xb56c3f9dU); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(head); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_params.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_params.cc new file mode 100644 index 000000000..9fadea85f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_params.cc @@ -0,0 +1,143 @@ +/* test_deflate_params.cc - Test deflate() with dynamic change of compression level */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "deflate.h" + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (64 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, params) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + uint32_t diff; + int32_t i; + time_t now; + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + /* Feed in already compressed data and switch to no compression: */ +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_BEST_SPEED); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); +#endif + + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* Switch back to compressing mode: */ +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_NO_COMPRESSION); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); +#endif + + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncompr_len; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + do { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } while (err == Z_OK); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, (2 * uncompr_len) + diff); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_pending.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_pending.cc new file mode 100644 index 000000000..8ccedbf33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_pending.cc @@ -0,0 +1,66 @@ +/* test_deflate_pending.cc - Test deflatePending() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, pending) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int *bits; + unsigned *ped; + int err; + + + bits = (int *)calloc(256, 1); + ASSERT_TRUE(bits != NULL); + ped = (unsigned *)calloc(256, 1); + ASSERT_TRUE(ped != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + EXPECT_EQ(err, Z_OK); + + EXPECT_GE(*bits, 0); + EXPECT_LE(*bits, 7); + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(bits); + free(ped); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_prime.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_prime.cc new file mode 100644 index 000000000..75dcf3177 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_prime.cc @@ -0,0 +1,91 @@ +/* test_deflate_prime.cc - Test deflatePrime() wrapping gzip around deflate stream */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared_ng.h" + +#include + +TEST(deflate, prime) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t crc = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + EXPECT_EQ(err, Z_OK); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + EXPECT_EQ(err, Z_OK); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + EXPECT_EQ(err, Z_OK); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len); + err = deflate_prime_32(&c_stream, crc); + EXPECT_EQ(err, Z_OK); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)hello_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_BUF_ERROR); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_bi_valid.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_bi_valid.cc new file mode 100644 index 000000000..8ce4c229d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_bi_valid.cc @@ -0,0 +1,80 @@ +/* Generated by fuzzing - test bi_valid handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, bi_valid) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[554] = { + 0x8d, 0xff, 0xff, 0xff, 0xa2, 0x00, 0x00, 0xff, 0x00, 0x15, 0x1b, 0x1b, 0xa2, 0xa2, 0xaf, 0xa2, + 0xa2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x07, 0x01, 0x18, 0x00, 0x22, 0x00, + 0x00, 0x00, 0xfd, 0x39, 0xff, 0x00, 0x00, 0x00, 0x1b, 0xfd, 0x3b, 0x00, 0x68, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0x57, 0xf8, 0x1e, 0x00, 0x00, 0xf2, 0xf2, 0xf2, 0xf2, 0xfa, 0xff, 0xff, 0xff, + 0xff, 0x7e, 0x00, 0x00, 0x4a, 0x00, 0xc5, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x01, 0x00, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4a, 0x4a, 0x4a, 0x32, + 0x00, 0xf9, 0xff, 0x00, 0x02, 0x9a, 0xff, 0x00, 0x00, 0x3f, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x08, 0x2f, 0x20, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7a, 0x7a, 0x9e, 0xff, 0xff, 0x00, 0x1b, 0x1b, 0x04, 0x00, 0x1b, 0x1b, + 0x1b, 0x1b, 0x00, 0x00, 0x00, 0xaf, 0xad, 0xaf, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2e, 0xff, + 0xff, 0x2e, 0xc1, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x00, 0xda, 0x67, 0x01, + 0x47, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x3f, + 0x54, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x34, 0x3e, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x40, 0x1b, 0x1b, 0x88, 0x1b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1f, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x50, 0x3e, 0x7a, 0x7a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xff, 0x3d, 0x00, 0x11, 0x4d, 0x00, 0x00, 0x01, 0xd4, 0xd4, 0xd4, 0xd4, 0x2d, 0xd4, + 0xd4, 0xff, 0xff, 0xff, 0xfa, 0x01, 0xd4, 0x00, 0xd4, 0x00, 0x00, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, + 0xd4, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00, 0xfe, 0xf9, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, + 0x16, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, + 0xff, 0x2b, 0x2b, 0x2b, 0x2b, 0x35, 0xd4, 0xd4, 0x47, 0x3f, 0xd4, 0xd4, 0xd6, 0xd4, 0xd4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x4a, 0x4a, 0x4a, 0x4a, 0x71, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, + 0x1f, 0x1b, 0x1b, 0x1b, 0x57, 0x57, 0x57, 0x57, 0x00, 0x00, 0x1b, 0x08, 0x2b, 0x16, 0xc3, 0x00, + 0x00, 0x00, 0x29, 0x30, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x07, 0x00, 0x00, 0x01, 0x0b, 0xff, + 0xff, 0xf5, 0xf5, 0xf5, 0x00, 0x00, 0xfe, 0xfa, 0x0f, 0x0f, 0x08, 0x00, 0xff, 0x00, 0x53, 0x3f, + 0x00, 0x04, 0x5d, 0xa8, 0x2e, 0xff, 0xff, 0x00, 0x2f, 0x2f, 0x05, 0xff, 0xff, 0xff, 0x2f, 0x2f, + 0x2f, 0x0a, 0x0a, 0x0a, 0x0a, 0x30, 0xff, 0xff, 0xff, 0xf0, 0x0a, 0x0a, 0x0a, 0x00, 0xff, 0x3f, + 0x4f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x71, 0x00, 0x71, 0x71, 0x71, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x3f, 0x00, 0xfa, 0x71, 0x71, 0x71, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x71, 0x71, 0x71, 0x71, 0x71}; + strm.next_in = next_in; + unsigned char next_out[1236]; + strm.next_out = next_out; + + strm.avail_in = 554; + strm.avail_out = 31; + + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 0; + strm.avail_out = 498; + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_block_open.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_block_open.cc new file mode 100644 index 000000000..84a1ac8bb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_quick_block_open.cc @@ -0,0 +1,94 @@ +/* Generated by fuzzing - test block_open handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, block_open) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -MAX_WBITS, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[495] = + "\x1d\x1d\x00\x00\x00\x4a\x4a\x4a\xaf\xaf\xaf\xaf\x4a\x4a\x4a\x4a" + "\x3f\x3e\xaf\xff\xff\xff\x11\xff\xff\xff\xff\xdf\x00\x00\x00\x01" + "\x3f\x7d\x00\x50\x00\x00\xc8\x01\x2b\x60\xc8\x00\x24\x06\xff\xff" + "\x4a\x4e\x4a\x7d\xc8\x01\xf1\x2b\x28\xb2\xb2\x60\x25\xc8\x06\x00" + "\x00\x00\x31\x00\x01\xb2\xb2\xb2\xff\xff\xfd\xb2\xb2\x40\xff\x7d" + "\x3b\x34\x3e\xff\xff\x4a\x4a\x01\xf1\xff\x02\xff\x3f\xff\x02\xff" + "\xff\xff\xbf\x0a\xff\x00\x01\x3f\xb3\xff\x26\x00\x00\x13\x00\xc8" + "\x3e\x3e\x3e\x4a\x76\x4a\x4a\x2e\x7d\x3e\x3e\x3e\x3e\x1d\x1d\x1d" + "\xfe\xea\xef\x80\x01\x00\x00\x40\x00\x00\xba\x00\x06\xfa\xb9\x11" + "\xbf\x98\xee\x45\x7e\x04\x00\xff\xff\xff\x67\xc3\xc3\xc3\xc3\x00" + "\x1d\x1d\xe1\xe3\x00\xc3\x1d\x98\x1d\x1d\x1d\x1d\x1d\x00\x00\x00" + "\x02\x00\x00\x00\xe8\x00\x00\x1d\x1d\x1d\xfa\x1e\x12\xff\xff\xff" + "\x00\x01\xa7\xff\xff\xff\x1d\x1d\x1d\x63\xff\xff\xff\x1f\x00\x00" + "\x10\x40\x00\x00\xad\xff\xff\x3f\x51\x00\xf8\xff\xff\x8a\x01\x05" + "\x00\x00\x03\x00\x00\xff\x00\x00\x00\x05\x40\x1f\x08\x0a\x00\xff" + "\xff\x01\x00\x12\x00\x00\x01\x00\x3f\x40\x1d\x1d\x1d\x1d\x1d\x1d" + "\x21\x00\x1d\x00\x00\x00\xe4\x00\x00\x00\x07\x00\x00\xe6\xe6\x34" + "\xe6\xe6\xe6\xe6\xff\x2b\xee\x1d\x1d\x1d\x93\x1d\x1d\x1d\xee\x2b" + "\xee\x01\x81\x1d\x00\x00\x58\x00\x00\x01\x14\x00\x1b\x00\x00\x2c" + "\x00\x00\x00\xdb\x00\x45\x7e\x00\x00\x00\xfb\xbd\x00\x06\x21\xd3" + "\x00\xff\xff\xff\xff\xff\x00\x49\x49\xc9\x49\x3d\x00\x34\x01\x00" + "\x00\x6a\x2b\x00\x00\x50\x40\xf0\xf0\xf0\xf0\xa3\xa3\xa3\xa3\xf0" + "\xf0\x06\xfa\xa9\x01\x10\xbf\x98\x9d\x2b\xee\x2d\x21\x01\xdb\x00" + "\x45\x10\x00\x00\x7e\x00\x00\xe7\x00\xff\xff\x00\xf6\x00\x00\x00" + "\xf9\x00\x00\x00\x11\x00\x00\x00\xe2\x00\x00\x00\x2d\x00\x00\x00" + "\x2f\x00\x3f\x54\x1d\x1d\x1d\x4c\x4c\x4c\x4c\x2a\x4c\x4c\x10\xff" + "\xff\x1a\x00\x00\x01\xff\x00\xff\xf9\x00\x3f\x53\xcc\xcc\xcc\xcc" + "\x6e\x00\x00\x01\xf8\xff\xff\xff\x49\x04\x2c\x01\x00\x1d\x00\x07" + "\x01\xff\x00\x00\x00\xf8\xff\x09\x00\x27\x00\x08\x21\x1c\x00\x00" + "\x00\x00\x1d\x05\x00\x00\x00\x2c\x53\x3f\x00\x01\x00\x00\xe6\xff" + "\xff\xff\x6a\x2b\xee\xe6\x6a\x2b\xee\x2b\xee\xee\x2b\xee"; + strm.next_in = next_in; + unsigned char next_out[1116]; + strm.next_out = next_out; + + strm.avail_in = sizeof(next_in); + while (1) { + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + if (strm.avail_out > 38) + strm.avail_out = 38; + err = PREFIX(deflate)(&strm, Z_FINISH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_tune.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_tune.cc new file mode 100644 index 000000000..9921ee643 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_deflate_tune.cc @@ -0,0 +1,56 @@ +/* test_deflate_tune.cc - Test deflateTune() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, tune) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateTune)(&c_stream, good_length, max_lazy,nice_length, max_chain); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_dict.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_dict.cc new file mode 100644 index 000000000..af9662e3d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_dict.cc @@ -0,0 +1,96 @@ +/* test_dict.cc - Test deflate() and inflate() with preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + +static const char dictionary[] = "hello"; + +TEST(dictionary, basic) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t dict_adler = 0; + uint8_t check_dict[MAX_DICTIONARY_SIZE]; + uint32_t check_dict_len = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char *)dictionary, (int)sizeof(dictionary)); + EXPECT_EQ(err, Z_OK); + + dict_adler = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncompr_len; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + EXPECT_EQ(d_stream.adler, dict_adler); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (uint32_t)sizeof(dictionary)); + EXPECT_EQ(d_stream.adler, dict_adler); + } + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_GE(check_dict_len, sizeof(dictionary)); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dict, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_TRUE(memcmp(dictionary, check_dict, sizeof(dictionary)) == 0); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(strncmp((char*)uncompr, hello, sizeof(hello)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_gzio.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_gzio.cc new file mode 100644 index 000000000..3cab1dbe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_gzio.cc @@ -0,0 +1,105 @@ +/* test_gzio.cc - Test read/write of .gz files */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define TESTFILE "foo.gz" + +TEST(gzip, readwrite) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); + GTEST_SKIP(); +#else + uint8_t compr[128], uncompr[128]; + uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + size_t read; + int64_t pos; + gzFile file; + int err; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(TESTFILE, "wb"); + ASSERT_TRUE(file != NULL); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4); + EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8); + /* Write string null-teriminator using gzseek */ + EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0); + /* Write hello, hello! using gzfwrite using best compression level */ + EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK); + EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0UL); + /* Flush compressed bytes to file */ + EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK); + compr_len = (uint32_t)PREFIX(gzoffset)(file); + EXPECT_GE(compr_len, 0UL); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(TESTFILE, "rb"); + ASSERT_TRUE(file != NULL); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len)); + EXPECT_STREQ((char*)uncompr, hello); + + /* Check position at the end of the gz file */ + EXPECT_EQ(PREFIX(gzeof)(file), 1); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + EXPECT_EQ(pos, 6); + EXPECT_EQ(PREFIX(gztell)(file), pos); + EXPECT_EQ(PREFIX(gzgetc)(file), ' '); + EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' '); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len); + EXPECT_EQ(strlen((char*)uncompr), 7UL); /* " hello!" */ + EXPECT_STREQ((char*)uncompr, hello + 6); + + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + EXPECT_EQ(pos, 14); + EXPECT_EQ(PREFIX(gztell)(file), pos); + + /* Check position not at end of file */ + EXPECT_EQ(PREFIX(gzeof)(file), 0); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file); + EXPECT_STREQ((const char *)uncompr, hello); + + pos = PREFIX(gzoffset)(file); + EXPECT_GE(pos, 0); + EXPECT_EQ(pos, (compr_len + 10)); + + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + EXPECT_NE(err, 0); + + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + EXPECT_EQ(err, 0); + + PREFIX(gzclose)(file); + + EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR); + Z_UNUSED(read); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_adler32.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_adler32.cc new file mode 100644 index 000000000..fb78bb1bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_adler32.cc @@ -0,0 +1,50 @@ +/* GH-1066 - inflate small amount of data and validate with adler32 checksum. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +const char* original = "The quick brown fox jumped over the lazy dog"; + +z_const unsigned char compressed[] = { + 0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48, + 0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d, + 0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8, + 0x49, 0xac, 0xaa, 0x54, 0x48, 0xc9, 0x4f, 0x07, 0x00, 0x6b, 0x93, 0x10, 0x30 +}; + +TEST(inflate, adler32) { + unsigned char uncompressed[1024]; + PREFIX3(stream) strm; + + memset(&strm, 0, sizeof(strm)); + + int err = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = compressed; + strm.avail_in = sizeof(compressed); + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + EXPECT_EQ(strm.adler, 0x6b931030); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_sync.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_sync.cc new file mode 100644 index 000000000..a79d867e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_inflate_sync.cc @@ -0,0 +1,75 @@ +/* test_inflate_sync.cc - Test inflateSync using full flush deflate and corrupted data */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(inflate, sync) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + /* build compressed stream with full flush */ + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* force an error in first compressed block */ + compr[3]++; + c_stream.avail_in = hello_len-3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + compr_len = (z_size_t)c_stream.total_out; + + memset(&d_stream, 0, sizeof(d_stream)); + /* just read the zlib header */ + d_stream.next_in = compr; + d_stream.avail_in = 2; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* read all compressed data, but skip damaged part */ + d_stream.avail_in = (uint32_t)compr_len-2; + err = PREFIX(inflateSync)(&d_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_large_buffers.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_large_buffers.cc new file mode 100644 index 000000000..3c1208140 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_large_buffers.cc @@ -0,0 +1,87 @@ +/* test_large_buffers.cc - Test deflate() and inflate() with large buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (32 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, large_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + int32_t i; + time_t now; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = compr_len; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, uncompr_len); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_main.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_main.cc new file mode 100644 index 000000000..82b39e487 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_main.cc @@ -0,0 +1,19 @@ +/* test_test.cc - Main entry point for test framework */ + +#include + +#include "gtest/gtest.h" + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" + + struct cpu_features test_cpu_features; +} + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + cpu_check_features(&test_cpu_features); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_raw.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_raw.cc new file mode 100644 index 000000000..a013d4bb4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_raw.cc @@ -0,0 +1,58 @@ +/* test_raw.cc - Test raw streams. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(raw, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[512]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + stream.adler = 0x12345678; + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x12345678); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + stream.adler = 0x87654321; + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x87654321); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared.h b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared.h new file mode 100644 index 000000000..616f57342 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared.h @@ -0,0 +1,18 @@ +#ifndef TEST_SHARED_H +#define TEST_SHARED_H + +/* Test definitions that can be used in the original zlib build environment. */ + +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ +static const char hello[] = "hello, hello!"; +static const int hello_len = sizeof(hello); + +/* Clang static analyzer doesn't understand googletest's ASSERT_TRUE, so we need to tell that it's like assert() */ +#ifdef __clang_analyzer__ +# undef ASSERT_TRUE +# define ASSERT_TRUE assert +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared_ng.h b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared_ng.h new file mode 100644 index 000000000..81e451998 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_shared_ng.h @@ -0,0 +1,23 @@ +#ifndef TEST_SHARED_NG_H +#define TEST_SHARED_NG_H + +#include "test_shared.h" + +/* Test definitions that can only be used in the zlib-ng build environment. */ + +static inline int deflate_prime_32(PREFIX3(stream) *stream, uint32_t value) { + int err; + +#ifdef ZLIBNG_ENABLE_TESTS + err = PREFIX(deflatePrime)(stream, 32, value); +#else + /* zlib's deflatePrime() takes at most 16 bits */ + err = PREFIX(deflatePrime)(stream, 16, value & 0xffff); + if (err != Z_OK) return err; + err = PREFIX(deflatePrime)(stream, 16, value >> 16); +#endif + + return err; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_buffers.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_buffers.cc new file mode 100644 index 000000000..bb3449fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_buffers.cc @@ -0,0 +1,69 @@ +/* test_small_buffers.cc - Test deflate() and inflate() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, small_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + /* Finish the stream, still forcing small buffers */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + while (d_stream.total_out < uncompr_len && d_stream.total_in < compr_len) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char*)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_window.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_window.cc new file mode 100644 index 000000000..e351efac0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_small_window.cc @@ -0,0 +1,67 @@ +/* test_small_window.cc - Test deflate() and inflate() with a small window and a preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(small_window, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[128]; + unsigned char dictionary1[(1 << 9) - sizeof(plain) / 2]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_COMPRESSION, Z_DEFLATED, -9, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Use a large dictionary that is loaded in two parts */ + memset(dictionary1, 'a', sizeof(dictionary1)); + err = PREFIX(deflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + err = PREFIX(deflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -9); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + err = PREFIX(inflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/test/test_version.cc b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_version.cc new file mode 100644 index 000000000..fda87904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/test/test_version.cc @@ -0,0 +1,27 @@ +/* test_version.cc - Test zVersion() and zlibCompileFlags() */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(version, basic) { + static const char *my_version = PREFIX2(VERSION); + + EXPECT_EQ(zVersion()[0], my_version[0]); + EXPECT_STREQ(zVersion(), PREFIX2(VERSION)); + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/tools/config.sub b/internal-complibs/zlib-ng-2.1.1-beta2/tools/config.sub new file mode 100755 index 000000000..dba175ae3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/tools/config.sub @@ -0,0 +1,17 @@ +#!/bin/sh +# Canonicalize CHOST. +# In particular, converts Debian multiarch tuples into GNU triplets. +# See also +# https://wiki.debian.org/Multiarch/Tuples +# https://wiki.gentoo.org/wiki/CHOST +# If you need an architecture not listed here, file a bug at github.com/zlib-ng/zlib-ng +# and work around the problem by dropping libtool's much more comprehensive config.sub +# on top of this file, see +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +case "$1" in +*-*-linux-gnu*) echo $1;; +i686-linux-gnu*|x86_64-linux-gnu*) echo $1 | sed 's/-linux-gnu/-pc-linux-gnu/';; +*-linux-gnu*) echo $1 | sed 's/-linux-gnu/-unknown-linux-gnu/';; +*) echo $1;; +esac diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/tools/makecrct.c b/internal-complibs/zlib-ng-2.1.1-beta2/tools/makecrct.c new file mode 100644 index 000000000..5c3ba58a1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/tools/makecrct.c @@ -0,0 +1,250 @@ +/* makecrct.c -- output crc32 tables + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#include +#include +#include "zbuild.h" +#include "zutil.h" + +/* + The crc32 table header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. +*/ + +#define W 8 /* Need a 64-bit integer type in order to generate crc32 tables. */ + +#include "crc32_braid_p.h" + +static uint32_t crc_table[256]; +static z_word_t crc_big_table[256]; + +static uint32_t crc_braid_table[W][256]; +static z_word_t crc_braid_big_table[W][256]; +static uint32_t x2n_table[32]; + +#include "crc32_braid_comb_p.h" + +static void make_crc_table(void); +static void print_crc_table(void); + +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w); + +static void write_table(const uint32_t *table, int k); +static void write_table32hi(const z_word_t *table, int k); +static void write_table64(const z_word_t *table, int k); + +/* ========================================================================= */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table(void) { + unsigned i, j, n; + uint32_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; + crc_big_table[i] = ZSWAP64(p); + } + + /* initialize the x^2^n mod p(x) table */ + p = (uint32_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +} + +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + uint32_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp(((z_off64_t)n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = ZSWAP64(q); + } + } +} + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +static void write_table(const uint32_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +static void write_table32hi(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +static void write_table64(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%016" PRIx64 "%s", n == 0 || n % 3 ? "" : " ", + (uint64_t)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +static void print_crc_table(void) { + int k, n; + uint32_t ltl[8][256]; + z_word_t big[8][256]; + + printf("#ifndef CRC32_BRAID_TBL_H_\n"); + printf("#define CRC32_BRAID_TBL_H_\n\n"); + printf("/* crc32_braid_tbl.h -- tables for braided CRC calculation\n"); + printf(" * Generated automatically by makecrct.c\n */\n\n"); + + /* print little-endian CRC table */ + printf("static const uint32_t crc_table[] = {\n"); + printf(" "); + write_table(crc_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 64-bit z_word_t */ + printf("#ifdef W\n\n"); + printf("#if W == 8\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table64(crc_big_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 32-bit z_word_t */ + printf("#else /* W == 4 */\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table32hi(crc_big_table, 256); + printf("};\n\n"); + printf("#endif\n\n"); + printf("#endif /* W */\n\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + printf("#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t */ + printf("\n"); + printf("#if W == 8\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table64(big[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t */ + printf("\n"); + printf("#else /* W == 4 */\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table32hi(big[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("#endif /* W */\n\n"); + + printf("#endif /* N == %d */\n", n); + } + printf("\n"); + + /* write out zeros operator table */ + printf("static const uint32_t x2n_table[] = {\n"); + printf(" "); + write_table(x2n_table, 32); + printf("};\n"); + + printf("\n"); + printf("#endif /* CRC32_BRAID_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate crc32 tables +int main(int argc, char *argv[]) { + Z_UNUSED(argc); + Z_UNUSED(argv); + + make_crc_table(); + print_crc_table(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/tools/makefixed.c b/internal-complibs/zlib-ng-2.1.1-beta2/tools/makefixed.c new file mode 100644 index 000000000..7fe71e75e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/tools/makefixed.c @@ -0,0 +1,89 @@ +#include +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +// Build and return state with length and distance decoding tables and index sizes set to fixed code decoding. +void Z_INTERNAL buildfixedtables(struct inflate_state *state) { + static code *lenfix, *distfix; + static code fixed[544]; + + // build fixed huffman tables + unsigned sym, bits; + static code *next; + + // literal/length table + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + zng_inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + // distance table + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + zng_inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + + +// Create fixed tables on the fly and write out a inffixed_tbl.h file that is #include'd above. +// makefixed() writes those tables to stdout, which would be piped to inffixed_tbl.h. +void makefixed(void) { + unsigned low, size; + struct inflate_state state; + + memset(&state, 0, sizeof(state)); + buildfixedtables(&state); + puts("/* inffixed_tbl.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts("/* WARNING: this file should *not* be used by applications."); + puts(" * It is part of the implementation of this library and is"); + puts(" * subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf("static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) + printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); + size = 1U << 5; + printf("\nstatic const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) + printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); +} + +// The output of this application can be piped out to recreate inffixed_tbl.h +int main(void) { + makefixed(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/tools/maketrees.c b/internal-complibs/zlib-ng-2.1.1-beta2/tools/maketrees.c new file mode 100644 index 000000000..2c32ccae0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/tools/maketrees.c @@ -0,0 +1,147 @@ +/* maketrees.c -- output static huffman trees + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" + +static ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see zng_tr_init). + */ + +static ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use 5 bits.) + */ + +static unsigned char dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances 3 .. 258, + * the last 256 values correspond to the top 8 bits of the 15 bit distances. + */ + +static unsigned char length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; +/* length code for each normalized match length (0 == STD_MIN_MATCH) */ + +static int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = STD_MIN_MATCH) */ + +static int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + + +static void tr_static_init(void) { + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + length_code[length++] = (unsigned char)code; + } + } + Assert(length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented in two different + * ways: code 284 + 5 bits or code 285, so we overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (unsigned char)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + dist_code[dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) + bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the tree construction + * to get a canonical Huffman tree (longest code all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = PREFIX(bi_reverse)((unsigned)n, 5); + } +} + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +static void gen_trees_header(void) { + int i; + + printf("#ifndef TREES_TBL_H_\n"); + printf("#define TREES_TBL_H_\n\n"); + + printf("/* header created automatically with maketrees.c */\n\n"); + + printf("Z_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + printf("{{%3u},{%u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + printf("Z_INTERNAL const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("{{%2u},{%u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + printf("const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + printf("%2u%s", dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + printf("const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = {\n"); + for (i = 0; i < STD_MAX_MATCH-STD_MIN_MATCH+1; i++) { + printf("%2u%s", length_code[i], SEPARATOR(i, STD_MAX_MATCH-STD_MIN_MATCH, 20)); + } + + printf("Z_INTERNAL const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + printf("%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + printf("Z_INTERNAL const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); + } + + printf("#endif /* TREES_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate trees.h +int main(void) { + tr_static_init(); + gen_trees_header(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/trees.c b/internal-complibs/zlib-ng-2.1.1-beta2/trees.c new file mode 100644 index 000000000..5bb88389b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/trees.c @@ -0,0 +1,818 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2021 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" +#include "trees_emit.h" +#include "trees_tbl.h" + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const int *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + unsigned int max_length; /* max bit length for the codes */ +}; + +static const static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +static const static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +static const static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +static void init_block (deflate_state *s); +static void pqdownheap (deflate_state *s, ct_data *tree, int k); +static void gen_bitlen (deflate_state *s, tree_desc *desc); +static void build_tree (deflate_state *s, tree_desc *desc); +static void scan_tree (deflate_state *s, ct_data *tree, int max_code); +static void send_tree (deflate_state *s, ct_data *tree, int max_code); +static int build_bl_tree (deflate_state *s); +static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); +static void compress_block (deflate_state *s, const ct_data *ltree, const ct_data *dtree); +static int detect_data_type (deflate_state *s); +static void bi_flush (deflate_state *s); + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void Z_INTERNAL zng_tr_init(deflate_state *s) { + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +static void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) + s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) + s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) + s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +static void pqdownheap(deflate_state *s, ct_data *tree, int k) { + /* tree: the tree to restore */ + /* k: node to move down */ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) + break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +static void gen_bitlen(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const int *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + unsigned int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + unsigned int bits; /* bit length */ + int xbits; /* extra bits */ + uint16_t f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) + s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1u; + if (bits > max_length){ + bits = max_length; + overflow++; + } + tree[n].Len = (uint16_t)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) /* not a leaf node */ + continue; + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (unsigned long)f * (unsigned int)(bits + xbits); + if (stree) + s->static_len += (unsigned long)f * (unsigned int)(stree[n].Len + xbits); + } + if (overflow == 0) + return; + + Tracev((stderr, "\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) + bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2u; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) + continue; + if (tree[m].Len != bits) { + Tracev((stderr, "code %d bits %d->%u\n", m, tree[m].Len, bits)); + s->opt_len += (unsigned long)(bits * tree[m].Freq); + s->opt_len -= (unsigned long)(tree[m].Len * tree[m].Freq); + tree[m].Len = (uint16_t)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +Z_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { + /* tree: the tree to decorate */ + /* max_code: largest code with non zero frequency */ + /* bl_count: number of codes at each bit length */ + uint16_t next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned int code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (uint16_t)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert(code + bl_count[MAX_BITS]-1 == (1 << MAX_BITS)-1, "inconsistent bit counts"); + Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) + continue; + /* Now reverse the bits */ + tree[n].Code = PREFIX(bi_reverse)(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n & 0xff) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +static void build_tree(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0; + s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; + if (stree) + s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) + pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (unsigned char)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (uint16_t)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +static void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code: and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + uint16_t count = 0; /* repeat count of the current code */ + uint16_t max_count = 7; /* max repeat count */ + uint16_t min_count = 4; /* min repeat count */ + + if (nextlen == 0) + max_count = 138, min_count = 3; + + tree[max_code+1].Len = (uint16_t)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) + s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +static void send_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) + max_count = 138, min_count = 3; + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 2, bi_buf, bi_valid); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 3, bi_buf, bi_valid); + + } else { + send_code(s, REPZ_11_138, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-11, 7, bi_buf, bi_valid); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +static int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) + break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((unsigned long)max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +static void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes) { + int rank; /* index in bl_order */ + + Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5, bi_buf, bi_valid); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5, bi_buf, bi_valid); + send_bits(s, blcodes-4, 4, bi_buf, bi_valid); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2u ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3, bi_buf, bi_valid); + } + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + zng_tr_emit_tree(s, STORED_BLOCK, last); /* send block type */ + zng_tr_emit_align(s); /* align on byte boundary */ + cmpr_bits_align(s); + put_short(s, (uint16_t)stored_len); + put_short(s, (uint16_t)~stored_len); + cmpr_bits_add(s, 32); + sent_bits_add(s, 32); + if (stored_len) { + memcpy(s->pending_buf + s->pending, (unsigned char *)buf, stored_len); + s->pending += stored_len; + cmpr_bits_add(s, stored_len << 3); + sent_bits_add(s, stored_len << 3); + } +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void Z_INTERNAL zng_tr_align(deflate_state *s) { + zng_tr_emit_tree(s, STATIC_TREES, 0); + zng_tr_emit_end_block(s, static_ltree, 0); + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block, or NULL if too old */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + unsigned long opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (UNLIKELY(s->sym_next == 0)) { + /* Emit an empty static tree block with no codes */ + opt_lenb = static_lenb = 0; + s->static_len = 7; + } else if (s->level > 0) { + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7) >> 3; + static_lenb = (s->static_len+3+7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %u lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) + opt_lenb = static_lenb; + + } else { + Assert(buf != NULL, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if (stored_len+4 <= opt_lenb && buf != NULL) { + /* 4: two words for the lengths + * The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zng_tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + zng_tr_emit_tree(s, STATIC_TREES, last); + compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); + cmpr_bits_add(s, s->static_len); + } else { + zng_tr_emit_tree(s, DYN_TREES, last); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); + cmpr_bits_add(s, s->opt_len); + } + Assert(s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and unsigned long implemented on 32 bits. + */ + init_block(s); + + if (last) { + zng_tr_emit_align(s); + } + Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +static void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { + /* ltree: literal tree */ + /* dtree: distance tree */ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + + if (s->sym_next != 0) { + do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + zng_emit_lit(s, ltree, lc); + } else { + zng_emit_dist(s, ltree, dtree, lc, dist); + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pending_buf overflow"); + } while (sx < s->sym_next); + } + + zng_emit_end_block(s, ltree, 0); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +static int detect_data_type(deflate_state *s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +static void bi_flush(deflate_state *s) { + if (s->bi_valid == 64) { + put_uint64(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else { + if (s->bi_valid >= 32) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid >= 16) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid >= 8) { + put_byte(s, s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } + } +} + +/* =========================================================================== + * Reverse the first len bits of a code using bit manipulation + */ +Z_INTERNAL uint16_t PREFIX(bi_reverse)(unsigned code, int len) { + /* code: the value to invert */ + /* len: its bit length */ + Assert(len >= 1 && len <= 15, "code length must be 1-15"); +#define bitrev8(b) \ + (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32) + return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/trees.h b/internal-complibs/zlib-ng-2.1.1-beta2/trees.h new file mode 100644 index 000000000..e57f92648 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/trees.h @@ -0,0 +1,40 @@ +#ifndef TREES_H_ +#define TREES_H_ + +/* Constants */ + +#define DIST_CODE_LEN 512 +/* see definition of array dist_code in trees.c */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +static const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const unsigned char bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + /* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + + +/* Function definitions */ +void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/trees_emit.h b/internal-complibs/zlib-ng-2.1.1-beta2/trees_emit.h new file mode 100644 index 000000000..922daae50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/trees_emit.h @@ -0,0 +1,227 @@ +#ifndef TREES_EMIT_H_ +#define TREES_EMIT_H_ + +#include "zbuild.h" +#include "trees.h" + +#ifdef ZLIB_DEBUG +# include +# include +#endif + + +/* trees.h */ +extern Z_INTERNAL const ct_data static_ltree[L_CODES+2]; +extern Z_INTERNAL const ct_data static_dtree[D_CODES]; + +extern const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN]; +extern const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; + +extern Z_INTERNAL const int base_length[LENGTH_CODES]; +extern Z_INTERNAL const int base_dist[D_CODES]; + +/* Bit buffer and deflate code stderr tracing */ +#ifdef ZLIB_DEBUG +# define send_bits_trace(s, value, length) { \ + Tracevv((stderr, " l %2d v %4llx ", (int)(length), (long long)(value))); \ + Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ + } +# define send_code_trace(s, c) \ + if (z_verbose > 2) { \ + fprintf(stderr, "\ncd %3d ", (c)); \ + } +#else +# define send_bits_trace(s, value, length) +# define send_code_trace(s, c) +#endif + +/* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid)) + * unused bits in value. + */ +#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\ + uint64_t val = (uint64_t)t_val;\ + uint32_t len = (uint32_t)t_len;\ + uint32_t total_bits = bi_valid + len;\ + send_bits_trace(s, val, len);\ + sent_bits_add(s, len);\ + if (total_bits < BIT_BUF_SIZE) {\ + bi_buf |= val << bi_valid;\ + bi_valid = total_bits;\ + } else if (bi_valid == BIT_BUF_SIZE) {\ + put_uint64(s, bi_buf);\ + bi_buf = val;\ + bi_valid = len;\ + } else {\ + bi_buf |= val << bi_valid;\ + put_uint64(s, bi_buf);\ + bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\ + bi_valid = total_bits - BIT_BUF_SIZE;\ + }\ +} + +/* Send a code of the given tree. c and tree must not have side effects */ +#ifdef ZLIB_DEBUG +# define send_code(s, c, tree, bi_buf, bi_valid) { \ + send_code_trace(s, c); \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \ +} +#else +# define send_code(s, c, tree, bi_buf, bi_valid) \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid) +#endif + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +static void bi_windup(deflate_state *s) { + if (s->bi_valid > 56) { + put_uint64(s, s->bi_buf); + } else { + if (s->bi_valid > 24) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid > 8) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid > 0) { + put_byte(s, s->bi_buf); + } + } + s->bi_buf = 0; + s->bi_valid = 0; +} + +/* =========================================================================== + * Emit literal code + */ +static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + send_code(s, c, ltree, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + Tracecv(isgraph(c & 0xff), (stderr, " '%c' ", c)); + + return ltree[c].Len; +} + +/* =========================================================================== + * Emit match distance/length code + */ +static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + uint32_t c, extra; + uint8_t code; + uint64_t match_bits; + uint32_t match_bits_len; + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + /* Send the length code, len is the match length - STD_MIN_MATCH */ + code = zng_length_code[lc]; + c = code+LITERALS+1; + Assert(c < L_CODES, "bad l_code"); + send_code_trace(s, c); + + match_bits = ltree[c].Code; + match_bits_len = ltree[c].Len; + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + match_bits |= ((uint64_t)lc << match_bits_len); + match_bits_len += extra; + } + + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert(code < D_CODES, "bad d_code"); + send_code_trace(s, code); + + /* Send the distance code */ + match_bits |= ((uint64_t)dtree[code].Code << match_bits_len); + match_bits_len += dtree[code].Len; + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + match_bits |= ((uint64_t)dist << match_bits_len); + match_bits_len += extra; + } + + send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + return match_bits_len; +} + +/* =========================================================================== + * Emit end block + */ +static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n", + last, s->pending, (uint64_t)s->strm->total_out)); + Z_UNUSED(last); +} + +/* =========================================================================== + * Emit literal and count bits + */ +static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); +} + +/* =========================================================================== + * Emit match and count bits + */ +static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); +} + +/* =========================================================================== + * Emit start of block + */ +static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + uint32_t header_bits = (type << 1) + last; + send_bits(s, header_bits, 3, bi_buf, bi_valid); + cmpr_bits_add(s, 3); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last)); +} + +/* =========================================================================== + * Align bit buffer on a byte boundary and count bits + */ +static inline void zng_tr_emit_align(deflate_state *s) { + bi_windup(s); /* align on byte boundary */ + sent_bits_align(s); +} + +/* =========================================================================== + * Emit an end block and align bit buffer if last block + */ +static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + zng_emit_end_block(s, ltree, last); + cmpr_bits_add(s, 7); + if (last) + zng_tr_emit_align(s); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/trees_tbl.h b/internal-complibs/zlib-ng-2.1.1-beta2/trees_tbl.h new file mode 100644 index 000000000..a3912b7fd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/trees_tbl.h @@ -0,0 +1,132 @@ +#ifndef TREES_TBL_H_ +#define TREES_TBL_H_ + +/* header created automatically with maketrees.c */ + +Z_INTERNAL const ct_data static_ltree[L_CODES+2] = { +{{ 12},{8}}, {{140},{8}}, {{ 76},{8}}, {{204},{8}}, {{ 44},{8}}, +{{172},{8}}, {{108},{8}}, {{236},{8}}, {{ 28},{8}}, {{156},{8}}, +{{ 92},{8}}, {{220},{8}}, {{ 60},{8}}, {{188},{8}}, {{124},{8}}, +{{252},{8}}, {{ 2},{8}}, {{130},{8}}, {{ 66},{8}}, {{194},{8}}, +{{ 34},{8}}, {{162},{8}}, {{ 98},{8}}, {{226},{8}}, {{ 18},{8}}, +{{146},{8}}, {{ 82},{8}}, {{210},{8}}, {{ 50},{8}}, {{178},{8}}, +{{114},{8}}, {{242},{8}}, {{ 10},{8}}, {{138},{8}}, {{ 74},{8}}, +{{202},{8}}, {{ 42},{8}}, {{170},{8}}, {{106},{8}}, {{234},{8}}, +{{ 26},{8}}, {{154},{8}}, {{ 90},{8}}, {{218},{8}}, {{ 58},{8}}, +{{186},{8}}, {{122},{8}}, {{250},{8}}, {{ 6},{8}}, {{134},{8}}, +{{ 70},{8}}, {{198},{8}}, {{ 38},{8}}, {{166},{8}}, {{102},{8}}, +{{230},{8}}, {{ 22},{8}}, {{150},{8}}, {{ 86},{8}}, {{214},{8}}, +{{ 54},{8}}, {{182},{8}}, {{118},{8}}, {{246},{8}}, {{ 14},{8}}, +{{142},{8}}, {{ 78},{8}}, {{206},{8}}, {{ 46},{8}}, {{174},{8}}, +{{110},{8}}, {{238},{8}}, {{ 30},{8}}, {{158},{8}}, {{ 94},{8}}, +{{222},{8}}, {{ 62},{8}}, {{190},{8}}, {{126},{8}}, {{254},{8}}, +{{ 1},{8}}, {{129},{8}}, {{ 65},{8}}, {{193},{8}}, {{ 33},{8}}, +{{161},{8}}, {{ 97},{8}}, {{225},{8}}, {{ 17},{8}}, {{145},{8}}, +{{ 81},{8}}, {{209},{8}}, {{ 49},{8}}, {{177},{8}}, {{113},{8}}, +{{241},{8}}, {{ 9},{8}}, {{137},{8}}, {{ 73},{8}}, {{201},{8}}, +{{ 41},{8}}, {{169},{8}}, {{105},{8}}, {{233},{8}}, {{ 25},{8}}, +{{153},{8}}, {{ 89},{8}}, {{217},{8}}, {{ 57},{8}}, {{185},{8}}, +{{121},{8}}, {{249},{8}}, {{ 5},{8}}, {{133},{8}}, {{ 69},{8}}, +{{197},{8}}, {{ 37},{8}}, {{165},{8}}, {{101},{8}}, {{229},{8}}, +{{ 21},{8}}, {{149},{8}}, {{ 85},{8}}, {{213},{8}}, {{ 53},{8}}, +{{181},{8}}, {{117},{8}}, {{245},{8}}, {{ 13},{8}}, {{141},{8}}, +{{ 77},{8}}, {{205},{8}}, {{ 45},{8}}, {{173},{8}}, {{109},{8}}, +{{237},{8}}, {{ 29},{8}}, {{157},{8}}, {{ 93},{8}}, {{221},{8}}, +{{ 61},{8}}, {{189},{8}}, {{125},{8}}, {{253},{8}}, {{ 19},{9}}, +{{275},{9}}, {{147},{9}}, {{403},{9}}, {{ 83},{9}}, {{339},{9}}, +{{211},{9}}, {{467},{9}}, {{ 51},{9}}, {{307},{9}}, {{179},{9}}, +{{435},{9}}, {{115},{9}}, {{371},{9}}, {{243},{9}}, {{499},{9}}, +{{ 11},{9}}, {{267},{9}}, {{139},{9}}, {{395},{9}}, {{ 75},{9}}, +{{331},{9}}, {{203},{9}}, {{459},{9}}, {{ 43},{9}}, {{299},{9}}, +{{171},{9}}, {{427},{9}}, {{107},{9}}, {{363},{9}}, {{235},{9}}, +{{491},{9}}, {{ 27},{9}}, {{283},{9}}, {{155},{9}}, {{411},{9}}, +{{ 91},{9}}, {{347},{9}}, {{219},{9}}, {{475},{9}}, {{ 59},{9}}, +{{315},{9}}, {{187},{9}}, {{443},{9}}, {{123},{9}}, {{379},{9}}, +{{251},{9}}, {{507},{9}}, {{ 7},{9}}, {{263},{9}}, {{135},{9}}, +{{391},{9}}, {{ 71},{9}}, {{327},{9}}, {{199},{9}}, {{455},{9}}, +{{ 39},{9}}, {{295},{9}}, {{167},{9}}, {{423},{9}}, {{103},{9}}, +{{359},{9}}, {{231},{9}}, {{487},{9}}, {{ 23},{9}}, {{279},{9}}, +{{151},{9}}, {{407},{9}}, {{ 87},{9}}, {{343},{9}}, {{215},{9}}, +{{471},{9}}, {{ 55},{9}}, {{311},{9}}, {{183},{9}}, {{439},{9}}, +{{119},{9}}, {{375},{9}}, {{247},{9}}, {{503},{9}}, {{ 15},{9}}, +{{271},{9}}, {{143},{9}}, {{399},{9}}, {{ 79},{9}}, {{335},{9}}, +{{207},{9}}, {{463},{9}}, {{ 47},{9}}, {{303},{9}}, {{175},{9}}, +{{431},{9}}, {{111},{9}}, {{367},{9}}, {{239},{9}}, {{495},{9}}, +{{ 31},{9}}, {{287},{9}}, {{159},{9}}, {{415},{9}}, {{ 95},{9}}, +{{351},{9}}, {{223},{9}}, {{479},{9}}, {{ 63},{9}}, {{319},{9}}, +{{191},{9}}, {{447},{9}}, {{127},{9}}, {{383},{9}}, {{255},{9}}, +{{511},{9}}, {{ 0},{7}}, {{ 64},{7}}, {{ 32},{7}}, {{ 96},{7}}, +{{ 16},{7}}, {{ 80},{7}}, {{ 48},{7}}, {{112},{7}}, {{ 8},{7}}, +{{ 72},{7}}, {{ 40},{7}}, {{104},{7}}, {{ 24},{7}}, {{ 88},{7}}, +{{ 56},{7}}, {{120},{7}}, {{ 4},{7}}, {{ 68},{7}}, {{ 36},{7}}, +{{100},{7}}, {{ 20},{7}}, {{ 84},{7}}, {{ 52},{7}}, {{116},{7}}, +{{ 3},{8}}, {{131},{8}}, {{ 67},{8}}, {{195},{8}}, {{ 35},{8}}, +{{163},{8}}, {{ 99},{8}}, {{227},{8}} +}; + +Z_INTERNAL const ct_data static_dtree[D_CODES] = { +{{ 0},{5}}, {{16},{5}}, {{ 8},{5}}, {{24},{5}}, {{ 4},{5}}, +{{20},{5}}, {{12},{5}}, {{28},{5}}, {{ 2},{5}}, {{18},{5}}, +{{10},{5}}, {{26},{5}}, {{ 6},{5}}, {{22},{5}}, {{14},{5}}, +{{30},{5}}, {{ 1},{5}}, {{17},{5}}, {{ 9},{5}}, {{25},{5}}, +{{ 5},{5}}, {{21},{5}}, {{13},{5}}, {{29},{5}}, {{ 3},{5}}, +{{19},{5}}, {{11},{5}}, {{27},{5}}, {{ 7},{5}}, {{23},{5}} +}; + +const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +Z_INTERNAL const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +Z_INTERNAL const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + +#endif /* TREES_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/uncompr.c b/internal-complibs/zlib-ng-2.1.1-beta2/uncompr.c new file mode 100644 index 000000000..311eca2b0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/uncompr.c @@ -0,0 +1,80 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int Z_EXPORT PREFIX(uncompress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t *sourceLen) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_uintmax_t len, left; + unsigned char buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(inflateInit)(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (unsigned long)max ? max : (unsigned int)len; + len -= stream.avail_in; + } + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = (z_size_t)stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + PREFIX(inflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int Z_EXPORT PREFIX(uncompress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(uncompress2)(dest, destLen, source, &sourceLen); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.a64 b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.a64 new file mode 100644 index 000000000..2a0f3cfe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.a64 @@ -0,0 +1,243 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.a64 (standard build) +# nmake -f win32/Makefile.a64 LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_NEON_HASLD4 \ + -DARM_FEATURES \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM64 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_quick.obj \ + deflate_medium.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +WFLAGS = $(WFLAGS) \ + -DARM_ACLE \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x55A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_neon.obj: $(SRCDIR)/arch/arm/slide_hash_neon.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.arm b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.arm new file mode 100644 index 000000000..7d3f1b58a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.arm @@ -0,0 +1,255 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.arm (standard build) +# nmake -f win32/Makefile.arm LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_FEATURES \ + -DARM_NEON_HASLD4 \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +WITH_ACLE = +WITH_NEON = +WITH_VFPV3 = +NEON_ARCH = /arch:VFPv4 +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +!if "$(WITH_ACLE)" != "" +WFLAGS = $(WFLAGS) -DARM_ACLE +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj +!endif +!if "$(WITH_VFPV3)" != "" +NEON_ARCH = /arch:VFPv3 +!endif +!if "$(WITH_NEON)" != "" +CFLAGS = $(CFLAGS) $(NEON_ARCH) +WFLAGS = $(WFLAGS) \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.msc b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.msc new file mode 100644 index 000000000..9ed26f283 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/Makefile.msc @@ -0,0 +1,266 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DX86_FEATURES \ + -DX86_PCLMULQDQ_CRC \ + -DX86_SSE2 \ + -DX86_SSE42 \ + -DX86_SSE42_CRC_INTRIN \ + -DX86_SSSE3 \ + -DX86_AVX2 + +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_avx2.obj \ + adler32_avx512.obj \ + adler32_avx512_vnni.obj \ + adler32_sse42.obj \ + adler32_ssse3.obj \ + adler32_fold.obj \ + chunkset.obj \ + chunkset_avx2.obj \ + chunkset_sse2.obj \ + chunkset_ssse3.obj \ + compare256.obj \ + compare256_avx2.obj \ + compare256_sse2.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + crc32_pclmulqdq.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + insert_string_sse42.obj \ + slide_hash.obj \ + slide_hash_avx2.obj \ + slide_hash_sse2.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + x86_features.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/x86}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_avx2.obj: $(SRCDIR)/arch/x86/adler32_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/fallback_builtins.h +adler32_avx512.obj: $(SRCDIR)/arch/x86/adler32_avx512.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_avx512_vnni.obj: $(SRCDIR)/arch/x86/adler32_avx512_vnni.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_sse42.obj: $(SRCDIR)/arch/x86/adler32_sse42.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_ssse3.obj: $(SRCDIR)/arch/x86/adler32_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_avx2.obj: $(SRCDIR)/arch/x86/chunkset_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_sse2.obj: $(SRCDIR)/arch/x86/chunkset_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_ssse3.obj: $(SRCDIR)/arch/x86/chunkset_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +crc32_pclmulqdq.obj: $(SRCDIR)/arch/x86/crc32_pclmulqdq.c $(SRCDIR)/arch/x86/crc32_pclmulqdq_tpl.h $(SRCDIR)/arch/x86/crc32_fold_pclmulqdq_tpl.h \ + $(SRCDIR)/crc32_fold.h $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_avx2.obj: $(SRCDIR)/arch/x86/slide_hash_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_sse2.obj: $(SRCDIR)/arch/x86/slide_hash_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/replace.vbs b/internal-complibs/zlib-ng-2.1.1-beta2/win32/replace.vbs new file mode 100644 index 000000000..6779971d0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/replace.vbs @@ -0,0 +1,15 @@ +strInputFileName = Wscript.Arguments(0) +strOutputFileName = Wscript.Arguments(1) +strOldText = Wscript.Arguments(2) +strNewText = Wscript.Arguments(3) + +Set objFSO = CreateObject("Scripting.FileSystemObject") +Set objFile = objFSO.OpenTextFile(strInputFileName, 1) + +strText = objFile.ReadAll +objFile.Close +strNewText = Replace(strText, strOldText, strNewText) + +Set objFile = objFSO.OpenTextFile(strOutputFileName, 2, True) +objFile.Write strNewText +objFile.Close diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng.def.in b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng.def.in new file mode 100644 index 000000000..53b2bc21f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng.def.in @@ -0,0 +1,60 @@ +; zlib-ng data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibng_version + @ZLIB_SYMBOL_PREFIX@zng_deflate + @ZLIB_SYMBOL_PREFIX@zng_deflateEnd + @ZLIB_SYMBOL_PREFIX@zng_deflateInit + @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflate + @ZLIB_SYMBOL_PREFIX@zng_inflateEnd + @ZLIB_SYMBOL_PREFIX@zng_inflateInit + @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +; advanced functions + @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateCopy + @ZLIB_SYMBOL_PREFIX@zng_deflateReset + @ZLIB_SYMBOL_PREFIX@zng_deflateParams + @ZLIB_SYMBOL_PREFIX@zng_deflateTune + @ZLIB_SYMBOL_PREFIX@zng_deflateBound + @ZLIB_SYMBOL_PREFIX@zng_deflatePending + @ZLIB_SYMBOL_PREFIX@zng_deflatePrime + @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader + @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams + @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateSync + @ZLIB_SYMBOL_PREFIX@zng_inflateCopy + @ZLIB_SYMBOL_PREFIX@zng_inflateReset + @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 + @ZLIB_SYMBOL_PREFIX@zng_inflatePrime + @ZLIB_SYMBOL_PREFIX@zng_inflateMark + @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader + @ZLIB_SYMBOL_PREFIX@zng_inflateBack + @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@zng_compress + @ZLIB_SYMBOL_PREFIX@zng_compress2 + @ZLIB_SYMBOL_PREFIX@zng_compressBound + @ZLIB_SYMBOL_PREFIX@zng_uncompress + @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +; checksum functions + @ZLIB_SYMBOL_PREFIX@zng_adler32 + @ZLIB_SYMBOL_PREFIX@zng_adler32_z + @ZLIB_SYMBOL_PREFIX@zng_crc32 + @ZLIB_SYMBOL_PREFIX@zng_crc32_z + @ZLIB_SYMBOL_PREFIX@zng_adler32_combine + @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@zng_zError + @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@zng_get_crc_table + @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine + @ZLIB_SYMBOL_PREFIX@zng_inflateValidate + @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep + @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng1.rc b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng1.rc new file mode 100644 index 000000000..327f17fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib-ng1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib-ng.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + PRODUCTVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIBNG_VERSION "\0" + VALUE "InternalName", "zlib-ng1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib-ng1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIBNG_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib.def.in b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib.def.in new file mode 100644 index 000000000..561a42f7f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib.def.in @@ -0,0 +1,64 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 +; large file functions + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib1.rc b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib1.rc new file mode 100644 index 000000000..73bc4389c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlib1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlibcompat.def.in b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlibcompat.def.in new file mode 100644 index 000000000..52a713cf0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/win32/zlibcompat.def.in @@ -0,0 +1,97 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 + @ZLIB_SYMBOL_PREFIX@gzopen + @ZLIB_SYMBOL_PREFIX@gzdopen + @ZLIB_SYMBOL_PREFIX@gzbuffer + @ZLIB_SYMBOL_PREFIX@gzsetparams + @ZLIB_SYMBOL_PREFIX@gzread + @ZLIB_SYMBOL_PREFIX@gzfread + @ZLIB_SYMBOL_PREFIX@gzwrite + @ZLIB_SYMBOL_PREFIX@gzfwrite + @ZLIB_SYMBOL_PREFIX@gzprintf + @ZLIB_SYMBOL_PREFIX@gzvprintf + @ZLIB_SYMBOL_PREFIX@gzputs + @ZLIB_SYMBOL_PREFIX@gzgets + @ZLIB_SYMBOL_PREFIX@gzputc + @ZLIB_SYMBOL_PREFIX@gzgetc + @ZLIB_SYMBOL_PREFIX@gzungetc + @ZLIB_SYMBOL_PREFIX@gzflush + @ZLIB_SYMBOL_PREFIX@gzseek + @ZLIB_SYMBOL_PREFIX@gzrewind + @ZLIB_SYMBOL_PREFIX@gztell + @ZLIB_SYMBOL_PREFIX@gzoffset + @ZLIB_SYMBOL_PREFIX@gzeof + @ZLIB_SYMBOL_PREFIX@gzdirect + @ZLIB_SYMBOL_PREFIX@gzclose + @ZLIB_SYMBOL_PREFIX@gzclose_r + @ZLIB_SYMBOL_PREFIX@gzclose_w + @ZLIB_SYMBOL_PREFIX@gzerror + @ZLIB_SYMBOL_PREFIX@gzclearerr +; large file functions + @ZLIB_SYMBOL_PREFIX@gzopen64 + @ZLIB_SYMBOL_PREFIX@gzseek64 + @ZLIB_SYMBOL_PREFIX@gztell64 + @ZLIB_SYMBOL_PREFIX@gzoffset64 + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@gzgetc_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep + @ZLIB_SYMBOL_PREFIX@gzopen_w diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zbuild.h b/internal-complibs/zlib-ng-2.1.1-beta2/zbuild.h new file mode 100644 index 000000000..525a34d8d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zbuild.h @@ -0,0 +1,248 @@ +#ifndef _ZBUILD_H +#define _ZBUILD_H + +#define _POSIX_SOURCE 1 /* fileno */ +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200809L /* snprintf, posix_memalign, strdup */ +#endif +#ifndef _ISOC11_SOURCE +# define _ISOC11_SOURCE 1 /* aligned_alloc */ +#endif +#ifdef __OpenBSD__ +# define _BSD_SOURCE 1 +#endif + +#include +#include +#include +#include + +/* Determine compiler version of C Standard */ +#ifdef __STDC_VERSION__ +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +# if __STDC_VERSION__ >= 201112L +# ifndef STDC11 +# define STDC11 +# endif +# endif +#endif + +/* Determine compiler support for TLS */ +#ifndef Z_TLS +# ifdef HAVE_THREAD_LOCAL +# define Z_TLS _Thread_local +# elif defined(__GNUC__) || defined(__SUNPRO_C) +# define Z_TLS __thread +# elif defined(_WIN32) && (defined(_MSC_VER) || defined(__ICL)) +# define Z_TLS __declspec(thread) +# else +# warning Unable to detect Thread Local Storage support. +# define Z_TLS +# endif +#endif + +#ifndef Z_HAS_ATTRIBUTE +# if defined(__has_attribute) +# define Z_HAS_ATTRIBUTE(a) __has_attribute(a) +# else +# define Z_HAS_ATTRIBUTE(a) 0 +# endif +#endif + +#ifndef Z_FALLTHROUGH +# if Z_HAS_ATTRIBUTE(__fallthrough__) || (defined(__GNUC__) && (__GNUC__ >= 7)) +# define Z_FALLTHROUGH __attribute__((__fallthrough__)) +# else +# define Z_FALLTHROUGH do {} while(0) /* fallthrough */ +# endif +#endif + +/* This has to be first include that defines any types */ +#if defined(_MSC_VER) +# if defined(_WIN64) + typedef __int64 ssize_t; +# else + typedef long ssize_t; +# endif + +# if defined(_WIN64) + #define SSIZE_MAX _I64_MAX +# else + #define SSIZE_MAX LONG_MAX +# endif +#endif + +/* MS Visual Studio does not allow inline in C, only C++. + But it provides __inline instead, so use that. */ +#if defined(_MSC_VER) && !defined(inline) && !defined(__cplusplus) +# define inline __inline +#endif + +#if defined(ZLIB_COMPAT) +# define PREFIX(x) x +# define PREFIX2(x) ZLIB_ ## x +# define PREFIX3(x) z_ ## x +# define PREFIX4(x) x ## 64 +# define zVersion zlibVersion +#else +# define PREFIX(x) zng_ ## x +# define PREFIX2(x) ZLIBNG_ ## x +# define PREFIX3(x) zng_ ## x +# define PREFIX4(x) zng_ ## x +# define zVersion zlibng_version +# define z_size_t size_t +#endif + +/* In zlib-compat some functions and types use unsigned long, but zlib-ng use size_t */ +#if defined(ZLIB_COMPAT) +# define z_uintmax_t unsigned long +#else +# define z_uintmax_t size_t +#endif + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) +/* Maximum of a and b. */ +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +/* Ignore unused variable warning */ +#define Z_UNUSED(var) (void)(var) + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#ifndef __cplusplus +# define Z_REGISTER register +#else +# define Z_REGISTER +#endif + +/* Reverse the bytes in a value. Use compiler intrinsics when + possible to take advantage of hardware implementations. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +# include +# pragma intrinsic(_byteswap_ulong) +# define ZSWAP16(q) _byteswap_ushort(q) +# define ZSWAP32(q) _byteswap_ulong(q) +# define ZSWAP64(q) _byteswap_uint64(q) + +#elif defined(__clang__) || (defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +# define ZSWAP16(q) __builtin_bswap16(q) +# define ZSWAP32(q) __builtin_bswap32(q) +# define ZSWAP64(q) __builtin_bswap64(q) + +#elif defined(__GNUC__) && (__GNUC__ >= 2) && defined(__linux__) +# include +# define ZSWAP16(q) bswap_16(q) +# define ZSWAP32(q) bswap_32(q) +# define ZSWAP64(q) bswap_64(q) + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +# include +# define ZSWAP16(q) bswap16(q) +# define ZSWAP32(q) bswap32(q) +# define ZSWAP64(q) bswap64(q) +#elif defined(__OpenBSD__) +# include +# define ZSWAP16(q) swap16(q) +# define ZSWAP32(q) swap32(q) +# define ZSWAP64(q) swap64(q) +#elif defined(__INTEL_COMPILER) +/* ICC does not provide a two byte swap. */ +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) _bswap(q) +# define ZSWAP64(q) _bswap64(q) + +#else +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) +# define ZSWAP64(q) \ + (((q & 0xFF00000000000000u) >> 56u) | \ + ((q & 0x00FF000000000000u) >> 40u) | \ + ((q & 0x0000FF0000000000u) >> 24u) | \ + ((q & 0x000000FF00000000u) >> 8u) | \ + ((q & 0x00000000FF000000u) << 8u) | \ + ((q & 0x0000000000FF0000u) << 24u) | \ + ((q & 0x000000000000FF00u) << 40u) | \ + ((q & 0x00000000000000FFu) << 56u)) +#endif + +/* Only enable likely/unlikely if the compiler is known to support it */ +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__INTEL_COMPILER) || defined(__clang__) +# define LIKELY_NULL(x) __builtin_expect((x) != 0, 0) +# define LIKELY(x) __builtin_expect(!!(x), 1) +# define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +# define LIKELY_NULL(x) x +# define LIKELY(x) x +# define UNLIKELY(x) x +#endif /* (un)likely */ + +#if defined(HAVE_ATTRIBUTE_ALIGNED) +# define ALIGNED_(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +# define ALIGNED_(x) __declspec(align(x)) +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int Z_INTERNAL z_verbose; + extern void Z_INTERNAL z_error(const char *m); +# define Assert(cond, msg) {if (!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose >= 0) fprintf x;} +# define Tracev(x) {if (z_verbose > 0) fprintf x;} +# define Tracevv(x) {if (z_verbose > 1) fprintf x;} +# define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x;} +# define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x;} +#else +# define Assert(cond, msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c, x) +# define Tracecv(c, x) +#endif + +#ifndef NO_UNALIGNED +# if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) || defined(_M_AMD64) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(_X86_) || defined(_M_IX86) +# define UNALIGNED_OK +# elif defined(__aarch64__) || defined(_M_ARM64) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# elif defined(__arm__) || (_M_ARM >= 7) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# endif +# elif defined(__powerpc64__) || defined(__ppc64__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# endif +#endif + +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# define Z_MEMORY_SANITIZER 1 +# include +# endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zconf-ng.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zconf-ng.h.in new file mode 100644 index 000000000..226f06a03 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zconf-ng.h.in @@ -0,0 +1,176 @@ +/* zconf-ng.h -- configuration of the zlib-ng compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONFNG_H +#define ZCONFNG_H + +#include "zlib_name_mangling-ng.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +/* Always define z_const as const */ +#define z_const const + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_EXPORT + +/* Fallback for something that includes us. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && defined(WITH_GZFILEOP) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +#endif /* ZCONFNG_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zconf.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zconf.h.in new file mode 100644 index 000000000..074f02551 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zconf.h.in @@ -0,0 +1,203 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONF_H +#define ZCONF_H + +#include "zlib_name_mangling.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + + +#ifndef OF /* function prototypes */ +# define OF(args) args +#endif + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_INTERNAL + +/* For backwards compatibility */ + +#ifndef ZEXTERN +# define ZEXTERN Z_EXTERN +#endif +#ifndef ZEXPORT +# define ZEXPORT Z_EXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA Z_EXPORTVA +#endif + +/* Legacy zlib typedefs for backwards compatibility. Don't assume stdint.h is defined. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +typedef unsigned int z_crc_t; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +typedef size_t z_size_t; + +#endif /* ZCONF_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zendian.h b/internal-complibs/zlib-ng-2.1.1-beta2/zendian.h new file mode 100644 index 000000000..3fdb13041 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zendian.h @@ -0,0 +1,60 @@ +/* zendian.h -- define BYTE_ORDER for endian tests + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ENDIAN_H_ +#define ENDIAN_H_ + +/* First check whether the compiler knows the target __BYTE_ORDER__. */ +#if defined(__BYTE_ORDER__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER BIG_ENDIAN +# endif +# endif +#elif defined(__MINGW32__) +# include +#elif defined(_WIN32) +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) || defined (_M_ARM64) +# define BYTE_ORDER LITTLE_ENDIAN +# else +# error Unknown endianness! +# endif +#elif defined(__linux__) +# include +#elif defined(__APPLE__) +# include +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) +# include +#elif defined(__sun) || defined(sun) +# include +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN 4321 +# endif +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN 1234 +# endif +# if !defined(BYTE_ORDER) +# if defined(_BIG_ENDIAN) +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# endif +#else +# include +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.h.in new file mode 100644 index 000000000..3c2c60a54 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.h.in @@ -0,0 +1,1867 @@ +#ifndef ZNGLIB_H_ +#define ZNGLIB_H_ +/* zlib-ng.h -- interface of the 'zlib-ng' compression library, forked from zlib. + + Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf-ng.h" + +#ifndef ZCONFNG_H +# error Missing zconf-ng.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.1.beta2" +#define ZLIBNG_VERNUM 0x02010120L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 1 +#define ZLIBNG_VER_STATUS 2 /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct zng_stream_s { + const uint8_t *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + size_t total_in; /* total number of input bytes read so far */ + + uint8_t *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + size_t total_out; /* total number of bytes output so far */ + + const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uint32_t adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} zng_stream; + +typedef zng_stream *zng_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct zng_gz_header_s { + int32_t text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int32_t xflags; /* extra flags (not used when writing a gzip file) */ + int32_t os; /* operating system */ + uint8_t *extra; /* pointer to extra field or NULL if none */ + uint32_t extra_len; /* extra field length (valid if extra != NULL) */ + uint32_t extra_max; /* space at extra (only when reading header) */ + uint8_t *name; /* pointer to zero-terminated file name or NULL */ + uint32_t name_max; /* space at name (only when reading header) */ + uint8_t *comment; /* pointer to zero-terminated comment or NULL */ + uint32_t comm_max; /* space at comment (only when reading header) */ + int32_t hcrc; /* true if there was or will be a header crc */ + int32_t done; /* true when done reading gzip header (not used when writing a gzip file) */ +} zng_gz_header; + +typedef zng_gz_header *zng_gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + + + /* basic functions */ + +Z_EXTERN Z_EXPORT +const char *zlibng_version(void); +/* The application can compare zlibng_version and ZLIBNG_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib-ng.h header file used by the application. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit(zng_stream *strm, int32_t level); +/* + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level. + msg is set to null if there is no error message. deflateInit does not perform + any compression: this will be done by deflate(). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflate(zng_stream *strm, int32_t flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit(zng_stream *strm); +/* + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit does not perform any decompression. Actual decompression will + be done by inflate(). So next_in, and avail_in, next_out, and avail_out + are unused and unchanged. The current implementation of inflateInit() + does not process any header information -- that is deferred until inflate() + is called. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflate(zng_stream *strm, int32_t flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit2(zng_stream *strm, int32_t level, int32_t method, int32_t windowBits, int32_t memLevel, int32_t strategy); +/* + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method). + msg is set to null if there is no error message. deflateInit2 does not perform + any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateReset(zng_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateParams(zng_stream *strm, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateTune(zng_stream *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN Z_EXPORT +unsigned long zng_deflateBound(zng_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePending(zng_stream *strm, uint32_t *pending, int32_t *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetHeader(zng_stream *strm, zng_gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided zng_gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit2(zng_stream *strm, int32_t windowBits); +/* + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit2 does not perform any decompression apart from possibly reading + the zlib header if present: actual decompression will be done by inflate(). + (So next_in and avail_in may be modified, but next_out and avail_out are + unused and unchanged.) The current implementation of inflateInit2() does not + process any header information -- that is deferred until inflate() is called. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSync(zng_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset(zng_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset2(zng_stream *strm, int32_t windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +long zng_inflateMark(zng_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetHeader(zng_stream *strm, zng_gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided zng_gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackInit(zng_stream *strm, int32_t windowBits, uint8_t *window); +/* + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated. +*/ + +typedef uint32_t (*in_func) (void *, const uint8_t * *); +typedef int32_t (*out_func) (void *, uint8_t *, uint32_t); + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBack(zng_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackEnd(zng_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +unsigned long zng_zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen, int32_t level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_compressBound(size_t sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + +#ifdef WITH_GZFILEOP + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +Z_EXTERN Z_EXPORT +gzFile zng_gzopen(const char *path, const char *mode); +/* + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN Z_EXPORT +gzFile zng_gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzbuffer(gzFile file, uint32_t size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzsetparams(gzFile file, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzread(gzFile file, void *buf, uint32_t len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfread(void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzwrite(gzFile file, void const *buf, uint32_t len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORTVA +int32_t zng_gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +char * zng_gzgets(gzFile file, char *buf, int32_t len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputc(gzFile file, int32_t c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzungetc(int32_t c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzflush(gzFile file, int32_t flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzseek(gzFile file, z_off64_t offset, int whence); +/* + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gztell(gzFile file); +/* + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzoffset(gzFile file); +/* + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_r(gzFile file); +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN Z_EXPORT +const char * zng_gzerror(gzFile file, int32_t *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN Z_EXPORT +void zng_gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* WITH_GZFILEOP */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32(uint32_t adler, const uint8_t *buf, uint32_t len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_z(uint32_t adler, const uint8_t *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_combine(uint32_t adler1, uint32_t adler2, z_off64_t len2); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32(uint32_t crc, const uint8_t *buf, uint32_t len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_z(uint32_t crc, const uint8_t *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine(uint32_t crc1, uint32_t crc2, z_off64_t len2); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_gen(z_off64_t len2); + +/* + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_op(uint32_t crc1, uint32_t crc2, const uint32_t op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + /* various hacks, don't look :) */ + +#ifdef WITH_GZFILEOP + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +# define @ZLIB_SYMBOL_PREFIX@zng_gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@zng_gzgetc)(g)) + +#endif /* WITH_GZFILEOP */ + + +typedef enum { + Z_DEFLATE_LEVEL = 0, /* compression level, represented as an int */ + Z_DEFLATE_STRATEGY = 1, /* compression strategy, represented as an int */ + Z_DEFLATE_REPRODUCIBLE = 2, + /* + Whether reproducible compression results are required. Represented as an int, where 0 means that it is allowed + to trade reproducibility for e.g. improved performance or compression ratio, and non-0 means that + reproducibility is strictly required. Reproducibility is guaranteed only when using an identical zlib-ng build. + Default is 0. + */ +} zng_deflate_param; + +typedef struct { + zng_deflate_param param; /* parameter ID */ + void *buf; /* parameter value */ + size_t size; /* parameter value size */ + int32_t status; /* result of the last set/get call */ +} zng_deflate_param_value; + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Sets the values of the given zlib-ng deflate stream parameters. All the buffers are copied internally, so the + caller still owns them after this function returns. Returns Z_OK if success. + + If the size of at least one of the buffers is too small to hold the entire value of the corresponding parameter, + or if the same parameter is specified multiple times, Z_BUF_ERROR is returned. The caller may inspect status fields + in order to determine which of the parameters caused this error. No other changes are performed. + + If the stream state is inconsistent or if at least one of the values cannot be updated, Z_STREAM_ERROR is + returned. The caller may inspect status fields in order to determine which of the parameters caused this error. + Parameters, whose status field is equal to Z_OK, have been applied successfully. If all status fields are not equal + to Z_STREAM_ERROR, then the error was caused by a stream state inconsistency. + + If there are no other errors, but at least one parameter is not supported by the current zlib-ng version, + Z_VERSION_ERROR is returned. The caller may inspect status fields in order to determine which of the parameters + caused this error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Copies the values of the given zlib-ng deflate stream parameters into the user-provided buffers. Returns Z_OK if + success, Z_VERSION_ERROR if at least one parameter is not supported by the current zlib-ng version, Z_STREAM_ERROR + if the stream state is inconsistent, and Z_BUF_ERROR if the size of at least one buffer is too small to hold the + entire value of the corresponding parameter. +*/ + +/* undocumented functions */ +Z_EXTERN Z_EXPORT const char * zng_zError (int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateSyncPoint (zng_stream *); +Z_EXTERN Z_EXPORT const uint32_t * zng_get_crc_table (void); +Z_EXTERN Z_EXPORT int32_t zng_inflateUndermine (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateValidate (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT unsigned long zng_inflateCodesUsed (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_inflateResetKeep (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_deflateResetKeep (zng_stream *); + +#ifdef WITH_GZFILEOP +# if defined(_WIN32) + Z_EXTERN Z_EXPORT gzFile zng_gzopen_w(const wchar_t *path, const char *mode); +# endif +Z_EXTERN Z_EXPORTVA int32_t zng_gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZNGLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.map b/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.map new file mode 100644 index 000000000..64411ab10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib-ng.map @@ -0,0 +1,111 @@ +ZLIB_NG_2.1.0 { + global: + zng_deflateInit; + zng_deflateInit2; + zng_inflateBackInit; + zng_inflateInit; + zng_inflateInit2; + zlibng_version; +}; + +ZLIB_NG_2.0.0 { + global: + zng_adler32; + zng_adler32_combine; + zng_adler32_z; + zng_compress; + zng_compress2; + zng_compressBound; + zng_crc32; + zng_crc32_combine; + zng_crc32_combine_gen; + zng_crc32_combine_op; + zng_crc32_z; + zng_deflate; + zng_deflateBound; + zng_deflateCopy; + zng_deflateEnd; + zng_deflateGetDictionary; + zng_deflateGetParams; + zng_deflateInit_; + zng_deflateInit2_; + zng_deflateParams; + zng_deflatePending; + zng_deflatePrime; + zng_deflateReset; + zng_deflateResetKeep; + zng_deflateSetDictionary; + zng_deflateSetHeader; + zng_deflateSetParams; + zng_deflateTune; + zng_get_crc_table; + zng_inflate; + zng_inflateBack; + zng_inflateBackEnd; + zng_inflateBackInit_; + zng_inflateCodesUsed; + zng_inflateCopy; + zng_inflateEnd; + zng_inflateGetDictionary; + zng_inflateGetHeader; + zng_inflateInit_; + zng_inflateInit2_; + zng_inflateMark; + zng_inflatePrime; + zng_inflateReset; + zng_inflateReset2; + zng_inflateResetKeep; + zng_inflateSetDictionary; + zng_inflateSync; + zng_inflateSyncPoint; + zng_inflateUndermine; + zng_inflateValidate; + zng_uncompress; + zng_uncompress2; + zng_zError; + zng_zlibCompileFlags; + zng_vstring; + local: + zng_deflate_copyright; + zng_inflate_copyright; + zng_zcalloc; + zng_zcfree; + zng_z_errmsg; + gz_error; + _*; +}; + +ZLIB_NG_GZ_2.0.0 { + global: + zng_gzbuffer; + zng_gzclearerr; + zng_gzclose; + zng_gzclose_r; + zng_gzclose_w; + zng_gzdirect; + zng_gzdopen; + zng_gzeof; + zng_gzerror; + zng_gzflush; + zng_gzfread; + zng_gzfwrite; + zng_gzgetc; + zng_gzgets; + zng_gzoffset; + zng_gzopen; + zng_gzprintf; + zng_gzputc; + zng_gzputs; + zng_gzread; + zng_gzrewind; + zng_gzseek; + zng_gzsetparams; + zng_gztell; + zng_gzungetc; + zng_gzvprintf; + zng_gzwrite; +}; + +FAIL { + local: *; +}; diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.h.in new file mode 100644 index 000000000..3fd25adf3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.h.in @@ -0,0 +1,1855 @@ +#ifndef ZLIB_H_ +#define ZLIB_H_ +/* zlib.h -- interface of the 'zlib-ng' compression library + Forked from and compatible with zlib 1.2.13 + + Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZNGLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf.h" + +#ifndef ZCONF_H +# error Missing zconf.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.1.beta2" +#define ZLIBNG_VERNUM 0x02010120L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 1 +#define ZLIBNG_VER_STATUS 2 /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +#define ZLIB_VERSION "1.2.13.zlib-ng" +#define ZLIB_VERNUM 0x12df +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_SUBREVISION 15 /* 15=fork (0xf) */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct z_stream_s { + z_const unsigned char *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + unsigned long total_in; /* total number of input bytes read so far */ + + unsigned char *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + unsigned long total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + unsigned long adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream *z_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + unsigned char *extra; /* pointer to extra field or NULL if none */ + unsigned int extra_len; /* extra field length (valid if extra != NULL) */ + unsigned int extra_max; /* space at extra (only when reading header) */ + unsigned char *name; /* pointer to zero-terminated file name or NULL */ + unsigned int name_max; /* space at name (only when reading header) */ + unsigned char *comment; /* pointer to zero-terminated comment or NULL */ + unsigned int comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used when writing a gzip file) */ +} gz_header; + +typedef gz_header *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +Z_EXTERN const char * Z_EXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +Z_EXTERN int Z_EXPORT deflateInit (z_stream *strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +Z_EXTERN int Z_EXPORT deflate(z_stream *strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN int Z_EXPORT deflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +Z_EXTERN int Z_EXPORT inflateInit (z_stream *strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +Z_EXTERN int Z_EXPORT inflate(z_stream *strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN int Z_EXPORT inflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +Z_EXTERN int Z_EXPORT deflateInit2 (z_stream *strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateSetDictionary(z_stream *strm, + const unsigned char *dictionary, + unsigned int dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateGetDictionary (z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT deflateReset(z_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT deflateParams(z_stream *strm, int level, int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN int Z_EXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN unsigned long Z_EXPORT deflateBound(z_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN int Z_EXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN int Z_EXPORT deflatePrime(z_stream *strm, int bits, int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateSetHeader(z_stream *strm, gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateInit2(z_stream *strm, int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +Z_EXTERN int Z_EXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN int Z_EXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateSync(z_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN int Z_EXPORT inflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT inflateReset(z_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT inflateReset2(z_stream *strm, int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN int Z_EXPORT inflatePrime(z_stream *strm, int bits, int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN long Z_EXPORT inflateMark(z_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateGetHeader(z_stream *strm, gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateBackInit (z_stream *strm, int windowBits, unsigned char *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef uint32_t (*in_func) (void *, z_const unsigned char * *); +typedef int (*out_func) (void *, unsigned char *, uint32_t); + +Z_EXTERN int Z_EXPORT inflateBack(z_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN int Z_EXPORT inflateBackEnd(z_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN unsigned long Z_EXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN int Z_EXPORT compress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN int Z_EXPORT compress2(unsigned char *dest, unsigned long *destLen, const unsigned char *source, + unsigned long sourceLen, int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN unsigned long Z_EXPORT compressBound(unsigned long sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN int Z_EXPORT uncompress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN int Z_EXPORT uncompress2 (unsigned char *dest, unsigned long *destLen, + const unsigned char *source, unsigned long *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +Z_EXTERN gzFile Z_EXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN gzFile Z_EXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN int Z_EXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN int Z_EXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN int Z_EXPORT gzread(gzFile file, void *buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN size_t Z_EXPORT gzfread (void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN int Z_EXPORT gzwrite(gzFile file, void const *buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN size_t Z_EXPORT gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN int Z_EXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN int Z_EXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN char * Z_EXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN int Z_EXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN int Z_EXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN int Z_EXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN int Z_EXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzseek (gzFile file, z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN int Z_EXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN int Z_EXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN int Z_EXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN int Z_EXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN int Z_EXPORT gzclose_r(gzFile file); +Z_EXTERN int Z_EXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN const char * Z_EXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN void Z_EXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32(unsigned long adler, const unsigned char *buf, unsigned int len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32_z(unsigned long adler, const unsigned char *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT adler32_combine(unsigned long adler1, unsigned long adler2, z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_z(unsigned long crc, const unsigned char *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine(unsigned long crc1, unsigned long crc2, z_off64_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_combine_op(unsigned long crc1, unsigned long crc2, + const unsigned long op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +Z_EXTERN int Z_EXPORT deflateInit_(z_stream *strm, int level, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit_(z_stream *strm, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, int memLevel, + int strategy, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateBackInit_(z_stream *strm, int windowBits, unsigned char *window, + const char *version, int stream_size); +#define @ZLIB_SYMBOL_PREFIX@deflateInit(strm, level) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit(strm) inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit2(strm, windowBits) inflateInit2_((strm), (windowBits), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), ZLIB_VERSION, (int)sizeof(z_stream)) + + +#ifndef Z_SOLO +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +Z_EXTERN int Z_EXPORT gzgetc_(gzFile file); /* backward compatibility */ +# define @ZLIB_SYMBOL_PREFIX@gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@gzgetc)(g)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT gzopen64(const char *, const char *); + Z_EXTERN z_off64_t Z_EXPORT gzseek64(gzFile, z_off64_t, int); + Z_EXTERN z_off64_t Z_EXPORT gztell64(gzFile); + Z_EXTERN z_off64_t Z_EXPORT gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT adler32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen64(z_off64_t); +#endif +#endif + +#if !defined(Z_SOLO) && !defined(Z_INTERNAL) && defined(Z_WANT64) +# define @ZLIB_SYMBOL_PREFIX@gzopen @ZLIB_SYMBOL_PREFIX@gzopen64 +# define @ZLIB_SYMBOL_PREFIX@gzseek @ZLIB_SYMBOL_PREFIX@gzseek64 +# define @ZLIB_SYMBOL_PREFIX@gztell @ZLIB_SYMBOL_PREFIX@gztell64 +# define @ZLIB_SYMBOL_PREFIX@gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define @ZLIB_SYMBOL_PREFIX@adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +# ifndef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen64(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek64(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell64(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64(z_off64_t); +# endif +#else +# ifndef Z_SOLO + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset(gzFile); +# endif + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen(z_off_t); +#endif + +/* undocumented functions */ +Z_EXTERN const char * Z_EXPORT zError (int); +Z_EXTERN int Z_EXPORT inflateSyncPoint (z_stream *); +Z_EXTERN const uint32_t * Z_EXPORT get_crc_table (void); +Z_EXTERN int Z_EXPORT inflateUndermine (z_stream *, int); +Z_EXTERN int Z_EXPORT inflateValidate (z_stream *, int); +Z_EXTERN unsigned long Z_EXPORT inflateCodesUsed (z_stream *); +Z_EXTERN int Z_EXPORT inflateResetKeep (z_stream *); +Z_EXTERN int Z_EXPORT deflateResetKeep (z_stream *); + +#ifndef Z_SOLO +#if defined(_WIN32) + Z_EXTERN gzFile Z_EXPORT gzopen_w(const wchar_t *path, const char *mode); +#endif +Z_EXTERN int Z_EXPORTVA gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib.map b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.map new file mode 100644 index 000000000..ebca10d35 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.map @@ -0,0 +1,97 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + zcalloc; + zcfree; + z_errmsg; + gz_error; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; + +ZLIB_1.2.9 { + inflateCodesUsed; + inflateValidate; + uncompress2; + gzfread; + gzfwrite; + deflateGetDictionary; + adler32_z; + crc32_z; +} ZLIB_1.2.7.1; + +ZLIB_1.2.12 { + crc32_combine_gen; + crc32_combine_gen64; + crc32_combine_op; +} ZLIB_1.2.9; diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.cmakein b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.cmakein new file mode 100644 index 000000000..3d440ce6b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.cmakein @@ -0,0 +1,14 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +symbol_prefix=@ZLIB_SYMBOL_PREFIX@ +libdir=@PC_LIB_INSTALL_DIR@ +sharedlibdir=${libdir} +includedir=@PC_INC_INSTALL_DIR@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @ZLIB_FULL_VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.in b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.in new file mode 100644 index 000000000..a0678fbe0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +symbol_prefix=@symbol_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling-ng.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling-ng.h.in new file mode 100644 index 000000000..e90904a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling-ng.h.in @@ -0,0 +1,178 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define zng__dist_code @ZLIB_SYMBOL_PREFIX@zng__dist_code +#define zng__length_code @ZLIB_SYMBOL_PREFIX@zng__length_code +#define zng__tr_align @ZLIB_SYMBOL_PREFIX@zng__tr_align +#define zng__tr_flush_bits @ZLIB_SYMBOL_PREFIX@zng__tr_flush_bits +#define zng__tr_flush_block @ZLIB_SYMBOL_PREFIX@zng__tr_flush_block +#define zng__tr_init @ZLIB_SYMBOL_PREFIX@zng__tr_init +#define zng__tr_stored_block @ZLIB_SYMBOL_PREFIX@zng__tr_stored_block +#define zng__tr_tally @ZLIB_SYMBOL_PREFIX@zng__tr_tally +#define zng_adler32 @ZLIB_SYMBOL_PREFIX@zng_adler32 +#define zng_adler32_combine @ZLIB_SYMBOL_PREFIX@zng_adler32_combine +#define zng_adler32_combine64 @ZLIB_SYMBOL_PREFIX@zng_adler32_combine64 +#define zng_adler32_z @ZLIB_SYMBOL_PREFIX@zng_adler32_z +#define zng_compress @ZLIB_SYMBOL_PREFIX@zng_compress +#define zng_compress2 @ZLIB_SYMBOL_PREFIX@zng_compress2 +#define zng_compressBound @ZLIB_SYMBOL_PREFIX@zng_compressBound +#define zng_crc32 @ZLIB_SYMBOL_PREFIX@zng_crc32 +#define zng_crc32_combine @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +#define zng_crc32_combine64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine64 +#define zng_crc32_combine_gen @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen +#define zng_crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen64 +#define zng_crc32_combine_op @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_op +#define zng_crc32_z @ZLIB_SYMBOL_PREFIX@zng_crc32_z +#define zng_deflate @ZLIB_SYMBOL_PREFIX@zng_deflate +#define zng_deflateBound @ZLIB_SYMBOL_PREFIX@zng_deflateBound +#define zng_deflateCopy @ZLIB_SYMBOL_PREFIX@zng_deflateCopy +#define zng_deflateEnd @ZLIB_SYMBOL_PREFIX@zng_deflateEnd +#define zng_deflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary +#define zng_deflateInit @ZLIB_SYMBOL_PREFIX@zng_deflateInit +#define zng_deflateInit2 @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 +#define zng_deflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit2_ +#define zng_deflateInit_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit_ +#define zng_deflateParams @ZLIB_SYMBOL_PREFIX@zng_deflateParams +#define zng_deflatePending @ZLIB_SYMBOL_PREFIX@zng_deflatePending +#define zng_deflatePrime @ZLIB_SYMBOL_PREFIX@zng_deflatePrime +#define zng_deflateReset @ZLIB_SYMBOL_PREFIX@zng_deflateReset +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep +#define zng_deflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary +#define zng_deflateSetHeader @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader +#define zng_deflateTune @ZLIB_SYMBOL_PREFIX@zng_deflateTune +#define zng_deflate_copyright @ZLIB_SYMBOL_PREFIX@zng_deflate_copyright +#define zng_fill_window @ZLIB_SYMBOL_PREFIX@zng_fill_window +#define zng_fixedtables @ZLIB_SYMBOL_PREFIX@zng_fixedtables +#define zng_flush_pending @ZLIB_SYMBOL_PREFIX@zng_flush_pending +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#ifdef WITH_GZFILEOP +# define zng_gz_error @ZLIB_SYMBOL_PREFIX@zng_gz_error +# define zng_gz_strwinerror @ZLIB_SYMBOL_PREFIX@zng_gz_strwinerror +# define zng_gzbuffer @ZLIB_SYMBOL_PREFIX@zng_gzbuffer +# define zng_gzclearerr @ZLIB_SYMBOL_PREFIX@zng_gzclearerr +# define zng_gzclose @ZLIB_SYMBOL_PREFIX@zng_gzclose +# define zng_gzclose_r @ZLIB_SYMBOL_PREFIX@zng_gzclose_r +# define zng_gzclose_w @ZLIB_SYMBOL_PREFIX@zng_gzclose_w +# define zng_gzdirect @ZLIB_SYMBOL_PREFIX@zng_gzdirect +# define zng_gzdopen @ZLIB_SYMBOL_PREFIX@zng_gzdopen +# define zng_gzeof @ZLIB_SYMBOL_PREFIX@zng_gzeof +# define zng_gzerror @ZLIB_SYMBOL_PREFIX@zng_gzerror +# define zng_gzflush @ZLIB_SYMBOL_PREFIX@zng_gzflush +# define zng_gzfread @ZLIB_SYMBOL_PREFIX@zng_gzfread +# define zng_gzfwrite @ZLIB_SYMBOL_PREFIX@zng_gzfwrite +# define zng_gzgetc @ZLIB_SYMBOL_PREFIX@zng_gzgetc +# define zng_gzgetc_ @ZLIB_SYMBOL_PREFIX@zng_gzgetc_ +# define zng_gzgets @ZLIB_SYMBOL_PREFIX@zng_gzgets +# define zng_gzoffset @ZLIB_SYMBOL_PREFIX@zng_gzoffset +# define zng_gzoffset64 @ZLIB_SYMBOL_PREFIX@zng_gzoffset64 +# define zng_gzopen @ZLIB_SYMBOL_PREFIX@zng_gzopen +# define zng_gzopen64 @ZLIB_SYMBOL_PREFIX@zng_gzopen64 +# ifdef _WIN32 +# define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +# endif +# define zng_gzprintf @ZLIB_SYMBOL_PREFIX@zng_gzprintf +# define zng_gzputc @ZLIB_SYMBOL_PREFIX@zng_gzputc +# define zng_gzputs @ZLIB_SYMBOL_PREFIX@zng_gzputs +# define zng_gzread @ZLIB_SYMBOL_PREFIX@zng_gzread +# define zng_gzrewind @ZLIB_SYMBOL_PREFIX@zng_gzrewind +# define zng_gzseek @ZLIB_SYMBOL_PREFIX@zng_gzseek +# define zng_gzseek64 @ZLIB_SYMBOL_PREFIX@zng_gzseek64 +# define zng_gzsetparams @ZLIB_SYMBOL_PREFIX@zng_gzsetparams +# define zng_gztell @ZLIB_SYMBOL_PREFIX@zng_gztell +# define zng_gztell64 @ZLIB_SYMBOL_PREFIX@zng_gztell64 +# define zng_gzungetc @ZLIB_SYMBOL_PREFIX@zng_gzungetc +# define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf +# define zng_gzwrite @ZLIB_SYMBOL_PREFIX@zng_gzwrite +#endif +#define zng_inflate @ZLIB_SYMBOL_PREFIX@zng_inflate +#define zng_inflateBack @ZLIB_SYMBOL_PREFIX@zng_inflateBack +#define zng_inflateBackEnd @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd +#define zng_inflateBackInit @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +#define zng_inflateBackInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit_ +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateCopy @ZLIB_SYMBOL_PREFIX@zng_inflateCopy +#define zng_inflateEnd @ZLIB_SYMBOL_PREFIX@zng_inflateEnd +#define zng_inflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary +#define zng_inflateGetHeader @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader +#define zng_inflateInit @ZLIB_SYMBOL_PREFIX@zng_inflateInit +#define zng_inflateInit2 @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 +#define zng_inflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit2_ +#define zng_inflateInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit_ +#define zng_inflateMark @ZLIB_SYMBOL_PREFIX@zng_inflateMark +#define zng_inflatePrime @ZLIB_SYMBOL_PREFIX@zng_inflatePrime +#define zng_inflateReset @ZLIB_SYMBOL_PREFIX@zng_inflateReset +#define zng_inflateReset2 @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_inflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary +#define zng_inflateSync @ZLIB_SYMBOL_PREFIX@zng_inflateSync +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflate_copyright @ZLIB_SYMBOL_PREFIX@zng_inflate_copyright +#define zng_inflate_ensure_window @ZLIB_SYMBOL_PREFIX@zng_inflate_ensure_window +#define zng_inflate_fast @ZLIB_SYMBOL_PREFIX@zng_inflate_fast +#define zng_inflate_table @ZLIB_SYMBOL_PREFIX@zng_inflate_table +#define zng_read_buf @ZLIB_SYMBOL_PREFIX@zng_read_buf +#define zng_uncompress @ZLIB_SYMBOL_PREFIX@zng_uncompress +#define zng_uncompress2 @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError +#define zng_zcalloc @ZLIB_SYMBOL_PREFIX@zng_zcalloc +#define zng_zcfree @ZLIB_SYMBOL_PREFIX@zng_zcfree +#define zng_zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +#define zng_zlibVersion @ZLIB_SYMBOL_PREFIX@zng_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifdef WITH_GZFILEOP +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define zng_gz_header_s @ZLIB_SYMBOL_PREFIX@zng_gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* zlib-ng specific symbols */ +#define zng_deflate_param @ZLIB_SYMBOL_PREFIX@zng_deflate_param +#define zng_deflate_param_value @ZLIB_SYMBOL_PREFIX@zng_deflate_param_value +#define zng_deflateSetParams @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams +#define zng_deflateGetParams @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version +#define zng_vstring @ZLIB_SYMBOL_PREFIX@zng_vstring +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError + +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep + +#define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +#define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.empty b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.empty new file mode 100644 index 000000000..b24cb834a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.empty @@ -0,0 +1,8 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.empty because ZLIB_SYMBOL_PREFIX was NOT set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.in b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.in new file mode 100644 index 000000000..f49615818 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zlib_name_mangling.h.in @@ -0,0 +1,170 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define _dist_code @ZLIB_SYMBOL_PREFIX@_dist_code +#define _length_code @ZLIB_SYMBOL_PREFIX@_length_code +#define _tr_align @ZLIB_SYMBOL_PREFIX@_tr_align +#define _tr_flush_bits @ZLIB_SYMBOL_PREFIX@_tr_flush_bits +#define _tr_flush_block @ZLIB_SYMBOL_PREFIX@_tr_flush_block +#define _tr_init @ZLIB_SYMBOL_PREFIX@_tr_init +#define _tr_stored_block @ZLIB_SYMBOL_PREFIX@_tr_stored_block +#define _tr_tally @ZLIB_SYMBOL_PREFIX@_tr_tally +#define adler32 @ZLIB_SYMBOL_PREFIX@adler32 +#define adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine +#define adler32_combine64 @ZLIB_SYMBOL_PREFIX@adler32_combine64 +#define adler32_z @ZLIB_SYMBOL_PREFIX@adler32_z +#ifndef Z_SOLO +# define compress @ZLIB_SYMBOL_PREFIX@compress +# define compress2 @ZLIB_SYMBOL_PREFIX@compress2 +# define compressBound @ZLIB_SYMBOL_PREFIX@compressBound +#endif +#define crc32 @ZLIB_SYMBOL_PREFIX@crc32 +#define crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine +#define crc32_combine64 @ZLIB_SYMBOL_PREFIX@crc32_combine64 +#define crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen +#define crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +#define crc32_combine_op @ZLIB_SYMBOL_PREFIX@crc32_combine_op +#define crc32_z @ZLIB_SYMBOL_PREFIX@crc32_z +#define deflate @ZLIB_SYMBOL_PREFIX@deflate +#define deflateBound @ZLIB_SYMBOL_PREFIX@deflateBound +#define deflateCopy @ZLIB_SYMBOL_PREFIX@deflateCopy +#define deflateEnd @ZLIB_SYMBOL_PREFIX@deflateEnd +#define deflateGetDictionary @ZLIB_SYMBOL_PREFIX@deflateGetDictionary +#define deflateInit @ZLIB_SYMBOL_PREFIX@deflateInit +#define deflateInit2 @ZLIB_SYMBOL_PREFIX@deflateInit2 +#define deflateInit2_ @ZLIB_SYMBOL_PREFIX@deflateInit2_ +#define deflateInit_ @ZLIB_SYMBOL_PREFIX@deflateInit_ +#define deflateParams @ZLIB_SYMBOL_PREFIX@deflateParams +#define deflatePending @ZLIB_SYMBOL_PREFIX@deflatePending +#define deflatePrime @ZLIB_SYMBOL_PREFIX@deflatePrime +#define deflateReset @ZLIB_SYMBOL_PREFIX@deflateReset +#define deflateResetKeep @ZLIB_SYMBOL_PREFIX@deflateResetKeep +#define deflateSetDictionary @ZLIB_SYMBOL_PREFIX@deflateSetDictionary +#define deflateSetHeader @ZLIB_SYMBOL_PREFIX@deflateSetHeader +#define deflateTune @ZLIB_SYMBOL_PREFIX@deflateTune +#define deflate_copyright @ZLIB_SYMBOL_PREFIX@deflate_copyright +#define fill_window @ZLIB_SYMBOL_PREFIX@fill_window +#define fixedtables @ZLIB_SYMBOL_PREFIX@fixedtables +#define flush_pending @ZLIB_SYMBOL_PREFIX@flush_pending +#define get_crc_table @ZLIB_SYMBOL_PREFIX@get_crc_table +#ifndef Z_SOLO +# define gz_error @ZLIB_SYMBOL_PREFIX@gz_error +# define gz_strwinerror @ZLIB_SYMBOL_PREFIX@gz_strwinerror +# define gzbuffer @ZLIB_SYMBOL_PREFIX@gzbuffer +# define gzclearerr @ZLIB_SYMBOL_PREFIX@gzclearerr +# define gzclose @ZLIB_SYMBOL_PREFIX@gzclose +# define gzclose_r @ZLIB_SYMBOL_PREFIX@gzclose_r +# define gzclose_w @ZLIB_SYMBOL_PREFIX@gzclose_w +# define gzdirect @ZLIB_SYMBOL_PREFIX@gzdirect +# define gzdopen @ZLIB_SYMBOL_PREFIX@gzdopen +# define gzeof @ZLIB_SYMBOL_PREFIX@gzeof +# define gzerror @ZLIB_SYMBOL_PREFIX@gzerror +# define gzflush @ZLIB_SYMBOL_PREFIX@gzflush +# define gzfread @ZLIB_SYMBOL_PREFIX@gzfread +# define gzfwrite @ZLIB_SYMBOL_PREFIX@gzfwrite +# define gzgetc @ZLIB_SYMBOL_PREFIX@gzgetc +# define gzgetc_ @ZLIB_SYMBOL_PREFIX@gzgetc_ +# define gzgets @ZLIB_SYMBOL_PREFIX@gzgets +# define gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset +# define gzoffset64 @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define gzopen @ZLIB_SYMBOL_PREFIX@gzopen +# define gzopen64 @ZLIB_SYMBOL_PREFIX@gzopen64 +# ifdef _WIN32 +# define gzopen_w @ZLIB_SYMBOL_PREFIX@gzopen_w +# endif +# define gzprintf @ZLIB_SYMBOL_PREFIX@gzprintf +# define gzputc @ZLIB_SYMBOL_PREFIX@gzputc +# define gzputs @ZLIB_SYMBOL_PREFIX@gzputs +# define gzread @ZLIB_SYMBOL_PREFIX@gzread +# define gzrewind @ZLIB_SYMBOL_PREFIX@gzrewind +# define gzseek @ZLIB_SYMBOL_PREFIX@gzseek +# define gzseek64 @ZLIB_SYMBOL_PREFIX@gzseek64 +# define gzsetparams @ZLIB_SYMBOL_PREFIX@gzsetparams +# define gztell @ZLIB_SYMBOL_PREFIX@gztell +# define gztell64 @ZLIB_SYMBOL_PREFIX@gztell64 +# define gzungetc @ZLIB_SYMBOL_PREFIX@gzungetc +# define gzvprintf @ZLIB_SYMBOL_PREFIX@gzvprintf +# define gzwrite @ZLIB_SYMBOL_PREFIX@gzwrite +#endif +#define inflate @ZLIB_SYMBOL_PREFIX@inflate +#define inflateBack @ZLIB_SYMBOL_PREFIX@inflateBack +#define inflateBackEnd @ZLIB_SYMBOL_PREFIX@inflateBackEnd +#define inflateBackInit @ZLIB_SYMBOL_PREFIX@inflateBackInit +#define inflateBackInit_ @ZLIB_SYMBOL_PREFIX@inflateBackInit_ +#define inflateCodesUsed @ZLIB_SYMBOL_PREFIX@inflateCodesUsed +#define inflateCopy @ZLIB_SYMBOL_PREFIX@inflateCopy +#define inflateEnd @ZLIB_SYMBOL_PREFIX@inflateEnd +#define inflateGetDictionary @ZLIB_SYMBOL_PREFIX@inflateGetDictionary +#define inflateGetHeader @ZLIB_SYMBOL_PREFIX@inflateGetHeader +#define inflateInit @ZLIB_SYMBOL_PREFIX@inflateInit +#define inflateInit2 @ZLIB_SYMBOL_PREFIX@inflateInit2 +#define inflateInit2_ @ZLIB_SYMBOL_PREFIX@inflateInit2_ +#define inflateInit_ @ZLIB_SYMBOL_PREFIX@inflateInit_ +#define inflateMark @ZLIB_SYMBOL_PREFIX@inflateMark +#define inflatePrime @ZLIB_SYMBOL_PREFIX@inflatePrime +#define inflateReset @ZLIB_SYMBOL_PREFIX@inflateReset +#define inflateReset2 @ZLIB_SYMBOL_PREFIX@inflateReset2 +#define inflateResetKeep @ZLIB_SYMBOL_PREFIX@inflateResetKeep +#define inflateSetDictionary @ZLIB_SYMBOL_PREFIX@inflateSetDictionary +#define inflateSync @ZLIB_SYMBOL_PREFIX@inflateSync +#define inflateSyncPoint @ZLIB_SYMBOL_PREFIX@inflateSyncPoint +#define inflateUndermine @ZLIB_SYMBOL_PREFIX@inflateUndermine +#define inflateValidate @ZLIB_SYMBOL_PREFIX@inflateValidate +#define inflate_copyright @ZLIB_SYMBOL_PREFIX@inflate_copyright +#define inflate_ensure_window @ZLIB_SYMBOL_PREFIX@inflate_ensure_window +#define inflate_fast @ZLIB_SYMBOL_PREFIX@inflate_fast +#define inflate_table @ZLIB_SYMBOL_PREFIX@inflate_table +#define read_buf @ZLIB_SYMBOL_PREFIX@read_buf +#ifndef Z_SOLO +# define uncompress @ZLIB_SYMBOL_PREFIX@uncompress +# define uncompress2 @ZLIB_SYMBOL_PREFIX@uncompress2 +#endif +#define zError @ZLIB_SYMBOL_PREFIX@zError +#ifndef Z_SOLO +# define zcalloc @ZLIB_SYMBOL_PREFIX@zcalloc +# define zcfree @ZLIB_SYMBOL_PREFIX@zcfree +#endif +#define zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +#define zlibVersion @ZLIB_SYMBOL_PREFIX@zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifndef Z_SOLO +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define gz_header_s @ZLIB_SYMBOL_PREFIX@gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* all zlib structs in zutil.h */ +#define z_errmsg @ZLIB_SYMBOL_PREFIX@z_errmsg +#define z_vstring @ZLIB_SYMBOL_PREFIX@z_vstring +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version + +/* zlib-ng specific symbols */ +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zutil.c b/internal-complibs/zlib-ng-2.1.1-beta2/zutil.c new file mode 100644 index 000000000..2d753b4ad --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zutil.c @@ -0,0 +1,159 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "zutil.h" + +z_const char * const PREFIX(z_errmsg)[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + +const char PREFIX3(vstring)[] = + " zlib-ng 2.1.1.beta2"; + +#ifdef ZLIB_COMPAT +const char * Z_EXPORT zlibVersion(void) { + return ZLIB_VERSION; +} +#else +const char * Z_EXPORT zlibng_version(void) { + return ZLIBNG_VERSION; +} +#endif + +unsigned long Z_EXPORT PREFIX(zlibCompileFlags)(void) { + unsigned long flags; + + flags = 0; + switch ((int)(sizeof(unsigned int))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(unsigned long))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(void *))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif + /* Bit 13 reserved for DYNAMIC_CRC_TABLE */ +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +# include +# ifndef verbose +# define verbose 0 +# endif +int Z_INTERNAL z_verbose = verbose; + +void Z_INTERNAL z_error(const char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * Z_EXPORT PREFIX(zError)(int err) { + return ERR_MSG(err); +} + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size) { + Z_UNUSED(opaque); + return zng_alloc((size_t)items * (size_t)size); +} + +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr) { + Z_UNUSED(opaque); + zng_free(ptr); +} + +/* Since we support custom memory allocators, some which might not align memory as we expect, + * we have to ask for extra memory and return an aligned pointer. */ +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align) { + uintptr_t return_ptr, original_ptr; + uint32_t alloc_size, align_diff; + void *ptr; + + /* If no custom calloc function used then call zlib-ng's aligned calloc */ + if (zalloc == PREFIX(zcalloc)) + return PREFIX(zcalloc)(opaque, items, size); + + /* Allocate enough memory for proper alignment and to store the original memory pointer */ + alloc_size = sizeof(void *) + (items * size) + align; + ptr = zalloc(opaque, 1, alloc_size); + if (!ptr) + return NULL; + + /* Calculate return pointer address with space enough to store original pointer */ + align_diff = align - ((uintptr_t)ptr % align); + return_ptr = (uintptr_t)ptr + align_diff; + if (align_diff < sizeof(void *)) + return_ptr += align; + + /* Store the original pointer for free() */ + original_ptr = return_ptr - sizeof(void *); + memcpy((void *)original_ptr, &ptr, sizeof(void *)); + + /* Return properly aligned pointer in allocation */ + return (void *)return_ptr; +} + +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr) { + /* If no custom cfree function used then call zlib-ng's aligned cfree */ + if (zfree == PREFIX(zcfree)) { + PREFIX(zcfree)(opaque, ptr); + return; + } + if (!ptr) + return; + + /* Calculate offset to original memory allocation pointer */ + void *original_ptr = (void *)((uintptr_t)ptr - sizeof(void *)); + void *free_ptr = *(void **)original_ptr; + + /* Free original memory allocation */ + zfree(opaque, free_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zutil.h b/internal-complibs/zlib-ng-2.1.1-beta2/zutil.h new file mode 100644 index 000000000..663616b44 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zutil.h @@ -0,0 +1,148 @@ +#ifndef ZUTIL_H_ +#define ZUTIL_H_ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +typedef unsigned char uch; /* Included for compatibility with external code only */ +typedef uint16_t ush; /* Included for compatibility with external code only */ +typedef unsigned long ulg; + +extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) PREFIX(z_errmsg)[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm, err) return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#define MAX_BITS 15 +/* all codes must not exceed MAX_BITS bits */ +#define MAX_DIST_EXTRA_BITS 13 +/* maximum number of extra distance bits */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define STD_MIN_MATCH 3 +#define STD_MAX_MATCH 258 +/* The minimum and maximum match lengths mandated by the deflate standard */ + +#define WANT_MIN_MATCH 4 +/* The minimum wanted match length, affects deflate_quick, deflate_fast, deflate_medium and deflate_slow */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + +#define ADLER32_INITIAL_VALUE 1 /* initial adler-32 hash value */ +#define CRC32_INITIAL_VALUE 0 /* initial crc-32 hash value */ + +#define ZLIB_WRAPLEN 6 /* zlib format overhead */ +#define GZIP_WRAPLEN 18 /* gzip format overhead */ + +#define DEFLATE_HEADER_BITS 3 +#define DEFLATE_EOBS_BITS 15 +#define DEFLATE_PAD_BITS 6 +#define DEFLATE_BLOCK_OVERHEAD ((DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3) +/* deflate block overhead: 3 bits for block start + 15 bits for block end + padding to nearest byte */ + +#define DEFLATE_QUICK_LIT_MAX_BITS 9 +#define DEFLATE_QUICK_OVERHEAD(x) ((x * (DEFLATE_QUICK_LIT_MAX_BITS - 8) + 7) >> 3) +/* deflate_quick worst-case overhead: 9 bits per literal, round up to next byte (+7) */ + + + /* target dependencies */ + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + + /* macros */ + +#define CHECK_VER_STSIZE(_ver,_stsize) ((_ver) == NULL || (_ver)[0] != PREFIX2(VERSION)[0] || (_stsize) != (int32_t)sizeof(PREFIX3(stream))) + + /* memory allocation functions */ + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size); +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr); + +typedef void *zng_calloc_func(void *opaque, unsigned items, unsigned size); +typedef void zng_cfree_func(void *opaque, void *ptr); + +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align); +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr); + +#define ZALLOC(strm, items, size) PREFIX3(alloc_aligned)((strm)->zalloc, (strm)->opaque, (items), (size), 64) +#define ZFREE(strm, addr) PREFIX3(free_aligned)((strm)->zfree, (strm)->opaque, (void *)(addr)) + +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/zutil_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/zutil_p.h new file mode 100644 index 000000000..caec91d50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/zutil_p.h @@ -0,0 +1,71 @@ +/* zutil_p.h -- Private inline functions used internally in zlib-ng + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZUTIL_P_H +#define ZUTIL_P_H + +#if defined(__APPLE__) || defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC) +# include +#elif defined(__FreeBSD__) +# include +# include +#else +# include +#endif + +/* Function to allocate 16 or 64-byte aligned memory */ +static inline void *zng_alloc(size_t size) { +#ifdef HAVE_POSIX_MEMALIGN + void *ptr; + return posix_memalign(&ptr, 64, size) ? NULL : ptr; +#elif defined(_WIN32) + return (void *)_aligned_malloc(size, 64); +#elif defined(__APPLE__) + return (void *)malloc(size); /* MacOS always aligns to 16 bytes */ +#elif defined(HAVE_ALIGNED_ALLOC) + return (void *)aligned_alloc(64, size); +#else + return (void *)memalign(64, size); +#endif +} + +/* Function that can free aligned memory */ +static inline void zng_free(void *ptr) { +#if defined(_WIN32) + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +/* Use memcpy instead of memcmp to avoid older compilers not converting memcmp calls to + unaligned comparisons when unaligned access is supported. */ +static inline int32_t zng_memcmp_2(const void *src0, const void *src1) { + uint16_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_4(const void *src0, const void *src1) { + uint32_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_8(const void *src0, const void *src1) { + uint64_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/.codecov.yaml b/internal-complibs/zlib-ng-2.1.2/.codecov.yaml new file mode 100644 index 000000000..fc17c66a9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.codecov.yaml @@ -0,0 +1,27 @@ +codecov: + max_report_age: off + notify: + wait_for_ci: false + require_ci_to_pass: false +comment: + require_base: false + require_head: false +coverage: + status: + project: + default: + threshold: 0.07 +fixes: +- '/home/actions-runner/_work/zlib-ng/zlib-ng::' +- '/home/actions-runner/_work/zlib-ng/zlib-ng/build/::' +ignore: +- usr/include/.* +- /usr/include/.* +- /build/usr/include/.* +- usr/lib/.* +- /usr/lib/.* +- /build/usr/lib/.* +- usr/lib64/.* +- /usr/lib64/.* +- /build/usr/lib64/.* +- _deps/**/* diff --git a/internal-complibs/zlib-ng-2.1.2/.gitattributes b/internal-complibs/zlib-ng-2.1.2/.gitattributes new file mode 100644 index 000000000..ac21ec459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.gitattributes @@ -0,0 +1,8 @@ +* text=auto +*.abi text eol=lf +*.c text +*.h text +*.sh text eol=lf +crc32_braid_tbl.h hooks-max-size=1000000 +Makefile text +configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml new file mode 100644 index 000000000..7cd812915 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/FUNDING.yml @@ -0,0 +1 @@ +github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml new file mode 100644 index 000000000..cbdea0e50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/analyze.yml @@ -0,0 +1,78 @@ +name: Static Analysis +on: [push, pull_request] +jobs: + static-analysis: + name: GCC + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y gcc-10 + + - name: Generate project files + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CC: gcc-10 + CFLAGS: + -fanalyzer + -Werror + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-malloc-leak + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-tainted-array-index + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release > /dev/null + + Clang: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y clang-tools + + - name: Generate project files + run: | + scan-build --status-bugs \ + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CI: true + + - name: Compile source code + run: | + scan-build --status-bugs \ + cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml new file mode 100644 index 000000000..f16ab99c7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/cmake.yml @@ -0,0 +1,635 @@ +name: CMake +on: [push, pull_request] +env: + TERM: xterm-256color + GTEST_COLOR: 1 +jobs: + cmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SANITIZER=Address + codecov: ubuntu_gcc + + - name: Ubuntu GCC Benchmark + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_BENCHMARKS=ON + codecov: ubuntu_gcc_benchmark + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_sprefix + + - name: Ubuntu GCC Compat Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_compat_sprefix + + - name: Ubuntu GCC -O3 OSB + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng + codecov: ubuntu_gcc_osb + cflags: -O3 + + - name: Ubuntu GCC -O3 OSB add_subdirectory + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng/test/add-subdirectory-project + + - name: Ubuntu GCC -O1 No Unaligned UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_o1 + cflags: -O1 + + - name: Ubuntu GCC 32-bit + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 + packages: gcc-multilib g++-multilib + codecov: ubuntu_gcc_m32 + + - name: Ubuntu GCC No CTZLL + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF + codecov: ubuntu_gcc_no_ctzll + + - name: Ubuntu GCC No CTZ + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF + codecov: ubuntu_gcc_no_ctz + + - name: Ubuntu GCC No AVX2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_avx2 + + - name: Ubuntu GCC No SSE2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse2 + + - name: Ubuntu GCC No SSE4.2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse42 + + - name: Ubuntu GCC No PCLMULQDQ UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_pclmulqdq + + - name: Ubuntu GCC Compat No Opt ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address + codecov: ubuntu_gcc_compat_no_opt + cflags: -DNOT_TWEAK_COMPILER + + - name: Ubuntu GCC ARM SF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf + + - name: Ubuntu GCC ARM SF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf_compat_no_opt + + - name: Ubuntu GCC ARM HF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf + + - name: Ubuntu GCC ARM HF No ACLE ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_acle + + - name: Ubuntu GCC ARM HF No NEON ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_neon + + - name: Ubuntu GCC ARM HF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_compat_no_opt + + - name: Ubuntu GCC AARCH64 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64 + + - name: Ubuntu GCC AARCH64 No ACLE UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_acle + + - name: Ubuntu GCC AARCH64 No NEON UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_neon + + - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_compat_no_opt + + - name: Ubuntu GCC MIPS + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips.cmake + packages: qemu qemu-user gcc-mips-linux-gnu g++-mips-linux-gnu libc-dev-mips-cross + codecov: ubuntu_gcc_mips + + - name: Ubuntu GCC MIPS64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips64.cmake + packages: qemu qemu-user gcc-mips64-linux-gnuabi64 g++-mips64-linux-gnuabi64 libc-dev-mips64-cross + codecov: ubuntu_gcc_mips64 + + - name: Ubuntu GCC PPC + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc_no_power8 + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake + packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross + ldflags: -static + codecov: ubuntu_gcc_ppc64 + + - name: Ubuntu GCC PPC64LE + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross + codecov: ubuntu_gcc_ppc64le + + - name: Ubuntu GCC SPARC64 + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake + packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross + ldflags: -static + codecov: ubuntu_gcc_sparc64 + + - name: Ubuntu GCC S390X ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X No vectorized CRC32 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x_no_crc32 + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC ASAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC Compat UBSAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc_compat + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu Clang S390X DFLTCC MSAN + os: z15 + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu MinGW i686 + os: ubuntu-22.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake + packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 libgcc-s1:i386 libstdc++6:i386 + ldflags: -static + codecov: ubuntu_gcc_mingw_i686 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu MinGW x86_64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake + packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 + ldflags: -static + codecov: ubuntu_gcc_mingw_x86_64 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu 20.04 Clang + os: ubuntu-20.04 + compiler: clang-6.0 + cxx-compiler: clang++-6.0 + packages: clang-6.0 + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang + + # Check for undefined symbols in the version script for the modern api + - name: Ubuntu Clang Undefined Symbols + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF + build-shared: ON + packages: clang-11 llvm-11 lld + + # Check for undefined symbols in the version script for the compat api + - name: Ubuntu Clang Undefined Symbols Compat + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON + build-shared: ON + packages: clang-11 llvm-11 lld + + - name: Ubuntu Clang Inflate Strict + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_STRICT=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_strict + + - name: Ubuntu Clang Inflate Allow Invalid Dist + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_allow_invalid_dist + + - name: Ubuntu Clang Reduced Memory + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_REDUCED_MEM=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_reduced_mem + + - name: Ubuntu Clang Memory Map + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cflags: -DUSE_MMAP + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_mmap + + - name: Ubuntu Clang Debug + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_debug + build-config: Debug + + - name: Ubuntu Clang MSAN + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_SANITIZER=Memory + packages: ninja-build clang-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + # https://github.com/llvm/llvm-project/issues/55785 + msan-options: use_sigaltstack=0 + + - name: Ubuntu Clang RISC-V + os: ubuntu-latest + cmake-args: -GNinja -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake -DTOOLCHAIN_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-clang -DQEMU_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64 + packages: build-essential cmake ninja-build + codecov: ubuntu_clang_toolchain_riscv + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON + + - name: Windows MSVC 2022 v143 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 + + - name: Windows MSVC 2022 v143 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 + + - name: Windows MSVC 2022 v142 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 + + - name: Windows MSVC 2022 v142 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 + + - name: Windows MSVC 2022 v141 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 + + - name: Windows MSVC 2022 v141 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 + + - name: Windows MSVC 2019 v140 Win32 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 + + - name: Windows MSVC 2019 v140 Win64 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 + + - name: Windows MSVC ARM No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM + + - name: Windows MSVC ARM64 No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + + - name: Windows ClangCl Win32 + os: windows-latest + cmake-args: -T ClangCl -A Win32 + + - name: Windows ClangCl Win64 + os: windows-latest + cmake-args: -T ClangCl -A x64 + + - name: Windows GCC + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja + codecov: win64_gcc + + - name: Windows GCC Compat No Opt + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF + codecov: win64_gcc_compat_no_opt + + - name: macOS Clang ASAN + os: macos-latest + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_SANITIZER=Address + codecov: macos_clang + + - name: macOS GCC UBSAN + os: macos-latest + compiler: gcc-10 + cxx-compiler: g++-10 + cmake-args: -DWITH_SANITIZER=Undefined + packages: gcc@10 + gcov-exec: gcov-10 + codecov: macos_gcc + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs + # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. + if: contains(matrix.name, 'MinGW') == false + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add repositories (Wine) + if: contains(matrix.packages, 'wine32') + run: sudo dpkg --add-architecture i386 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} + + - name: Download prebuilt RISC-V Clang toolchain & QEMU emulator + if: runner.os == 'Linux' && contains(matrix.name, 'RISC-V') + run: | + gh release download ubuntu20.04_llvm16.0.0_qemu7.0.0 --repo sifive/prepare-riscv-toolchain-qemu + tar zxvf prebuilt-riscv-toolchain-qemu.tar.gz + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install packages (Windows) + if: runner.os == 'Windows' + run: | + # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. + # zlib-ng does not need perl, so simply remove it. + choco uninstall --no-progress strawberryperl + choco install --no-progress ninja ${{ matrix.packages }} + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Initialize Wine + # Prevent parallel test jobs from initializing Wine at the same time + if: contains(matrix.packages, 'wine') + run: wineboot --init + + - name: Compile LLVM C++ libraries (MSAN) + if: contains(matrix.name, 'MSAN') + run: | + git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 + cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ + -DLLVM_USE_SANITIZER=MemoryWithOrigins \ + -DLLVM_LIBC_ENABLE_LINTING=OFF + cmake --build llvm-project/build -j2 -- cxx cxxabi + echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + + - name: Generate project files + shell: bash + # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources + run: | + cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ + -DWITH_FUZZERS=ON \ + -DWITH_MAINTAINER_WARNINGS=ON \ + ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} + + - name: Run test cases + # Don't run tests on Windows ARM + if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: ${{ matrix.build-dir || '.' }} + env: + ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 + + - name: Generate coverage report + if: matrix.codecov + shell: bash + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root ${{ matrix.build-src-dir || '.' }} \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + directory: ${{ matrix.build-src-dir || '.' }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml new file mode 100644 index 000000000..1cfa4d7fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + schedule: + - cron: "27 17 * * 0" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ cpp ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml new file mode 100644 index 000000000..02a36005f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/configure.yml @@ -0,0 +1,252 @@ +name: Configure +on: [push, pull_request] +jobs: + configure: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + configure-args: --warn + + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + configure-args: --warn + + - name: Ubuntu GCC OSB + os: ubuntu-latest + compiler: gcc + configure-args: --warn + build-dir: ../build + build-src-dir: ../zlib-ng + + - name: Ubuntu GCC Compat No Opt + os: ubuntu-latest + compiler: gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + + - name: Ubuntu GCC ARM SF + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM SF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No ACLE + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-acle + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No NEON + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-neon + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No ACLE + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-acle + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No NEON + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-neon + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 Compat No Opt + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC MIPS + os: ubuntu-latest + compiler: mips-linux-gnu-gcc + configure-args: --warn + chost: mips-linux-gnu + packages: qemu qemu-user gcc-mips-linux-gnu libc-dev-mips-cross + + - name: Ubuntu GCC MIPS64 + os: ubuntu-latest + compiler: mips64-linux-gnuabi64-gcc + configure-args: --warn + chost: mips64-linux-gnuabi64 + packages: qemu qemu-user gcc-mips64-linux-gnuabi64 libc-dev-mips64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --without-power8 + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + compiler: powerpc64-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + compiler: powerpc64le-linux-gnu-gcc + configure-args: --warn + chost: powerpc64le-linux-gnu + packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross + + - name: Ubuntu GCC S390X + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X No vectorized CRC32 + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static --without-crc32-vx + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X DFLTCC + os: z15 + compiler: gcc + configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu GCC S390X DFLTCC Compat + os: z15 + compiler: gcc + configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + configure-args: --warn --zlib-compat --static + configure-prefix: emconfigure + cflags: -static + ldflags: -static + emu-run: node + + - name: macOS GCC Symbol Prefix + os: macOS-latest + compiler: gcc-11 + configure-args: --sprefix=zTest_ + + - name: macOS GCC Symbol Prefix & Compat + os: macOS-latest + compiler: gcc-11 + configure-args: --zlib-compat --sprefix=zTest_ + + - name: macOS GCC + os: macOS-latest + compiler: gcc-11 + configure-args: --warn + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Generate project files + run: | + mkdir ${{ matrix.build-dir || '.not-used' }} + cd ${{ matrix.build-dir || '.' }} + ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CHOST: ${{ matrix.chost }} + EMU_RUN: ${{ matrix.emu-run }} + CI: true + + - name: Compile source code + run: make -j2 + working-directory: ${{ matrix.build-dir }} + + - name: Run test cases + run: make test + working-directory: ${{ matrix.build-dir }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (configure) + path: | + **/Makefile + ${{ matrix.build-dir || '.' }}/configure.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml new file mode 100644 index 000000000..95d64e67a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/fuzz.yml @@ -0,0 +1,36 @@ +name: OSS-Fuzz +on: + pull_request: + push: + branches: + - stable + - develop + - pre-release + - '2.*' + tags: + - '*' + +jobs: + fuzzing: + name: Fuzzing + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + dry-run: false + + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + fuzz-seconds: 600 + dry-run: false + + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() + with: + name: artifacts + path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml new file mode 100644 index 000000000..c5fea574f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/libpng.yml @@ -0,0 +1,51 @@ +name: Libpng +on: [push, pull_request] +jobs: + libpng: + name: Ubuntu Clang + runs-on: ubuntu-latest + steps: + - name: Checkout repository (zlib-ng) + uses: actions/checkout@v3 + + - name: Generate project files (zlib-ng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_COMPAT=ON \ + -DZLIB_ENABLE_TESTS=OFF + env: + CC: clang + CFLAGS: -fPIC + CI: true + + - name: Compile source code (zlib-ng) + run: cmake --build . -j2 --config Release + + - name: Checkout repository (libpng) + uses: actions/checkout@v3 + with: + repository: glennrp/libpng + path: libpng + + - name: Generate project files (libpng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DPNG_TESTS=ON \ + -DPNG_STATIC=OFF \ + -DZLIB_INCLUDE_DIR=.. \ + -DZLIB_LIBRARY=$PWD/../libz.a + working-directory: libpng + env: + CC: clang + CI: true + + - name: Compile source code (libpng) + run: cmake --build . -j2 --config Release + working-directory: libpng + + - name: Run test cases (libpng) + run: ctest -j2 -C Release --output-on-failure --max-width 120 + working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml new file mode 100644 index 000000000..5de669840 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/link.yml @@ -0,0 +1,66 @@ +name: Link +on: [push, pull_request] +jobs: + zlib: + name: Link zlib + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout zlib repository + uses: actions/checkout@v3 + with: + repository: madler/zlib + path: zlib + + - name: Generate project files (zlib) + run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF + + - name: Compile source code (zlib) + run: cmake --build zlib/build -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 + + zlib-ng-compat: + name: Link zlib-ng compat + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Generate project files (compat) + run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON + + - name: Compile source code (compat) + run: cmake --build compat -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib-ng compat (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml new file mode 100644 index 000000000..38e669093 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/nmake.yml @@ -0,0 +1,68 @@ +name: NMake +on: [push, pull_request] +jobs: + nmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows NMake x86 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86 + + - name: Windows NMake x64 compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes + + - name: Windows NMake x64 Symbol Prefix + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 Symbol Prefix Compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + + - name: Windows NMake ARM No Test + os: windows-2022 + makefile: win32/Makefile.arm + arch: x86_arm + + - name: Windows NMake ARM64 No Test + os: windows-2022 + makefile: win32/Makefile.a64 + arch: x86_arm64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup development environment + uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + + - name: Compile source code + shell: cmd + run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} + + - name: Run test cases + shell: cmd + # Don't run tests on Windows ARM + if: contains(matrix.arch, 'arm') == false + run: | + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml new file mode 100644 index 000000000..be4e1ce50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pigz.yml @@ -0,0 +1,131 @@ +name: Pigz +on: [push, pull_request] +jobs: + pigz: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz + + - name: Ubuntu Clang No Optim + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_optim + cmake-args: -DWITH_OPTIM=OFF + + # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 + - name: Ubuntu Clang No Threads + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_threads + cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_pigz_aarch64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Generate project files + run: | + cmake ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_ROOT=../.. \ + -DWITH_CODE_COVERAGE=ON \ + -DWITH_MAINTAINER_WARNINGS=ON + working-directory: test/pigz + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} + working-directory: test/pigz + + - name: Run test cases + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: test/pigz + + - name: Generate coverage report + if: matrix.codecov + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root . \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml new file mode 100644 index 000000000..4e07f021b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/pkgcheck.yml @@ -0,0 +1,192 @@ +name: Package Check +on: [push, pull_request] +jobs: + pkgcheck: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC -m32 + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + packages: gcc-multilib g++-multilib + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 + cflags: -m32 + cxxflags: -m32 + ldflags: -m32 + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + chost: arm-linux-gnueabihf + compiler: arm-linux-gnueabihf-gcc + cxx-compiler: arm-linux-gnueabihf-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake + packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + chost: aarch64-linux-gnu + compiler: aarch64-linux-gnu-gcc + cxx-compiler: aarch64-linux-gnu-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake + packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross + + - name: Ubuntu GCC MIPS + os: ubuntu-latest + chost: mips-linux-gnu + compiler: mips-linux-gnu-gcc + cxx-compiler: mips-linux-gnu-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips.cmake + packages: qemu gcc-mips-linux-gnu g++-mips-linux-gnu libc6-dev-mips-cross + + - name: Ubuntu GCC MIPS64 + os: ubuntu-latest + chost: mips64-linux-gnuabi64 + compiler: mips64-linux-gnuabi64-gcc + cxx-compiler: mips64-linux-gnuabi64-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mips64.cmake + packages: qemu gcc-mips64-linux-gnuabi64 g++-mips64-linux-gnuabi64 libc6-dev-mips64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + chost: powerpc-linux-gnu + compiler: powerpc-linux-gnu-gcc + cxx-compiler: powerpc-linux-gnu-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + chost: powerpc64le-linux-gnu + compiler: powerpc64le-linux-gnu-gcc + cxx-compiler: powerpc64le-linux-gnu-g++ + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross + + - name: macOS Clang + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + + - name: macOS Clang Native + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON + configure-args: --native + + - name: macOS Clang Symbol Prefix + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + configure-args: --sprefix=zTest_ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ + abigail-tools \ + diffoscope \ + ninja-build + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja diffoscope ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Select Xcode version (macOS) + # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports + # AppleClang linking with libtool using -D argument + # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 + if: runner.os == 'macOS' + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '11.7.0' + + - name: Compare builds + run: sh test/pkgcheck.sh + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Compare builds (compat) + run: sh test/pkgcheck.sh --zlib-compat + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI (compat) + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --zlib-compat --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} + path: | + **/*.abi + btmp1/configure.log + btmp1/CMakeFiles/CMakeOutput.log + btmp1/CMakeFiles/CMakeError.log + btmp2/configure.log + btmp2/CMakeFiles/CMakeOutput.log + btmp2/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml new file mode 100644 index 000000000..b64933cc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.github/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release +on: + push: + tags: + - '*' +jobs: + release: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows MSVC Win32 + os: windows-latest + compiler: cl + cmake-args: -A Win32 + deploy-name: win-x86 + + - name: Windows MSVC Win32 Compat + os: windows-latest + compiler: cl + cmake-args: -A Win32 -DZLIB_COMPAT=ON + deploy-name: win-x86-compat + + - name: Windows MSVC Win64 + os: windows-latest + compiler: cl + cmake-args: -A x64 + deploy-name: win-x86-64 + + - name: Windows MSVC Win64 Compat + os: windows-latest + compiler: cl + cmake-args: -A x64 -DZLIB_COMPAT=ON + deploy-name: win-x86-64-compat + + - name: Windows MSVC ARM + os: windows-latest + compiler: cl + cmake-args: -A ARM + deploy-name: win-arm + + - name: Windows MSVC ARM Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM -DZLIB_COMPAT=ON + deploy-name: win-arm-compat + + - name: Windows MSVC ARM64 + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + deploy-name: win-arm64 + + - name: Windows MSVC ARM64 Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM64 -DZLIB_COMPAT=ON + deploy-name: win-arm64-compat + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set environment variables + shell: bash + run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + + - name: Generate project files + shell: bash + run: | + cmake . ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DZLIB_ENABLE_TESTS=ON \ + -DCMAKE_INSTALL_PREFIX=out \ + -DINSTALL_UTILS=ON + env: + CC: ${{ matrix.compiler }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release --target install + + - name: Package release (Windows) + if: runner.os == 'Windows' + run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md + working-directory: out + + - name: Upload release (Windows) + uses: svenstaro/upload-release-action@v2 + if: runner.os == 'Windows' + with: + asset_name: zlib-ng-${{ matrix.deploy-name }}.zip + file: zlib-ng-${{ matrix.deploy-name }}.zip + tag: ${{env.tag}} + repo_token: ${{ secrets.GITHUB_TOKEN }} + overwrite: true + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.2/.gitignore b/internal-complibs/zlib-ng-2.1.2/.gitignore new file mode 100644 index 000000000..cd4a9c3fe --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.gitignore @@ -0,0 +1,97 @@ +*.diff +*.patch +*.orig +*.rej + +*~ +*.a +*.lo +*.o +*.dylib + +*.gcda +*.gcno +*.gcov + +/benchmark_zlib +/example +/example64 +/examplesh +/gtest_zlib +/libz.so* +/libz-ng.so* +/makefixed +/minigzip +/minigzip64 +/minigzipsh +/switchlevels +/zlib.pc +/zlib-ng.pc + +.DS_Store +*_fuzzer +*.obj +*.exe +*.pdb +*.exp +*.lib +*.dll +*.res +foo.gz +*.manifest +*.opensdf +*.sln +*.sdf +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +.vs + +CMakeCache.txt +CMakeFiles +Testing +/*.cmake +*.stackdump +*._h +zconf.h +zconf.h.cmakein +zconf.h.included +zconf-ng.h +zconf-ng.h.cmakein +ztest* +/test/CTestTestfile.cmake +/test/cmake_install.cmake + +configure.log +a.out + +/Makefile +/arch/arm/Makefile +/arch/generic/Makefile +/arch/power/Makefile +/arch/x86/Makefile +.kdev4 +*.kdev4 + +/Debug +/example.dir +/minigzip.dir +/zlib.dir +/zlibstatic.dir +/test/*.dir/ +/build/ +/build[.-]*/ +/btmp[12]/ +/pkgtmp[12]/ + +/.idea +/cmake-build-debug +/x64/Debug/ +/x64/Release/ +/win32/Debug/ +/win32/Release/ +/ARM*/Debug/ +/ARM*/Release/ +MinSizeRel +RelWithDebInfo +/_deps/googletest* diff --git a/internal-complibs/zlib-ng-2.1.2/.shellcheckrc b/internal-complibs/zlib-ng-2.1.2/.shellcheckrc new file mode 100644 index 000000000..89a1625ff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2140,SC2086,SC2046,SC2015,SC1097,SC1035,SC1036,SC1007,SC2154,SC2155,SC2000,SC2034,SC2016,SC1091,SC1090,SC2212,SC2143,SC2129,SC2102,SC2069,SC1041,SC1042,SC1044,SC1046,SC1119,SC1110,SC1111,SC1112,SC1102,SC1105,SC1101,SC1004,SC1003,SC1012,SC2068,SC2065,SC2064,SC2063,SC2059,SC2053,SC2048,SC2044,SC2032,SC2031,SC2030,SC2029,SC2025,SC2024,SC2022,SC2018,SC2019,SC2017,SC2014,SC2013,SC2012,SC2009,SC2001,SC2098,SC2096,SC2094,SC2091,SC2092,SC2088,SC2087,SC2076,SC2072,SC2071,SC2223,SC2221,SC2222,SC2217,SC2207,SC2206,SC2205,SC2190,SC2188,SC2187,SC2185,SC2179,SC2178,SC2174,SC2168,SC2167,SC2163,SC2161,SC2160,SC2153,SC2150,SC2148,SC2147,SC2146,SC2142,SC2139,SC2126,SC2123,SC2120,SC2119,SC2117,SC2114,SC1117,SC2164,SC1083,SC2004,SC2125,SC2128,SC2011,SC1008,SC1019,SC2093,SC1132,SC1129,SC2236,SC2237,SC2231,SC2230,SC2229,SC2106,SC2102,SC2243,SC2244,SC2245,SC2247,SC2248,SC2249,SC2250,SC2251,SC2252,SC2181 diff --git a/internal-complibs/zlib-ng-2.1.2/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.2/CMakeLists.txt new file mode 100644 index 000000000..424fddf61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/CMakeLists.txt @@ -0,0 +1,1268 @@ +cmake_minimum_required(VERSION 3.5.1) +if(CMAKE_VERSION VERSION_LESS 3.12) + cmake_policy(VERSION ${CMAKE_VERSION}) +else() + cmake_policy(VERSION 3.5.1...3.13.2) +endif() +message(STATUS "Using CMake version ${CMAKE_VERSION}") + +# If not specified on the command line, enable C11 as the default +# Configuration items that affect the global compiler environment standards +# should be issued before the "project" command. +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) # The C standard whose features are requested to build this target +endif() +if(NOT CMAKE_C_STANDARD_REQUIRED) + set(CMAKE_C_STANDARD_REQUIRED ON) # Boolean describing whether the value of C_STANDARD is a requirement +endif() +if(NOT CMAKE_C_EXTENSIONS) + set(CMAKE_C_EXTENSIONS OFF) # Boolean specifying whether compiler specific extensions are requested +endif() +set(VALID_C_STANDARDS "99" "11") +if(NOT CMAKE_C_STANDARD IN_LIST VALID_C_STANDARDS) + MESSAGE(FATAL_ERROR "CMAKE_C_STANDARD:STRING=${CMAKE_C_STANDARD} not in known standards list\n ${VALID_C_STANDARDS}") +endif() + +# Parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9]+.[0-9]+.[0-9]+).*\".*" + "\\1" ZLIB_HEADER_VERSION ${_zlib_h_contents}) +string(REGEX REPLACE ".*#define[ \t]+ZLIBNG_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIBNG_HEADER_VERSION ${_zlib_h_contents}) +message(STATUS "ZLIB_HEADER_VERSION: ${ZLIB_HEADER_VERSION}") +message(STATUS "ZLIBNG_HEADER_VERSION: ${ZLIBNG_HEADER_VERSION}") + +project(zlib VERSION ${ZLIB_HEADER_VERSION} LANGUAGES C) + +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CheckCCompilerFlag) +include(CMakeDependentOption) +include(FeatureSummary) + +include(cmake/detect-arch.cmake) +include(cmake/detect-install-dirs.cmake) +include(cmake/detect-coverage.cmake) +include(cmake/detect-intrinsics.cmake) +include(cmake/detect-sanitizer.cmake) +include(cmake/fallback-macros.cmake) + +if(CMAKE_TOOLCHAIN_FILE) + message(STATUS "Using CMake toolchain: ${CMAKE_TOOLCHAIN_FILE}") +endif() + +# Make sure we use an appropriate BUILD_TYPE by default, "Release" to be exact +# this should select the maximum generic optimisation on the current platform (i.e. -O3 for gcc/clang) +if(NOT GENERATOR_IS_MULTI_CONFIG) + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, standard options are: Debug Release RelWithDebInfo MinSizeRel." + FORCE) + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (default)") + else() + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (selected)") + endif() +endif() + +# +# Options parsing +# +option(WITH_GZFILEOP "Compile with support for gzFile related functions" ON) +option(ZLIB_COMPAT "Compile with zlib compatible API" OFF) +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +option(ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API" ON) +option(WITH_GTEST "Build gtest_zlib" ON) +option(WITH_FUZZERS "Build test/fuzz" OFF) +option(WITH_BENCHMARKS "Build test/benchmarks" OFF) +option(WITH_BENCHMARK_APPS "Build application benchmarks" OFF) +option(WITH_OPTIM "Build with optimisation" ON) +option(WITH_REDUCED_MEM "Reduced memory usage for special cases (reduces performance)" OFF) +option(WITH_NEW_STRATEGIES "Use new strategies" ON) +option(WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)" OFF) +option(WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings" OFF) +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_INFLATE_STRICT "Build with strict inflate distance checking" OFF) +option(WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances" OFF) +option(WITH_UNALIGNED "Support unaligned reads on platforms that support it" ON) + +set(ZLIB_SYMBOL_PREFIX "" CACHE STRING "Give this prefix to all publicly exported symbols. +Useful when embedding into a larger library. +Default is no prefix (empty prefix).") + +# Add multi-choice option +set(WITH_SANITIZER AUTO CACHE STRING "Enable sanitizer support") +set_property(CACHE WITH_SANITIZER PROPERTY STRINGS "Memory" "Address" "Undefined" "Thread") + +if(BASEARCH_ARM_FOUND) + option(WITH_ACLE "Build with ACLE" ON) + option(WITH_NEON "Build with NEON intrinsics" ON) +elseif(BASEARCH_PPC_FOUND) + option(WITH_ALTIVEC "Build with AltiVec (VMX) optimisations for PowerPC" ON) + option(WITH_POWER8 "Build with optimisations for POWER8" ON) + option(WITH_POWER9 "Build with optimisations for POWER9" ON) +elseif(BASEARCH_RISCV_FOUND) + option(WITH_RVV "Build with RVV intrinsics" ON) +elseif(BASEARCH_S360_FOUND) + option(WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z" OFF) + option(WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z" OFF) + option(WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z" ON) +elseif(BASEARCH_X86_FOUND) + option(WITH_AVX2 "Build with AVX2" ON) + option(WITH_AVX512 "Build with AVX512" ON) + option(WITH_AVX512VNNI "Build with AVX512 VNNI extensions" ON) + option(WITH_SSE2 "Build with SSE2" ON) + option(WITH_SSSE3 "Build with SSSE3" ON) + option(WITH_SSE42 "Build with SSE42" ON) + option(WITH_PCLMULQDQ "Build with PCLMULQDQ" ON) + option(WITH_VPCLMULQDQ "Build with VPCLMULQDQ" ON) +endif() + +option(INSTALL_UTILS "Copy minigzip and minideflate during install" OFF) + +mark_as_advanced(FORCE + ZLIB_SYMBOL_PREFIX + WITH_REDUCED_MEM + WITH_ACLE WITH_NEON + WITH_DFLTCC_DEFLATE + WITH_DFLTCC_INFLATE + WITH_CRC32_VX + WITH_AVX2 WITH_SSE2 + WITH_SSSE3 WITH_SSE42 + WITH_PCLMULQDQ + WITH_ALTIVEC + WITH_POWER8 + WITH_POWER9 + WITH_RVV + WITH_INFLATE_STRICT + WITH_INFLATE_ALLOW_INVALID_DIST + WITH_UNALIGNED + INSTALL_UTILS + ) + +if(ZLIB_COMPAT) + add_definitions(-DZLIB_COMPAT) + set(WITH_GZFILEOP ON) + set(SUFFIX "") + set(ZLIB_FULL_VERSION ${ZLIB_HEADER_VERSION}.zlib-ng) +else() + set(SUFFIX "-ng") + set(ZLIB_FULL_VERSION ${ZLIBNG_HEADER_VERSION}) +endif() + +if(WITH_GZFILEOP) + add_definitions(-DWITH_GZFILEOP) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "^Intel") + if(CMAKE_HOST_UNIX) + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wall -Wcheck -Wremarks) + set(WARNFLAGS_DISABLE) + else() + set(WARNFLAGS /Wall) + set(WARNFLAGS_MAINTAINER /W5) + set(WARNFLAGS_DISABLE) + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(MSVC) + # Minimum supported MSVC version is 1800 = Visual Studio 12.0/2013 + # See also https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html + if(MSVC_VERSION VERSION_LESS 1800) + message(SEND_ERROR "Unsupported Visual Studio compiler version (requires 2013 or later).") + endif() + # TODO. ICC can be used through MSVC. I'm not sure if we'd ever see that combination + # (who'd use cmake from an IDE...) but checking for ICC before checking for MSVC should + # avoid mistakes. + # /Oi ? + set(WARNFLAGS /W3) + set(WARNFLAGS_MAINTAINER /W4) + set(WARNFLAGS_DISABLE) + if(BASEARCH_ARM_FOUND) + add_definitions(-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE) + if(NOT "${ARCH}" MATCHES "aarch64") + set(NEONFLAG "/arch:VFPv4") + endif() + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + # Enable warnings in GCC and Clang + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wextra) + set(WARNFLAGS_DISABLE) + if(WITH_NATIVE_INSTRUCTIONS) + if(BASEARCH_PPC_FOUND) + set(NATIVEFLAG "-mcpu=native") + else() + set(NATIVEFLAG "-march=native") + endif() + else() + if(BASEARCH_ARM_FOUND) + if("${ARCH}" MATCHES "arm" AND NOT CMAKE_C_FLAGS MATCHES "-mfloat-abi") + # Auto-detect support for ARM floating point ABI + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=softfp) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_SOFTFP) + if(HAVE_FLOATABI_SOFTFP) + set(FLOATABI -mfloat-abi=softfp) + else() + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=hard) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_HARD) + if(HAVE_FLOATABI_HARD) + set(FLOATABI -mfloat-abi=hard) + endif() + endif() + set(CMAKE_REQUIRED_FLAGS) + if(FLOATABI) + message(STATUS "ARM floating point arch: ${FLOATABI}") + add_compile_options(${FLOATABI}) + else() + message(STATUS "ARM floating point arch not auto-detected") + endif() + endif() + endif() + # Check whether -fno-lto is available + set(CMAKE_REQUIRED_FLAGS "-fno-lto") + check_c_source_compiles( + "int main() { return 0; }" + FNO_LTO_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) + if(FNO_LTO_AVAILABLE) + set(NOLTOFLAG "-fno-lto") + endif() + endif() + if(MINGW) + list(APPEND WARNFLAGS_DISABLE -Wno-pedantic-ms-format) + endif() +else() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not implemented yet on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +endif() + +# Disable LTO +if(NOT WITH_NATIVE_INSTRUCTIONS) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF) + foreach(_cfg_name IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER "${_cfg_name}" _cfg_name_uc) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${_cfg_name_uc} OFF) + endforeach() +endif() + +# Set architecture alignment requirements +if(NOT WITH_UNALIGNED) + add_definitions(-DNO_UNALIGNED) + message(STATUS "Unaligned reads manually disabled") +endif() + +# Apply warning compiler flags +if(WITH_MAINTAINER_WARNINGS) + add_compile_options(${WARNFLAGS} ${WARNFLAGS_MAINTAINER} ${WARNFLAGS_DISABLE}) +else() + add_compile_options(${WARNFLAGS} ${WARNFLAGS_DISABLE}) +endif() + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Replace optimization level 3 added by default with level 2 +if(NOT WITH_CODE_COVERAGE AND NOT MSVC AND NOT CMAKE_C_FLAGS MATCHES "([\\/\\-]O)3") + string(REGEX REPLACE "([\\/\\-]O)3" "\\12" + CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +endif() + +# Set native instruction set compiler flag +if(WITH_NATIVE_INSTRUCTIONS AND DEFINED NATIVEFLAG) + # Apply flag to all source files and compilation checks + add_compile_options(${NATIVEFLAG}) +endif() + +# +# Check for standard/system includes +# +check_include_file(sys/auxv.h HAVE_SYS_AUXV_H) +if(HAVE_SYS_AUXV_H) + add_definitions(-DHAVE_SYS_AUXV_H) +endif() +check_include_file(sys/sdt.h HAVE_SYS_SDT_H) +if(HAVE_SYS_SDT_H) + add_definitions(-DHAVE_SYS_SDT_H) +endif() +check_include_file(unistd.h HAVE_UNISTD_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +else() + check_type_size(_off64_t _OFF64_T) + if(HAVE__OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) + else() + check_type_size(__off64_t __OFF64_T) + endif() +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko and other optional functions +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +check_function_exists(strerror HAVE_STRERROR) +if(NOT HAVE_STRERROR) + add_definitions(-DNO_STRERROR) +endif() + +set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L) +check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) +if(HAVE_POSIX_MEMALIGN) + add_definitions(-DHAVE_POSIX_MEMALIGN) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +set(CMAKE_REQUIRED_DEFINITIONS -D_ISOC11_SOURCE=1) +check_symbol_exists(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) +if(HAVE_ALIGNED_ALLOC) + add_definitions(-DHAVE_ALIGNED_ALLOC) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +if(WITH_SANITIZER STREQUAL "Address") + add_address_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Memory") + add_memory_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Thread") + add_thread_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Undefined") + add_undefined_sanitizer() +endif() + +# +# Check whether compiler supports -fno-semantic-interposition parameter +# +check_c_compiler_flag(-fno-semantic-interposition HAVE_NO_INTERPOSITION) + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using hidden +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"hidden\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_HIDDEN FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_HIDDEN) + add_definitions(-DHAVE_VISIBILITY_HIDDEN) +endif() + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using internal +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"internal\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_INTERNAL FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_INTERNAL) + add_definitions(-DHAVE_VISIBILITY_INTERNAL) +endif() + +# +# Check for __attribute__((aligned(x))) support in the compiler +# +check_c_source_compiles( + "int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; + }" + HAVE_ATTRIBUTE_ALIGNED FAIL_REGEX "aligned") +if(HAVE_ATTRIBUTE_ALIGNED) + add_definitions(-DHAVE_ATTRIBUTE_ALIGNED) +endif() + +# +# check for _Thread_local() support in the compiler +# +check_c_source_compiles( + "_Thread_local int test; + int main(void) { + (void)test; + return 0; + }" + HAVE_THREAD_LOCAL +) +if(HAVE_THREAD_LOCAL) + add_definitions(-DHAVE_THREAD_LOCAL) +endif() + +# +# check for __builtin_ctz() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZ +) +if(HAVE_BUILTIN_CTZ) + add_definitions(-DHAVE_BUILTIN_CTZ) +endif() + +# +# check for __builtin_ctzll() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZLL +) +if(HAVE_BUILTIN_CTZLL) + add_definitions(-DHAVE_BUILTIN_CTZLL) +endif() + +# +# check for ptrdiff_t support +# +check_c_source_compiles( + "#include + int main() { + ptrdiff_t *a; + (void)a; + return 0; + }" + HAVE_PTRDIFF_T +) +if(NOT HAVE_PTRDIFF_T) + set(NEED_PTRDIFF_T 1) + + check_type_size("void *" SIZEOF_DATA_PTR) + message(STATUS "sizeof(void *) is ${SIZEOF_DATA_PTR} bytes") + + if(${SIZEOF_DATA_PTR} MATCHES "4") + set(PTRDIFF_TYPE "uint32_t") + elseif(${SIZEOF_DATA_PTR} MATCHES "8") + set(PTRDIFF_TYPE "uint64_t") + else() + message(FATAL_ERROR "sizeof(void *) is neither 32 nor 64 bit") + endif() +endif() + +# Macro to check if source compiles +# (and, when compiling very natively, also runs). +macro(check_c_source_compile_or_run source flag) + if(CMAKE_CROSSCOMPILING OR NOT WITH_NATIVE_INSTRUCTIONS) + check_c_source_compiles("${source}" ${flag}) + else() + check_c_source_runs("${source}" ${flag}) + endif() +endmacro() + +add_compile_options($<$:-DZLIB_DEBUG>) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +endif() + +if(BASEARCH_X86_FOUND) + # FORCE_SSE2 option will only be shown if HAVE_SSE2_INTRIN is true + if("${ARCH}" MATCHES "i[3-6]86") + cmake_dependent_option(FORCE_SSE2 "Always assume CPU is SSE2 capable" OFF "HAVE_SSE2_INTRIN" OFF) + endif() +endif() + +# +# Enable deflate_quick at level 1 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_QUICK_STRATEGY) +endif() +# +# Enable deflate_medium at level 4-6 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_MEDIUM_STRATEGY) +endif() +# +# Enable inflate compilation options +# +if(WITH_INFLATE_STRICT) + add_definitions(-DINFLATE_STRICT) + message(STATUS "Inflate strict distance checking enabled") +endif() +if(WITH_INFLATE_ALLOW_INVALID_DIST) + add_definitions(-DINFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR) + message(STATUS "Inflate zero data for invalid distances enabled") +endif() +# +# Enable reduced memory configuration +# +if(WITH_REDUCED_MEM) + add_definitions(-DHASH_SIZE=32768u -DGZBUFSIZE=8192) + message(STATUS "Configured for reduced memory environment") +endif() + + +set(ZLIB_ARCH_SRCS) +set(ZLIB_ARCH_HDRS) +set(ARCHDIR "arch/generic") +if(BASEARCH_ARM_FOUND) + set(ARCHDIR "arch/arm") +elseif(BASEARCH_PPC_FOUND) + set(ARCHDIR "arch/power") +elseif(BASEARCH_RISCV_FOUND) + set(ARCHDIR "arch/riscv") +elseif(BASEARCH_S360_FOUND) + set(ARCHDIR "arch/s390") +elseif(BASEARCH_X86_FOUND) + set(ARCHDIR "arch/x86") + if(NOT ${ARCH} MATCHES "x86_64") + add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") + endif() +else() + message(STATUS "No optimized architecture: using ${ARCHDIR}") +endif() + +if(WITH_OPTIM) + if(BASEARCH_ARM_FOUND) + add_definitions(-DARM_FEATURES) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + check_c_source_compiles( + "#include + #include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_HWCAP_HAS_CRC32 + ) + if (ARM_HWCAP_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP) + else() + message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if(ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if (ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + message(STATUS "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + endif() + endif() + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/arm_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/arm_features.c) + if(WITH_ACLE AND NOT "${ARCH}" MATCHES "armv[2-7]") + check_acle_compiler_flag() + if(HAVE_ACLE_FLAG) + add_definitions(-DARM_ACLE) + set(ACLE_SRCS ${ARCHDIR}/crc32_acle.c ${ARCHDIR}/insert_string_acle.c) + set_property(SOURCE ${ACLE_SRCS} PROPERTY COMPILE_FLAGS "${ACLEFLAG} ${NOLTOFLAG}") + list(APPEND ZLIB_ARCH_SRCS ${ACLE_SRCS}) + add_feature_info(ACLE_CRC 1 "Support ACLE optimized CRC hash generation, using \"${ACLEFLAG}\"") + else() + set(WITH_ACLE OFF) + endif() + else() + set(WITH_ACLE OFF) + endif() + if(WITH_NEON) + check_neon_compiler_flag() + if(MFPU_NEON_AVAILABLE) + add_definitions(-DARM_NEON) + set(NEON_SRCS ${ARCHDIR}/adler32_neon.c ${ARCHDIR}/chunkset_neon.c + ${ARCHDIR}/compare256_neon.c ${ARCHDIR}/slide_hash_neon.c) + list(APPEND ZLIB_ARCH_SRCS ${NEON_SRCS}) + set_property(SOURCE ${NEON_SRCS} PROPERTY COMPILE_FLAGS "${NEONFLAG} ${NOLTOFLAG}") + if(MSVC) + add_definitions(-D__ARM_NEON__) + endif() + add_feature_info(NEON_ADLER32 1 "Support NEON instructions in adler32, using \"${NEONFLAG}\"") + add_feature_info(NEON_SLIDEHASH 1 "Support NEON instructions in slide_hash, using \"${NEONFLAG}\"") + check_neon_ld4_intrinsics() + if(NEON_HAS_LD4) + add_definitions(-DARM_NEON_HASLD4) + endif() + else() + set(WITH_NEON OFF) + endif() + endif() + elseif(BASEARCH_PPC_FOUND) + # Common arch detection code + if(WITH_ALTIVEC) + check_ppc_intrinsics() + endif() + if(WITH_POWER8) + check_power8_intrinsics() + endif() + if(WITH_POWER9) + check_power9_intrinsics() + endif() + if(HAVE_VMX OR HAVE_POWER8_INTRIN OR HAVE_POWER9_INTRIN) + add_definitions(-DPOWER_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/power_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/power_features.c) + endif() + # VMX specific options and files + if(WITH_ALTIVEC) + if(HAVE_VMX) + add_definitions(-DPPC_FEATURES) + if(HAVE_ALTIVEC) + add_definitions(-DPPC_VMX) + set(PPC_SRCS ${ARCHDIR}/adler32_vmx.c ${ARCHDIR}/slide_hash_vmx.c) + list(APPEND ZLIB_ARCH_SRCS ${PPC_SRCS}) + add_feature_info(ALTIVEC 1 "Support the AltiVec instruction set, using \"-maltivec\"") + set_property(SOURCE ${PPC_SRCS} PROPERTY COMPILE_FLAGS "${PPCFLAGS}") + else() + set(WITH_ALTIVEC OFF) + endif() + endif() + endif() + # Power8 specific options and files + if(WITH_POWER8) + if(HAVE_POWER8_INTRIN) + add_definitions(-DPOWER8_VSX) + set(POWER8_SRCS ${ARCHDIR}/adler32_power8.c ${ARCHDIR}/chunkset_power8.c ${ARCHDIR}/slide_hash_power8.c) + if("${ARCH}" MATCHES "powerpc64(le)?") + add_definitions(-DPOWER8_VSX_CRC32) + list(APPEND POWER8_SRCS ${ARCHDIR}/crc32_power8.c) + endif() + list(APPEND ZLIB_ARCH_SRCS ${POWER8_SRCS}) + set_property(SOURCE ${POWER8_SRCS} PROPERTY COMPILE_FLAGS "${POWER8FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER8 OFF) + endif() + endif() + # Power9 specific options and files + if(WITH_POWER9) + if(HAVE_POWER9_INTRIN) + add_definitions(-DPOWER9) + set(POWER9_SRCS ${ARCHDIR}/compare256_power9.c) + list(APPEND ZLIB_ARCH_SRCS ${POWER9_SRCS}) + set_property(SOURCE ${POWER9_SRCS} PROPERTY COMPILE_FLAGS "${POWER9FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER9 OFF) + endif() + endif() + elseif(BASEARCH_RISCV_FOUND) + if(WITH_RVV) + check_rvv_intrinsics() + if(HAVE_RVV_INTRIN) + add_definitions(-DRISCV_FEATURES) + add_definitions(-DRISCV_RVV) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/riscv_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/riscv_features.c) + else() + set(WITH_RVV OFF) + endif() + endif() + elseif(BASEARCH_S360_FOUND) + check_s390_intrinsics() + if(HAVE_S390_INTRIN) + add_definitions(-DS390_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/s390_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/s390_features.c) + endif() + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_common.c) + endif() + if(WITH_DFLTCC_DEFLATE) + add_definitions(-DS390_DFLTCC_DEFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_deflate.c) + endif() + if(WITH_DFLTCC_INFLATE) + add_definitions(-DS390_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_inflate.c) + endif() + if(WITH_CRC32_VX) + check_vgfma_intrinsics() + if(HAVE_VGFMA_INTRIN) + add_definitions(-DS390_CRC32_VX) + set(CRC32_VX_SRCS ${ARCHDIR}/crc32-vx.c) + list(APPEND ZLIB_ARCH_SRCS ${CRC32_VX_SRCS}) + set_property(SOURCE ${CRC32_VX_SRCS} PROPERTY COMPILE_FLAGS "${VGFMAFLAG} ${NOLTOFLAG}") + else() + set(WITH_CRC32_VX OFF) + endif() + endif() + elseif(BASEARCH_X86_FOUND) + add_definitions(-DX86_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/x86_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/x86_features.c) + if(MSVC) + list(APPEND ZLIB_ARCH_HDRS fallback_builtins.h) + endif() + if(WITH_AVX2) + check_avx2_intrinsics() + if(HAVE_AVX2_INTRIN) + add_definitions(-DX86_AVX2) + set(AVX2_SRCS ${ARCHDIR}/slide_hash_avx2.c) + add_feature_info(AVX2_SLIDEHASH 1 "Support AVX2 optimized slide_hash, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/chunkset_avx2.c) + add_feature_info(AVX2_CHUNKSET 1 "Support AVX2 optimized chunkset, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/compare256_avx2.c) + add_feature_info(AVX2_COMPARE256 1 "Support AVX2 optimized compare256, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/adler32_avx2.c) + add_feature_info(AVX2_ADLER32 1 "Support AVX2-accelerated adler32, using \"${AVX2FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX2_SRCS}) + set_property(SOURCE ${AVX2_SRCS} PROPERTY COMPILE_FLAGS "${AVX2FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX2 OFF) + endif() + endif() + if(WITH_AVX512) + check_avx512_intrinsics() + if(HAVE_AVX512_INTRIN) + add_definitions(-DX86_AVX512) + list(APPEND AVX512_SRCS ${ARCHDIR}/adler32_avx512.c) + add_feature_info(AVX512_ADLER32 1 "Support AVX512-accelerated adler32, using \"${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX512_SRCS}) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/adler32_avx512_p.h) + if(HAVE_MASK_INTRIN) + add_definitions(-DX86_MASK_INTRIN) + endif() + set_property(SOURCE ${AVX512_SRCS} PROPERTY COMPILE_FLAGS "${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512 OFF) + endif() + endif() + if(WITH_AVX512VNNI) + check_avx512vnni_intrinsics() + if(HAVE_AVX512VNNI_INTRIN) + add_definitions(-DX86_AVX512VNNI) + add_feature_info(AVX512VNNI_ADLER32 1 "Support AVX512VNNI adler32, using \"${AVX512VNNIFLAG}\"") + list(APPEND AVX512VNNI_SRCS ${ARCHDIR}/adler32_avx512_vnni.c) + list(APPEND ZLIB_ARCH_SRCS ${AVX512VNNI_SRCS}) + set_property(SOURCE ${AVX512VNNI_SRCS} PROPERTY COMPILE_FLAGS "${AVX512VNNIFLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512VNNI OFF) + endif() + endif() + if(WITH_SSE42) + check_sse42_intrinsics() + if(HAVE_SSE42CRC_INLINE_ASM OR HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42) + set(SSE42_SRCS ${ARCHDIR}/adler32_sse42.c ${ARCHDIR}/insert_string_sse42.c) + add_feature_info(SSE42_CRC 1 "Support SSE4.2 optimized CRC hash generation, using \"${SSE42FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSE42_SRCS}) + set_property(SOURCE ${SSE42_SRCS} PROPERTY COMPILE_FLAGS "${SSE42FLAG} ${NOLTOFLAG}") + if(HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42_CRC_INTRIN) + endif() + else() + set(WITH_SSE42 OFF) + endif() + endif() + if(WITH_SSE2) + check_sse2_intrinsics() + if(HAVE_SSE2_INTRIN) + add_definitions(-DX86_SSE2) + set(SSE2_SRCS ${ARCHDIR}/chunkset_sse2.c ${ARCHDIR}/compare256_sse2.c ${ARCHDIR}/slide_hash_sse2.c) + list(APPEND ZLIB_ARCH_SRCS ${SSE2_SRCS}) + if(NOT ${ARCH} MATCHES "x86_64") + set_property(SOURCE ${SSE2_SRCS} PROPERTY COMPILE_FLAGS "${SSE2FLAG} ${NOLTOFLAG}") + add_feature_info(FORCE_SSE2 FORCE_SSE2 "Assume CPU is SSE2 capable") + if(FORCE_SSE2) + add_definitions(-DX86_NOCHECK_SSE2) + endif() + endif() + else() + set(WITH_SSE2 OFF) + endif() + endif() + if(WITH_SSSE3) + check_ssse3_intrinsics() + if(HAVE_SSSE3_INTRIN) + add_definitions(-DX86_SSSE3) + set(SSSE3_SRCS ${ARCHDIR}/adler32_ssse3.c ${ARCHDIR}/chunkset_ssse3.c) + add_feature_info(SSSE3_ADLER32 1 "Support SSSE3-accelerated adler32, using \"${SSSE3FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSSE3_SRCS}) + set_property(SOURCE ${SSSE3_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${NOLTOFLAG}") + else() + set(WITH_SSSE3 OFF) + endif() + endif() + if(WITH_PCLMULQDQ AND WITH_SSSE3 AND WITH_SSE42) + check_pclmulqdq_intrinsics() + if(HAVE_PCLMULQDQ_INTRIN AND HAVE_SSSE3_INTRIN) + add_definitions(-DX86_PCLMULQDQ_CRC) + set(PCLMULQDQ_SRCS ${ARCHDIR}/crc32_pclmulqdq.c) + add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ, using \"${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${PCLMULQDQ_SRCS}) + set_property(SOURCE ${PCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${NOLTOFLAG}") + + if(WITH_VPCLMULQDQ AND WITH_AVX512) + check_vpclmulqdq_intrinsics() + if(HAVE_VPCLMULQDQ_INTRIN AND HAVE_AVX512_INTRIN) + add_definitions(-DX86_VPCLMULQDQ_CRC) + set(VPCLMULQDQ_SRCS ${ARCHDIR}/crc32_vpclmulqdq.c) + add_feature_info(VPCLMUL_CRC 1 "Support CRC hash generation using VPCLMULQDQ, using \"${VPCLMULFLAG} ${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${VPCLMULQDQ_SRCS}) + set_property(SOURCE ${VPCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${VPCLMULFLAG} ${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + check_xsave_intrinsics() + if(HAVE_XSAVE_INTRIN) + add_feature_info(XSAVE 1 "Support XSAVE intrinsics using \"${XSAVEFLAG}\"") + set_property(SOURCE ${ARCHDIR}/x86_features.c PROPERTY COMPILE_FLAGS "${XSAVEFLAG}") + endif() + endif() +endif() + +message(STATUS "Architecture-specific source files: ${ZLIB_ARCH_SRCS}") + +#============================================================================ +# zconf.h +#============================================================================ + +macro(generate_cmakein input output) + file(REMOVE ${output}) + file(STRINGS ${input} _lines) + foreach(_line IN LISTS _lines) + string(REGEX REPLACE "#ifdef HAVE_UNISTD_H.*" "@ZCONF_UNISTD_LINE@" _line "${_line}") + string(REGEX REPLACE "#ifdef NEED_PTRDIFF_T.*" "@ZCONF_PTRDIFF_LINE@" _line "${_line}") + if(NEED_PTRDIFF_T) + string(REGEX REPLACE "typedef PTRDIFF_TYPE" "typedef @PTRDIFF_TYPE@" _line "${_line}") + endif() + file(APPEND ${output} "${_line}\n") + endforeach() +endmacro(generate_cmakein) + +generate_cmakein( ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.in ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein ) + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h") + message(STATUS "to 'zconf${SUFFIX}.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.included) + endif() + + # If we're doing an out of source build and the user has a zconf.h.cmakein + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein") + message(STATUS "to 'zconf${SUFFIX}.h.cmakeincluded' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakeincluded) + endif() +endif() + +# Refer to prefix symbolically to ease relocation by end user, +# as Makefile-generated .pc file does. +string(FIND "${CMAKE_INSTALL_INCLUDEDIR}" "${CMAKE_INSTALL_PREFIX}/" INCLUDEDIR_POS) +string(FIND "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_PREFIX}/" LIBDIR_POS) +string(LENGTH "${CMAKE_INSTALL_PREFIX}/" INSTALL_PREFIX_LEN) + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(PC_INC_INSTALL_DIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +elseif(INCLUDEDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_INCLUDEDIR}" "${INSTALL_PREFIX_LEN}" "-1" INCLUDEDIR_RELATIVE) + set(PC_INC_INSTALL_DIR "\${prefix}/${INCLUDEDIR_RELATIVE}") +else() + set(PC_INC_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +endif() + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +elseif(LIBDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_LIBDIR}" "${INSTALL_PREFIX_LEN}" "-1" LIBDIR_RELATIVE) + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${LIBDIR_RELATIVE}") +else() + set(PC_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") +endif() + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h +) +set(ZLIB_PRIVATE_HDRS + adler32_p.h + chunkset_tpl.h + compare256_rle.h + cpu_features.h + crc32_braid_p.h + crc32_braid_comb_p.h + crc32_braid_tbl.h + crc32_fold.h + deflate.h + deflate_p.h + functable.h + inffast_tpl.h + inffixed_tbl.h + inflate.h + inflate_p.h + inftrees.h + insert_string_tpl.h + match_tpl.h + trees.h + trees_emit.h + trees_tbl.h + zbuild.h + zendian.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + adler32_fold.c + chunkset.c + compare256.c + compress.c + cpu_features.c + crc32_braid.c + crc32_braid_comb.c + crc32_fold.c + deflate.c + deflate_fast.c + deflate_huff.c + deflate_medium.c + deflate_quick.c + deflate_rle.c + deflate_slow.c + deflate_stored.c + functable.c + infback.c + inflate.c + inftrees.c + insert_string.c + insert_string_roll.c + slide_hash.c + trees.c + uncompr.c + zutil.c +) + +set(ZLIB_GZFILE_PRIVATE_HDRS + gzguts.h +) +set(ZLIB_GZFILE_SRCS + gzlib.c + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c + gzwrite.c +) + +set(ZLIB_ALL_SRCS ${ZLIB_SRCS} ${ZLIB_ARCH_HDRS} ${ZLIB_ARCH_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +if(WITH_GZFILEOP) + list(APPEND ZLIB_ALL_SRCS ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS win32/zlib${SUFFIX}1.rc) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS) + add_library(zlib SHARED ${ZLIB_ALL_SRCS} ${ZLIB_DLL_SRCS}) + add_library(zlibstatic STATIC ${ZLIB_ALL_SRCS}) + + set(ZLIB_INSTALL_LIBRARIES zlib zlibstatic) +else() + add_library(zlib ${ZLIB_ALL_SRCS}) + + if(BUILD_SHARED_LIBS) + target_sources(zlib PRIVATE ${ZLIB_DLL_SRCS}) + else() + add_library(zlibstatic ALIAS zlib) + endif() + + set(ZLIB_INSTALL_LIBRARIES zlib) +endif() + +foreach(ZLIB_INSTALL_LIBRARY ${ZLIB_INSTALL_LIBRARIES}) + if(NOT ZLIB_COMPAT) + target_compile_definitions(${ZLIB_INSTALL_LIBRARY} PUBLIC ZLIBNG_NATIVE_API) + endif() + target_include_directories(${ZLIB_INSTALL_LIBRARY} PUBLIC + "$" + "$") +endforeach() + +if(WIN32) + # Shared library + if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlib${SUFFIX}) + endif() + # Static library + if(NOT DEFINED BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + elseif(NOT BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlib PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + endif() +else() + # On unix-like platforms the library is almost always called libz + set_target_properties(${ZLIB_INSTALL_LIBRARIES} PROPERTIES OUTPUT_NAME z${SUFFIX}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SOVERSION 1) + else() + set_target_properties(zlib PROPERTIES SOVERSION 2) + endif() + + if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) + endif() + + if(UNIX) + if(HAVE_NO_INTERPOSITION) + set_target_properties(zlib PROPERTIES COMPILE_FLAGS "-fno-semantic-interposition") + endif() + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS + "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.map\"") + else() + # Match configure/make's behavior (i.e. don't use @rpath on mac). + set_target_properties(zlib PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}") + endif() + endif() + if(MSYS) + # Suppress version number from shared library name + set(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 0) + elseif(WIN32) + # Creates zlib1.dll when building shared library version + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") + else() + set_target_properties(zlib PROPERTIES SUFFIX "2.dll") + endif() + endif() +endif() + +if(HAVE_UNISTD_H) + SET(ZCONF_UNISTD_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_UNISTD_LINE "#if 0 /* was set to #if 0 by configure/cmake/etc */") +endif() +if(NEED_PTRDIFF_T) + SET(ZCONF_PTRDIFF_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_PTRDIFF_LINE "#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */") +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.pc) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file(${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gzread.c.in + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c @ONLY) + + +if (NOT ZLIB_SYMBOL_PREFIX STREQUAL "") + add_feature_info(ZLIB_SYMBOL_PREFIX ON "Publicly exported symbols have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h @ONLY) +else() + add_feature_info(ZLIB_SYMBOL_PREFIX OFF "Publicly exported symbols DO NOT have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling.h.empty + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h COPYONLY) +endif() +# add_definitions(-DZLIB_SYMBOL_PREFIX=${ZLIB_SYMBOL_PREFIX}) # not needed + + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${ZLIB_INSTALL_LIBRARIES} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib_name_mangling${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zconf${SUFFIX}.h) +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL) + install(FILES ${ZLIB_PC} DESTINATION "${PKGCONFIG_INSTALL_DIR}") +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +if(ZLIB_ENABLE_TESTS) + enable_testing() + + if(BUILD_SHARED_LIBS) + if(ZLIBNG_ENABLE_TESTS) + message(STATUS "Disabling zlib-ng tests because shared libraries are enabled") + set(ZLIBNG_ENABLE_TESTS OFF) + endif() + + if(WITH_BENCHMARKS OR WITH_BENCHMARK_APPS) + message(STATUS "Disabling benchmarks because shared libraries are enabled") + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARK_APPS OFF) + endif() + endif() + + add_subdirectory(test) +endif() + +add_feature_info(WITH_GZFILEOP WITH_GZFILEOP "Compile with support for gzFile related functions") +add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Compile with zlib compatible API") +add_feature_info(ZLIB_ENABLE_TESTS ZLIB_ENABLE_TESTS "Build test binaries") +add_feature_info(ZLIBNG_ENABLE_TESTS ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API") +add_feature_info(WITH_SANITIZER WITH_SANITIZER "Enable sanitizer support") +add_feature_info(WITH_GTEST WITH_GTEST "Build gtest_zlib") +add_feature_info(WITH_FUZZERS WITH_FUZZERS "Build test/fuzz") +add_feature_info(WITH_BENCHMARKS WITH_BENCHMARKS "Build test/benchmarks") +add_feature_info(WITH_BENCHMARK_APPS WITH_BENCHMARK_APPS "Build application benchmarks") +add_feature_info(WITH_OPTIM WITH_OPTIM "Build with optimisation") +add_feature_info(WITH_NEW_STRATEGIES WITH_NEW_STRATEGIES "Use new strategies") +add_feature_info(WITH_NATIVE_INSTRUCTIONS WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)") +add_feature_info(WITH_MAINTAINER_WARNINGS WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings") +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_INFLATE_STRICT WITH_INFLATE_STRICT "Build with strict inflate distance checking") +add_feature_info(WITH_INFLATE_ALLOW_INVALID_DIST WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances") + +if(BASEARCH_ARM_FOUND) + add_feature_info(WITH_ACLE WITH_ACLE "Build with ACLE") + add_feature_info(WITH_NEON WITH_NEON "Build with NEON intrinsics") +elseif(BASEARCH_PPC_FOUND) + add_feature_info(WITH_ALTIVEC WITH_ALTIVEC "Build with AltiVec optimisations") + add_feature_info(WITH_POWER8 WITH_POWER8 "Build with optimisations for POWER8") + add_feature_info(WITH_POWER9 WITH_POWER9 "Build with optimisations for POWER9") +elseif(BASEARCH_RISCV_FOUND) + add_feature_info(WITH_RVV WITH_RVV "Build with RVV intrinsics") +elseif(BASEARCH_S360_FOUND) + add_feature_info(WITH_DFLTCC_DEFLATE WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z") + add_feature_info(WITH_DFLTCC_INFLATE WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z") + add_feature_info(WITH_CRC32_VX WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z") +elseif(BASEARCH_X86_FOUND) + add_feature_info(WITH_AVX2 WITH_AVX2 "Build with AVX2") + add_feature_info(WITH_AVX512 WITH_AVX512 "Build with AVX512") + add_feature_info(WITH_AVX512VNNI WITH_AVX512VNNI "Build with AVX512 VNNI") + add_feature_info(WITH_SSE2 WITH_SSE2 "Build with SSE2") + add_feature_info(WITH_SSSE3 WITH_SSSE3 "Build with SSSE3") + add_feature_info(WITH_SSE42 WITH_SSE42 "Build with SSE42") + add_feature_info(WITH_PCLMULQDQ WITH_PCLMULQDQ "Build with PCLMULQDQ") + add_feature_info(WITH_VPCLMULQDQ WITH_VPCLMULQDQ "Build with VPCLMULQDQ") +endif() + +add_feature_info(INSTALL_UTILS INSTALL_UTILS "Copy minigzip and minideflate during install") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.2/FAQ.zlib b/internal-complibs/zlib-ng-2.1.2/FAQ.zlib new file mode 100644 index 000000000..163160c10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/FAQ.zlib @@ -0,0 +1,374 @@ +## +# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.11 +## + + + + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +https://zlib.net/ which may have more recent information. +The latest zlib FAQ is at https://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at https://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * https://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See https://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See https://www.pdflib.com/ . To modify PDF forms, see + https://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com/ for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + https://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + https://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: https://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, https://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://infozip.sourceforge.net/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/internal-complibs/zlib-ng-2.1.2/INDEX.md b/internal-complibs/zlib-ng-2.1.2/INDEX.md new file mode 100644 index 000000000..22fd470e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/INDEX.md @@ -0,0 +1,36 @@ +Contents +-------- + +| Name | Description | +|:-----------------|:---------------------------------------------------------------| +| arch/ | Architecture-specific code | +| doc/ | Documentation for formats and algorithms | +| test/example.c | Zlib usages examples for build testing | +| test/minigzip.c | Minimal gzip-like functionality for build testing | +| test/infcover.c | Inflate code coverage for build testing | +| win32/ | Shared library version resources for Windows | +| CMakeLists.txt | Cmake build script | +| configure | Bash configure/build script | +| adler32.c | Compute the Adler-32 checksum of a data stream | +| chunkset.* | Inline functions to copy small data chunks | +| compress.c | Compress a memory buffer | +| deflate.* | Compress data using the deflate algorithm | +| deflate_fast.c | Compress data using the deflate algorithm with fast strategy | +| deflate_medium.c | Compress data using the deflate algorithm with medium strategy | +| deflate_slow.c | Compress data using the deflate algorithm with slow strategy | +| functable.* | Struct containing function pointers to optimized functions | +| gzguts.h | Internal definitions for gzip operations | +| gzlib.c | Functions common to reading and writing gzip files | +| gzread.c | Read gzip files | +| gzwrite.c | Write gzip files | +| infback.* | Inflate using a callback interface | +| inflate.* | Decompress data | +| inffast.* | Decompress data with speed optimizations | +| inffixed_tbl.h | Table for decoding fixed codes | +| inftrees.h | Generate Huffman trees for efficient decoding | +| trees.* | Output deflated data using Huffman coding | +| uncompr.c | Decompress a memory buffer | +| zconf.h.cmakein | zconf.h template for cmake | +| zendian.h | BYTE_ORDER for endian tests | +| zlib.map | Linux symbol information | +| zlib.pc.in | Pkg-config template | diff --git a/internal-complibs/zlib-ng-2.1.2/LICENSE.md b/internal-complibs/zlib-ng-2.1.2/LICENSE.md new file mode 100644 index 000000000..adb48d472 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/LICENSE.md @@ -0,0 +1,19 @@ +(C) 1995-2013 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/internal-complibs/zlib-ng-2.1.2/Makefile.in b/internal-complibs/zlib-ng-2.1.2/Makefile.in new file mode 100644 index 000000000..deb3ebcd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/Makefile.in @@ -0,0 +1,395 @@ +# Makefile for zlib +# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DZLIB_DEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS=-L. +LIBNAME1=libz-ng +LIBNAME2=zlib-ng +SUFFIX=-ng +TEST_LIBS=$(LIBNAME1).a +LDSHARED=$(CC) +LDSHAREDFLAGS=-shared + +VER=2.1.2 +VER1=2 + +STATICLIB=$(LIBNAME1).a +SHAREDLIB=$(LIBNAME1).so +SHAREDLIBV=$(LIBNAME1).so.$(VER) +SHAREDLIBM=$(LIBNAME1).so.$(VER1) +IMPORTLIB= +SHAREDTARGET=$(LIBNAME1).so.$(VER) +PKGFILE=$(LIBNAME2).pc + +LIBS=$(STATICLIB) $(SHAREDTARGET) + +AR=ar +ARFLAGS=rc +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC= +EXE= + +SRCDIR=. +INCLUDES=-I$(SRCDIR) + +BUILDDIR=. + +ARCHDIR=arch/generic +ARCH_STATIC_OBJS= +ARCH_SHARED_OBJS= + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig + +OBJZ = \ + adler32.o \ + adler32_fold.o \ + chunkset.o \ + compare256.o \ + compress.o \ + cpu_features.o \ + crc32_braid.o \ + crc32_braid_comb.o \ + crc32_fold.o \ + deflate.o \ + deflate_fast.o \ + deflate_huff.o \ + deflate_medium.o \ + deflate_quick.o \ + deflate_rle.o \ + deflate_slow.o \ + deflate_stored.o \ + functable.o \ + infback.o \ + inflate.o \ + inftrees.o \ + insert_string.o \ + insert_string_roll.o \ + slide_hash.o \ + trees.o \ + uncompr.o \ + zutil.o \ + $(ARCH_STATIC_OBJS) + +OBJG = \ + gzlib.o \ + gzread.o \ + gzwrite.o + +TESTOBJG = +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = \ + adler32.lo \ + adler32_fold.lo \ + chunkset.lo \ + compare256.lo \ + compress.lo \ + cpu_features.lo \ + crc32_braid.lo \ + crc32_braid_comb.lo \ + crc32_fold.lo \ + deflate.lo \ + deflate_fast.lo \ + deflate_huff.lo \ + deflate_medium.lo \ + deflate_quick.lo \ + deflate_rle.lo \ + deflate_slow.lo \ + deflate_stored.lo \ + functable.lo \ + infback.lo \ + inflate.lo \ + inftrees.lo \ + insert_string.lo \ + insert_string_roll.lo \ + slide_hash.lo \ + trees.lo \ + uncompr.lo \ + zutil.lo \ + $(ARCH_SHARED_OBJS) + +PIC_OBJG = \ + gzlib.lo \ + gzread.lo \ + gzwrite.lo + +PIC_TESTOBJG = +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +OBJS = $(OBJC) + +PIC_OBJS = $(PIC_OBJC) + +all: static shared + +static: example$(EXE) minigzip$(EXE) makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +check: test + +.SECONDARY: + +$(ARCHDIR)/%.o: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +$(ARCHDIR)/%.lo: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +%.o: $(ARCHDIR)/%.o + -cp $< $@ + +%.lo: $(ARCHDIR)/%.lo + -cp $< $@ + +test: all + $(MAKE) -C test + +infcover.o: $(SRCDIR)/test/infcover.c zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/infcover.c + +infcover$(EXE): infcover.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ infcover.o $(STATICLIB) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +cover: infcover$(EXE) + rm -f *.gcda + ./infcover + gcov inf*.c + +$(STATICLIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +example.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/example.c + +minigzip.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/minigzip.c + +makefixed.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makefixed.c + +maketrees.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/maketrees.c + +makecrct.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makecrct.c + +zlibrc.o: $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + $(RC) $(RCFLAGS) -o $@ $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + +.SUFFIXES: .lo + +%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +%.lo: $(SRCDIR)/%.c + $(CC) $(SFLAGS) -DPIC $(INCLUDES) -c -o $@ $< + +gzlib.o: $(SRCDIR)/gzlib.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzlib.lo: $(SRCDIR)/gzlib.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.o: gzread.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.lo: gzread.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.o: $(SRCDIR)/gzwrite.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.lo: $(SRCDIR)/gzwrite.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +$(SHAREDTARGET): $(PIC_OBJS) $(DEFFILE) $(RCOBJS) +ifneq ($(SHAREDTARGET),) + $(LDSHARED) $(CFLAGS) $(LDSHAREDFLAGS) $(LDFLAGS) -o $@ $(DEFFILE) $(PIC_OBJS) $(RCOBJS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) +endif +endif + +example$(EXE): example.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzip$(EXE): minigzip.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzipsh$(EXE): minigzip.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + + +examplesh$(EXE): example.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makefixed$(EXE): makefixed.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makefixed.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +maketrees$(EXE): maketrees.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ maketrees.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makecrct$(EXE): makecrct.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makecrct.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +install-shared: $(SHAREDTARGET) +ifneq ($(SHAREDTARGET),) + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) + cp $(SHAREDTARGET) $(DESTDIR)$(sharedlibdir) + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ($(LDCONFIG) || true) >/dev/null 2>&1 +# ldconfig is for Linux +endif +ifneq ($(IMPORTLIB),) + cp $(IMPORTLIB) $(DESTDIR)$(sharedlibdir) + chmod 644 $(DESTDIR)$(sharedlibdir)/$(IMPORTLIB) +endif +endif + +install-static: $(STATICLIB) + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/$(STATICLIB) || true) >/dev/null 2>&1 +# The ranlib in install-static is needed on NeXTSTEP which checks file times + +install-libs: install-shared install-static + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + cp $(PKGFILE) $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + rm -f $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + cp zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zlib$(SUFFIX).h + cp zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h + cp zlib_name_mangling$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + chmod 644 $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + +uninstall-static: + cd $(DESTDIR)$(libdir) && rm -f $(STATICLIB) + +uninstall-shared: +ifneq ($(SHAREDLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM) +endif +ifneq ($(IMPORTLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(IMPORTLIB) +endif + +uninstall: uninstall-static uninstall-shared + cd $(DESTDIR)$(includedir) && rm -f zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + cd $(DESTDIR)$(pkgconfigdir) && rm -f $(PKGFILE) + +mostlyclean: clean +clean: + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) clean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test clean; fi + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) minigzipsh$(EXE) \ + infcover makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) \ + $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \ + foo.gz so_locations \ + _match.s maketree + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f a.out a.exe + rm -f *._h + rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +maintainer-clean: distclean +distclean: clean + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) distclean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test distclean; fi + rm -f $(PKGFILE) configure.log zconf.h zconf.h.cmakein zlib$(SUFFIX).h zlib_name_mangling$(SUFFIX)}.h *.pc + -@rm -f .DS_Store +# Reset Makefile if building inside source tree + @if [ -f Makefile.in ]; then \ + printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ + printf '\ndistclean:\n\t$(MAKE) -f Makefile.in distclean\n' >> Makefile ; \ + touch -r $(SRCDIR)/Makefile.in Makefile ; fi +# Reset zconf.h and zconf.h.cmakein if building inside source tree + @if [ -f zconf.h.in ]; then \ + cp -p $(SRCDIR)/zconf.h.in zconf.h ; \ + grep -v '^#cmakedefine' $(SRCDIR)/zconf.h.in > zconf.h.cmakein &&\ + touch -r $(SRCDIR)/zconf.h.in zconf.h.cmakein ; fi +# Cleanup these files if building outside source tree + @if [ ! -f README.md ]; then rm -f Makefile; fi +# Remove arch and test directory if building outside source tree + @if [ ! -f $(ARCHDIR)/Makefile.in ]; then rm -rf arch; fi + @if [ ! -f test/Makefile.in ]; then rm -rf test; fi + +tags: + etags $(SRCDIR)/*.[ch] diff --git a/internal-complibs/zlib-ng-2.1.2/PORTING.md b/internal-complibs/zlib-ng-2.1.2/PORTING.md new file mode 100644 index 000000000..c48522e3a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/PORTING.md @@ -0,0 +1,79 @@ +Porting applications to use zlib-ng +=================================== + +Zlib-ng can be used/compiled in two different modes, that require some +consideration by the application developer. + +zlib-compat mode +---------------- +Zlib-ng can be compiled in zlib-compat mode, suitable for zlib-replacement +in a single application or system-wide. + +Please note that zlib-ng in zlib-compat mode tries to maintain both API and +ABI compatibility with the original zlib. Any issues regarding compatibility +can be reported as bugs. + +In certain instances you may not be able to simply replace the zlib library/dll +files and expect the application to work. The application may need to be +recompiled against the zlib-ng headers and libs to ensure full compatibility. + +It is also possible for the deflate output stream to differ from the original +zlib due to algorithmic differences between the two libraries. Any tests or +applications that depend on the exact length of the deflate stream being a +certain value will need to be updated. + +**Advantages:** +- Easy to port to, since it only requires a recompile of the application and + no changes to the application code. + +**Disadvantages:** +- Can conflict with a system-installed zlib, as that can often be linked in + by another library you are linking into your application. This can cause + crashes or incorrect output. +- If your application is pre-allocating a memory buffer and you are providing + deflate/inflate init with your own allocator that allocates from that buffer + (looking at you nginx), you should be aware that zlib-ng needs to allocate + more memory than stock zlib needs. The same problem exists with Intel’s and + Cloudflare’s zlib forks. Doing this is not recommended since it makes it + very hard to maintain compatibility over time. + +**Build Considerations:** +- Compile against the *zlib.h* provided by zlib-ng +- Configuration header is named *zconf.h* +- Static library is *libz.a* on Unix and macOS, or *zlib.lib* on Windows +- Shared library is *libz.so* on Unix, *libz.dylib* on macOS, or *zlib1.dll* + on Windows +- Type `z_size_t` is *unsigned __int64* on 64-bit Windows, and *unsigned long* on 32-bit Windows, Unix and macOS +- Type `z_uintmax_t` is *unsigned long* in zlib-compat mode, and *size_t* with zlib-ng API + +zlib-ng native mode +------------------- +Zlib-ng in native mode is suitable for co-existing with the standard zlib +library, allowing applications to implement support and testing separately. + +The zlib-ng native has implemented some modernization and simplifications +in its API, intended to make life easier for application developers. + +**Advantages:** +- Does not conflict with other zlib implementations, and can co-exist as a + system library along with zlib. +- In certain places zlib-ng native uses more appropriate data types, removing + the need for some workarounds in the API compared to zlib. + +**Disadvantages:** +- Requires minor changes to applications to use the prefixed zlib-ng + function calls and structs. Usually this means a small prefix `zng_` has to be added. + +**Build Considerations:** +- Compile against *zlib-ng.h* +- Configuration header is named *zconf-ng.h* +- Static library is *libz-ng.a* on Unix and macOS, or *zlib-ng.lib* on Windows +- Shared library is *libz-ng.so* on Unix, *libz-ng.dylib* on macOS, or + *zlib-ng2.dll* on Windows +- Type `z_size_t` is *size_t* + +zlib-ng compile-time detection +------------------------------ + +To distinguish zlib-ng from other zlib implementations at compile-time check for the +existence of `ZLIBNG_VERSION` defined in the zlib header. diff --git a/internal-complibs/zlib-ng-2.1.2/README.md b/internal-complibs/zlib-ng-2.1.2/README.md new file mode 100644 index 000000000..75b716b60 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/README.md @@ -0,0 +1,216 @@ +| CI | Stable | Develop | +|:---|:-------|:--------| +| GitHub Actions | [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20CMake/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20Configure/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20NMake/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions) | [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20CMake/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20Configure/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20NMake/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions) | +| CodeFactor | [![CodeFactor](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/badge/stable)](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/overview/stable) | [![CodeFactor](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/badge/develop)](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/overview/develop) | +| OSS-Fuzz | [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/zlib-ng.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zlib-ng) | [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/zlib-ng.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zlib-ng) | +| Codecov | [![codecov](https://codecov.io/github/zlib-ng/zlib-ng/branch/stable/graph/badge.svg?token=uKsgK9LIuC)](https://codecov.io/github/zlib-ng/zlib-ng/tree/stable) | [![codecov](https://codecov.io/github/zlib-ng/zlib-ng/branch/develop/graph/badge.svg?token=uKsgK9LIuC)](https://codecov.io/github/zlib-ng/zlib-ng/tree/develop) | + +## zlib-ng +*zlib data compression library for the next generation systems* + +Maintained by Hans Kristian Rosbach + aka Dead2 (zlib-ng àt circlestorm dót org) + +Features +-------- + +* Zlib compatible API with support for dual-linking +* Modernized native API based on zlib API for ease of porting +* Modern C11 syntax and a clean code layout +* Deflate medium and quick algorithms based on Intel’s zlib fork +* Support for CPU intrinsics when available + * Adler32 implementation using SSSE3, AVX2, AVX512, AVX512-VNNI, Neon, VMX & VSX + * CRC32-B implementation using PCLMULQDQ, VPCLMULQDQ, ACLE, & IBM Z + * Hash table implementation using CRC32-C intrinsics on x86 and ARM + * Slide hash implementations using SSE2, AVX2, Neon, VMX & VSX + * Compare256 implementations using SSE2, AVX2, Neon, & POWER9 + * Inflate chunk copying using SSE2, SSSE3, AVX, Neon & VSX + * Support for hardware-accelerated deflate using IBM Z DFLTCC +* Unaligned memory read/writes and large bit buffer improvements +* Includes improvements from Cloudflare and Intel forks +* Configure, CMake, and NMake build system support +* Comprehensive set of CMake unit tests +* Code sanitizers, fuzzing, and coverage +* GitHub Actions continuous integration on Windows, macOS, and Linux + * Emulated CI for ARM, AARCH64, PPC, PPC64, RISCV, SPARC64, S390x using qemu + + +History +------- + +The motivation for this fork was seeing several 3rd party contributions with new optimizations not getting +implemented into the official zlib repository. + +Mark Adler has been maintaining zlib for a very long time, and he has done a great job and hopefully he will continue +for a long time yet. The idea of zlib-ng is not to replace zlib, but to co-exist as a drop-in replacement with a +lower threshold for code change. + +zlib has a long history and is incredibly portable, even supporting many systems that predate the Internet.
    +That is great, but it can complicate further development and maintainability. The zlib code contains many workarounds +for really old compilers or to accommodate systems with limitations such as operating in a 16-bit environment. + +Many of these workarounds are only maintenance burdens, some of them are pretty huge code-wise. With many workarounds +cluttered throughout the code, it makes it harder for new programmers with an idea/interest for zlib to contribute. + +I decided to make a fork, merge all the Intel optimizations, some of the Cloudflare optimizations, plus a couple other +smaller patches. Then started cleaning out workarounds, various dead code, all contrib and example code.
    +The result is a better performing and easier to maintain zlib-ng. + +A lot of improvements have gone into zlib-ng since its start, and numerous people and companies have contributed both +small and big improvements, or valuable testing. + + +Build +----- +Please read LICENSE.md, it is very simple and very liberal. + +There are two ways to build zlib-ng: + +### Cmake + +To build zlib-ng using the cross-platform makefile generator cmake. + +``` +cmake . +cmake --build . --config Release +ctest --verbose -C Release +``` + +Alternatively, you can use the cmake configuration GUI tool ccmake: + +``` +ccmake . +``` + +### Configure + +To build zlib-ng using the bash configure script: + +``` +./configure +make +make test +``` + +Build Options +------------- + +| CMake | configure | Description | Default | +|:-------------------------|:-------------------------|:--------------------------------------------------------------------------------------|---------| +| ZLIB_COMPAT | --zlib-compat | Compile with zlib compatible API | OFF | +| ZLIB_ENABLE_TESTS | | Build test binaries | ON | +| WITH_GZFILEOP | --without-gzfileops | Compile with support for gzFile related functions | ON | +| WITH_OPTIM | --without-optimizations | Build with optimisations | ON | +| WITH_NEW_STRATEGIES | --without-new-strategies | Use new strategies | ON | +| WITH_NATIVE_INSTRUCTIONS | --native | Compiles with full instruction set supported on this host (gcc/clang -march=native) | OFF | +| WITH_SANITIZER | | Build with sanitizer (memory, address, undefined) | OFF | +| WITH_GTEST | | Build gtest_zlib | ON | +| WITH_FUZZERS | | Build test/fuzz | OFF | +| WITH_BENCHMARKS | | Build test/benchmarks | OFF | +| WITH_MAINTAINER_WARNINGS | | Build with project maintainer warnings | OFF | +| WITH_CODE_COVERAGE | | Enable code coverage reporting | OFF | + + +Install +------- + +WARNING: We do not recommend manually installing unless you really know what you are doing, because this can +potentially override the system default zlib library, and any incompatibility or wrong configuration of zlib-ng +can make the whole system unusable, requiring recovery or reinstall. +If you still want a manual install, we recommend using the /opt/ path prefix. + +For Linux distros, an alternative way to use zlib-ng (if compiled in zlib-compat mode) instead of zlib, is through +the use of the _LD_PRELOAD_ environment variable. If the program is dynamically linked with zlib, then the program +will temporarily attempt to use zlib-ng instead, without risking system-wide instability. + +``` +LD_PRELOAD=/opt/zlib-ng/libz.so.1.2.13.zlib-ng /usr/bin/program +``` + +### Cmake + +To install zlib-ng system-wide using cmake: + +``` +cmake --build . --target install +``` + +### Configure + +To install zlib-ng system-wide using the configure script: + +``` +make install +``` + +### Vcpkg + +Alternatively, you can build and install zlib-ng using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + +```sh or powershell +git clone https://github.com/Microsoft/vcpkg.git +cd vcpkg +./bootstrap-vcpkg.sh # "./bootstrap-vcpkg.bat" for powershell +./vcpkg integrate install +./vcpkg install zlib-ng +``` + +The zlib-ng port in vcpkg is kept up to date by Microsoft team members and community contributors. +If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + +Contributing +------------ + +Zlib-ng is aiming to be open to contributions, and we would be delighted to receive pull requests on github. +Help with testing and reviewing pull requests etc is also very much appreciated. + +Please check the Wiki for more info: [Contributing](https://github.com/zlib-ng/zlib-ng/wiki/Contributing) + +Acknowledgments +---------------- + +Thanks go out to all the people and companies who have taken the time to contribute +code reviews, testing and/or patches. Zlib-ng would not have been nearly as good without you. + +The deflate format used by zlib was defined by Phil Katz.
    +The deflate and zlib specifications were written by L. Peter Deutsch. + +zlib was originally created by Jean-loup Gailly (compression) and Mark Adler (decompression). + + +Advanced Build Options +---------------------- + +| CMake | configure | Description | Default | +|:--------------------------------|:----------------------|:--------------------------------------------------------------------|------------------------| +| FORCE_SSE2 | --force-sse2 | Skip runtime check for SSE2 instructions (Always on for x86_64) | OFF (x86) | +| WITH_AVX2 | | Build with AVX2 intrinsics | ON | +| WITH_AVX512 | | Build with AVX512 intrinsics | ON | +| WITH_AVX512VNNI | | Build with AVX512VNNI intrinsics | ON | +| WITH_SSE2 | | Build with SSE2 intrinsics | ON | +| WITH_SSSE3 | | Build with SSSE3 intrinsics | ON | +| WITH_SSE42 | | Build with SSE42 intrinsics | ON | +| WITH_PCLMULQDQ | | Build with PCLMULQDQ intrinsics | ON | +| WITH_VPCLMULQDQ | --without-vpclmulqdq | Build with VPCLMULQDQ intrinsics | ON | +| WITH_ACLE | --without-acle | Build with ACLE intrinsics | ON | +| WITH_NEON | --without-neon | Build with NEON intrinsics | ON | +| WITH_ALTIVEC | --without-altivec | Build with AltiVec (VMX) intrinsics | ON | +| WITH_POWER8 | --without-power8 | Build with POWER8 optimisations | ON | +| WITH_RVV | | Build with RVV intrinsics | ON | +| WITH_CRC32_VX | --without-crc32-vx | Build with vectorized CRC32 on IBM Z | ON | +| WITH_DFLTCC_DEFLATE | --with-dfltcc-deflate | Build with DFLTCC intrinsics for compression on IBM Z | OFF | +| WITH_DFLTCC_INFLATE | --with-dfltcc-inflate | Build with DFLTCC intrinsics for decompression on IBM Z | OFF | +| WITH_UNALIGNED | --without-unaligned | Allow optimizations that use unaligned reads if safe on current arch| ON | +| WITH_INFLATE_STRICT | | Build with strict inflate distance checking | OFF | +| WITH_INFLATE_ALLOW_INVALID_DIST | | Build with zero fill for inflate invalid distances | OFF | +| INSTALL_UTILS | | Copy minigzip and minideflate during install | OFF | +| ZLIBNG_ENABLE_TESTS | | Test zlib-ng specific API | ON | + + +Related Projects +---------------- + +* Fork of the popular minizip https://github.com/zlib-ng/minizip-ng +* Python tool to benchmark minigzip/minideflate https://github.com/zlib-ng/deflatebench +* Python tool to benchmark pigz https://github.com/zlib-ng/pigzbench +* 3rd party patches for zlib-ng compatibility https://github.com/zlib-ng/patches diff --git a/internal-complibs/zlib-ng-2.1.2/adler32.c b/internal-complibs/zlib-ng-2.1.2/adler32.c new file mode 100644 index 000000000..95ac13c30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/adler32.c @@ -0,0 +1,115 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_p.h" + +/* ========================================================================= */ +Z_INTERNAL uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; +#ifdef UNROLL_MORE + n = NMAX / 16; /* NMAX is divisible by 16 */ +#else + n = NMAX / 8; /* NMAX is divisible by 8 */ +#endif + do { +#ifdef UNROLL_MORE + DO16(adler, sum2, buf); /* 16 sums unrolled */ + buf += 16; +#else + DO8(adler, sum2, buf, 0); /* 8 sums unrolled */ + buf += 8; +#endif + } while (--n); + adler %= BASE; + sum2 %= BASE; + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + return adler32_len_64(adler, buf, len, sum2); +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_z)(unsigned long adler, const unsigned char *buf, size_t len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32_z)(uint32_t adler, const unsigned char *buf, size_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32)(unsigned long adler, const unsigned char *buf, unsigned int len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32)(uint32_t adler, const unsigned char *buf, uint32_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +static uint32_t adler32_combine_(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + uint32_t sum1; + uint32_t sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffff; + + /* the derivation of this formula is left as an exercise for the reader */ + len2 %= BASE; /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + sum2 %= BASE; + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} + +unsigned long Z_EXPORT PREFIX4(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off64_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} +#else +uint32_t Z_EXPORT PREFIX4(adler32_combine)(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/adler32_fold.c b/internal-complibs/zlib-ng-2.1.2/adler32_fold.c new file mode 100644 index 000000000..e2f6f9ac7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/adler32_fold.c @@ -0,0 +1,16 @@ +/* adler32_fold.c -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_fold.h" + +#include + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + adler = functable.adler32(adler, src, len); + memcpy(dst, src, len); + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.2/adler32_fold.h b/internal-complibs/zlib-ng-2.1.2/adler32_fold.h new file mode 100644 index 000000000..20aa1c740 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/adler32_fold.h @@ -0,0 +1,11 @@ +/* adler32_fold.h -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_FOLD_H_ +#define ADLER32_FOLD_H_ + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/adler32_p.h b/internal-complibs/zlib-ng-2.1.2/adler32_p.h new file mode 100644 index 000000000..38ba2ad72 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/adler32_p.h @@ -0,0 +1,70 @@ +/* adler32_p.h -- Private inline functions and macros shared with + * different computation of the Adler-32 checksum + * of a data stream. + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_P_H +#define ADLER32_P_H + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(sum1, sum2, buf, i) {(sum1) += buf[(i)]; (sum2) += (sum1);} +#define DO2(sum1, sum2, buf, i) {DO1(sum1, sum2, buf, i); DO1(sum1, sum2, buf, i+1);} +#define DO4(sum1, sum2, buf, i) {DO2(sum1, sum2, buf, i); DO2(sum1, sum2, buf, i+2);} +#define DO8(sum1, sum2, buf, i) {DO4(sum1, sum2, buf, i); DO4(sum1, sum2, buf, i+4);} +#define DO16(sum1, sum2, buf) {DO8(sum1, sum2, buf, 0); DO8(sum1, sum2, buf, 8);} + +static inline uint32_t adler32_len_1(uint32_t adler, const uint8_t *buf, uint32_t sum2) { + adler += buf[0]; + adler %= BASE; + sum2 += adler; + sum2 %= BASE; + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_16(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { + while (len) { + --len; + adler += *buf++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_copy_len_16(uint32_t adler, const uint8_t *buf, uint8_t *dst, size_t len, uint32_t sum2) { + while (len--) { + *dst = *buf++; + adler += *dst++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_64(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { +#ifdef UNROLL_MORE + while (len >= 16) { + len -= 16; + DO16(adler, sum2, buf); + buf += 16; +#else + while (len >= 8) { + len -= 8; + DO8(adler, sum2, buf, 0); + buf += 8; +#endif + } + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif /* ADLER32_P_H */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/.gitignore b/internal-complibs/zlib-ng-2.1.2/arch/.gitignore new file mode 100644 index 000000000..2c3af0a08 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/.gitignore @@ -0,0 +1,2 @@ +# ignore Makefiles; they're all automatically generated +Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/Makefile.in b/internal-complibs/zlib-ng-2.1.2/arch/arm/Makefile.in new file mode 100644 index 000000000..717754760 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/Makefile.in @@ -0,0 +1,77 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +ACLEFLAG= +NEONFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + adler32_neon.o adler32_neon.lo \ + arm_features.o arm_features.lo \ + chunkset_neon.o chunkset_neon.lo \ + compare256_neon.o compare256_neon.lo \ + crc32_acle.o crc32_acle.lo \ + slide_hash_neon.o slide_hash_neon.lo \ + insert_string_acle.o insert_string_acle.lo + +adler32_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +adler32_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +arm_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +arm_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +chunkset_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +chunkset_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +compare256_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +compare256_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +crc32_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +crc32_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +slide_hash_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +slide_hash_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +insert_string_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +insert_string_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/adler32_neon.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/adler32_neon.c new file mode 100644 index 000000000..f1c43ff04 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/adler32_neon.c @@ -0,0 +1,215 @@ +/* Copyright (C) 1995-2011, 2016 Mark Adler + * Copyright (C) 2017 ARM Holdings Inc. + * Authors: + * Adenilson Cavalcanti + * Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../adler32_p.h" + +static void NEON_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + static const uint16_t ALIGNED_(16) taps[64] = { + 64, 63, 62, 61, 60, 59, 58, 57, + 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1 }; + + uint32x4_t adacc = vdupq_n_u32(0); + uint32x4_t s2acc = vdupq_n_u32(0); + uint32x4_t s2acc_0 = vdupq_n_u32(0); + uint32x4_t s2acc_1 = vdupq_n_u32(0); + uint32x4_t s2acc_2 = vdupq_n_u32(0); + + adacc = vsetq_lane_u32(s[0], adacc, 0); + s2acc = vsetq_lane_u32(s[1], s2acc, 0); + + uint32x4_t s3acc = vdupq_n_u32(0); + uint32x4_t adacc_prev = adacc; + + uint16x8_t s2_0, s2_1, s2_2, s2_3; + s2_0 = s2_1 = s2_2 = s2_3 = vdupq_n_u16(0); + + uint16x8_t s2_4, s2_5, s2_6, s2_7; + s2_4 = s2_5 = s2_6 = s2_7 = vdupq_n_u16(0); + + size_t num_iter = len >> 2; + int rem = len & 3; + + for (size_t i = 0; i < num_iter; ++i) { + uint8x16x4_t d0_d3 = vld1q_u8_x4(buf); + + /* Unfortunately it doesn't look like there's a direct sum 8 bit to 32 + * bit instruction, we'll have to make due summing to 16 bits first */ + uint16x8x2_t hsum, hsum_fold; + hsum.val[0] = vpaddlq_u8(d0_d3.val[0]); + hsum.val[1] = vpaddlq_u8(d0_d3.val[1]); + + hsum_fold.val[0] = vpadalq_u8(hsum.val[0], d0_d3.val[2]); + hsum_fold.val[1] = vpadalq_u8(hsum.val[1], d0_d3.val[3]); + + adacc = vpadalq_u16(adacc, hsum_fold.val[0]); + s3acc = vaddq_u32(s3acc, adacc_prev); + adacc = vpadalq_u16(adacc, hsum_fold.val[1]); + + /* If we do straight widening additions to the 16 bit values, we don't incur + * the usual penalties of a pairwise add. We can defer the multiplications + * until the very end. These will not overflow because we are incurring at + * most 408 loop iterations (NMAX / 64), and a given lane is only going to be + * summed into once. This means for the maximum input size, the largest value + * we will see is 255 * 102 = 26010, safely under uint16 max */ + s2_0 = vaddw_u8(s2_0, vget_low_u8(d0_d3.val[0])); + s2_1 = vaddw_high_u8(s2_1, d0_d3.val[0]); + s2_2 = vaddw_u8(s2_2, vget_low_u8(d0_d3.val[1])); + s2_3 = vaddw_high_u8(s2_3, d0_d3.val[1]); + s2_4 = vaddw_u8(s2_4, vget_low_u8(d0_d3.val[2])); + s2_5 = vaddw_high_u8(s2_5, d0_d3.val[2]); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0_d3.val[3])); + s2_7 = vaddw_high_u8(s2_7, d0_d3.val[3]); + + adacc_prev = adacc; + buf += 64; + } + + s3acc = vshlq_n_u32(s3acc, 6); + + if (rem) { + uint32x4_t s3acc_0 = vdupq_n_u32(0); + while (rem--) { + uint8x16_t d0 = vld1q_u8(buf); + uint16x8_t adler; + adler = vpaddlq_u8(d0); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0)); + s2_7 = vaddw_high_u8(s2_7, d0); + adacc = vpadalq_u16(adacc, adler); + s3acc_0 = vaddq_u32(s3acc_0, adacc_prev); + adacc_prev = adacc; + buf += 16; + } + + s3acc_0 = vshlq_n_u32(s3acc_0, 4); + s3acc = vaddq_u32(s3acc_0, s3acc); + } + + uint16x8x4_t t0_t3 = vld1q_u16_x4(taps); + uint16x8x4_t t4_t7 = vld1q_u16_x4(taps + 32); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[0], s2_0); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[0]), vget_low_u16(s2_0)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[1], s2_1); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[1]), vget_low_u16(s2_1)); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[2], s2_2); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[2]), vget_low_u16(s2_2)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[3], s2_3); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[3]), vget_low_u16(s2_3)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[0], s2_4); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[0]), vget_low_u16(s2_4)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[1], s2_5); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[1]), vget_low_u16(s2_5)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[2], s2_6); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[2]), vget_low_u16(s2_6)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[3], s2_7); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[3]), vget_low_u16(s2_7)); + + s2acc = vaddq_u32(s2acc_0, s2acc); + s2acc_2 = vaddq_u32(s2acc_1, s2acc_2); + s2acc = vaddq_u32(s2acc, s2acc_2); + + uint32x2_t adacc2, s2acc2, as; + s2acc = vaddq_u32(s2acc, s3acc); + adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc)); + s2acc2 = vpadd_u32(vget_low_u32(s2acc), vget_high_u32(s2acc)); + as = vpadd_u32(adacc2, s2acc2); + s[0] = vget_lane_u32(as, 0); + s[1] = vget_lane_u32(as, 1); +} + +static void NEON_handle_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +Z_INTERNAL uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len) { + /* split Adler-32 into component sums */ + uint32_t sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) + return adler32_len_16(adler, buf, len, sum2); + + uint32_t pair[2]; + int n = NMAX; + unsigned int done = 0; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + pair[0] = adler; + pair[1] = sum2; + + /* If memory is not SIMD aligned, do scalar sums to an aligned + * offset, provided that doing so doesn't completely eliminate + * SIMD operation. Aligned loads are still faster on ARM, even + * though there's no explicit aligned load instruction */ + unsigned int align_offset = ((uintptr_t)buf & 15); + unsigned int align_adj = (align_offset) ? 16 - align_offset : 0; + + if (align_offset && len >= (16 + align_adj)) { + NEON_handle_tail(pair, buf, align_adj); + n -= align_adj; + done += align_adj; + + } else { + /* If here, we failed the len criteria test, it wouldn't be + * worthwhile to do scalar aligning sums */ + align_adj = 0; + } + + while (done < len) { + int remaining = (int)(len - done); + n = MIN(remaining, (done == align_adj) ? n : NMAX); + + if (n < 16) + break; + + NEON_accum32(pair, buf + done, n >> 4); + pair[0] %= BASE; + pair[1] %= BASE; + + int actual_nsums = (n >> 4) << 4; + done += actual_nsums; + } + + /* Handle the tail elements. */ + if (done < len) { + NEON_handle_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.c new file mode 100644 index 000000000..7394351fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.c @@ -0,0 +1,82 @@ +#include "../../zbuild.h" +#include "arm_features.h" + +#if defined(__linux__) && defined(HAVE_SYS_AUXV_H) +# include +# ifdef ARM_ASM_HWCAP +# include +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) +# include +# ifndef ID_AA64ISAR0_CRC32_VAL +# define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32 +# endif +#elif defined(__APPLE__) +# if !defined(_DARWIN_C_SOURCE) +# define _DARWIN_C_SOURCE /* enable types aliases (eg u_int) */ +# endif +# include +#elif defined(_WIN32) +# include +#endif + +static int arm_has_crc32() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_CRC32) +# ifdef HWCAP_CRC32 + return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) + return getenv("QEMU_EMULATING") == NULL + && ID_AA64ISAR0_CRC32_VAL(READ_SPECIALREG(id_aa64isar0_el1)) >= ID_AA64ISAR0_CRC32_BASE; +#elif defined(__APPLE__) + int hascrc32; + size_t size = sizeof(hascrc32); + return sysctlbyname("hw.optional.armv8_crc32", &hascrc32, &size, NULL, 0) == 0 + && hascrc32 == 1; +#elif defined(_WIN32) + return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); +#elif defined(ARM_NOCHECK_ACLE) + return 1; +#else + return 0; +#endif +} + +/* AArch64 has neon. */ +#if !defined(__aarch64__) && !defined(_M_ARM64) +static inline int arm_has_neon() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) +# ifdef HWCAP_ARM_NEON + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# endif +#elif defined(__APPLE__) + int hasneon; + size_t size = sizeof(hasneon); + return sysctlbyname("hw.optional.neon", &hasneon, &size, NULL, 0) == 0 + && hasneon == 1; +#elif defined(_M_ARM) && defined(WINAPI_FAMILY_PARTITION) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + return 1; /* Always supported */ +# endif +#endif + +#if defined(ARM_NOCHECK_NEON) + return 1; +#else + return 0; +#endif +} +#endif + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features) { +#if defined(__aarch64__) || defined(_M_ARM64) + features->has_neon = 1; /* always available */ +#else + features->has_neon = arm_has_neon(); +#endif + features->has_crc32 = arm_has_crc32(); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.h b/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.h new file mode 100644 index 000000000..6fcd8d3eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/arm_features.h @@ -0,0 +1,15 @@ +/* arm_features.h -- check for ARM features. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ARM_H_ +#define ARM_H_ + +struct arm_cpu_features { + int has_neon; + int has_crc32; +}; + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features); + +#endif /* ARM_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/chunkset_neon.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/chunkset_neon.c new file mode 100644 index 000000000..1890c9135 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/chunkset_neon.c @@ -0,0 +1,101 @@ +/* chunkset_neon.c -- NEON inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../generic/chunk_permute_table.h" + +typedef uint8x16_t chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u16(vdupq_n_u16(tmp)); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u32(vdupq_n_u32(tmp)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u64(vdupq_n_u64(tmp)); +} + +#define CHUNKSIZE chunksize_neon +#define CHUNKCOPY chunkcopy_neon +#define CHUNKUNROLL chunkunroll_neon +#define CHUNKMEMSET chunkmemset_neon +#define CHUNKMEMSET_SAFE chunkmemset_safe_neon + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vld1q_u8(s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vst1q_u8(out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + + /* This version of table is only available on aarch64 */ +#if defined(_M_ARM64) || defined(__aarch64__) + uint8x16_t ret_vec = vld1q_u8(buf); + + uint8x16_t perm_vec = vld1q_u8(permute_table + lut_rem.idx); + return vqtbl1q_u8(ret_vec, perm_vec); +#else + uint8x8_t ret0, ret1, a, b, perm_vec0, perm_vec1; + perm_vec0 = vld1_u8(permute_table + lut_rem.idx); + perm_vec1 = vld1_u8(permute_table + lut_rem.idx + 8); + a = vld1_u8(buf); + b = vld1_u8(buf + 8); + ret0 = vtbl1_u8(a, perm_vec0); + uint8x8x2_t ab = {{a, b}}; + ret1 = vtbl2_u8(ab, perm_vec1); + return vcombine_u8(ret0, ret1); +#endif +} + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_neon + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/compare256_neon.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/compare256_neon.c new file mode 100644 index 000000000..7daeba411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/compare256_neon.c @@ -0,0 +1,59 @@ +/* compare256_neon.c - NEON version of compare256 + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +#include "neon_intrins.h" + +static inline uint32_t compare256_neon_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint8x16_t a, b, cmp; + uint64_t lane; + + a = vld1q_u8(src0); + b = vld1q_u8(src1); + + cmp = veorq_u8(a, b); + + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 0); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 1); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + + src0 += 16, src1 += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1) { + return compare256_neon_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/crc32_acle.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/crc32_acle.c new file mode 100644 index 000000000..a4e54d718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/crc32_acle.c @@ -0,0 +1,98 @@ +/* crc32_acle.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2016 Yang Zhang + * For conditions of distribution and use, see copyright notice in zlib.h + * +*/ + +#ifdef ARM_ACLE +#ifdef _MSC_VER +# include +#else +# include +#endif +#include "../../zbuild.h" + +Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + Z_REGISTER const uint16_t *buf2; + Z_REGISTER const uint32_t *buf4; + + c = ~crc; + if (len && ((ptrdiff_t)buf & 1)) { + c = __crc32b(c, *buf++); + len--; + } + + if ((len >= sizeof(uint16_t)) && ((ptrdiff_t)buf & sizeof(uint16_t))) { + buf2 = (const uint16_t *) buf; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf4 = (const uint32_t *) buf2; + } else { + buf4 = (const uint32_t *) buf; + } + +#if defined(__aarch64__) || defined(_M_ARM64) + if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len == 0) { + c = ~c; + return c; + } + + const uint64_t *buf8 = (const uint64_t *) buf4; + + while (len >= sizeof(uint64_t)) { + c = __crc32d(c, *buf8++); + len -= sizeof(uint64_t); + } + + if (len >= sizeof(uint32_t)) { + buf4 = (const uint32_t *) buf8; + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + buf2 = (const uint16_t *) buf4; + } else { + buf2 = (const uint16_t *) buf8; + } + + if (len >= sizeof(uint16_t)) { + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + } + + buf = (const unsigned char *) buf2; +#else /* __aarch64__ */ + + if (len == 0) { + c = ~c; + return c; + } + + while (len >= sizeof(uint32_t)) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len >= sizeof(uint16_t)) { + buf2 = (const uint16_t *) buf4; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf = (const unsigned char *) buf2; + } else { + buf = (const unsigned char *) buf4; + } +#endif /* __aarch64__ */ + + if (len) { + c = __crc32b(c, *buf); + } + + c = ~c; + return c; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/insert_string_acle.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/insert_string_acle.c new file mode 100644 index 000000000..9ac3ccb42 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/insert_string_acle.c @@ -0,0 +1,26 @@ +/* insert_string_acle.c -- insert_string integer hash variant using ACLE's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifdef ARM_ACLE +#ifndef _MSC_VER +# include +#endif +#include "../../zbuild.h" +#include "../../deflate.h" + +#define HASH_CALC(s, h, val) \ + h = __crc32w(0, val) + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_acle +#define INSERT_STRING insert_string_acle +#define QUICK_INSERT_STRING quick_insert_string_acle + +#include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/neon_intrins.h b/internal-complibs/zlib-ng-2.1.2/arch/arm/neon_intrins.h new file mode 100644 index 000000000..d6b57f641 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/neon_intrins.h @@ -0,0 +1,57 @@ +#ifndef ARM_NEON_INTRINS_H +#define ARM_NEON_INTRINS_H + +#ifdef _M_ARM64 +# include +#else +# include +#endif + +#if defined(ARM_NEON) && !defined(__aarch64__) && !defined(_M_ARM64) +/* Compatibility shim for the _high family of functions */ +#define vmull_high_u8(a, b) vmull_u8(vget_high_u8(a), vget_high_u8(b)) +#define vmlal_high_u8(a, b, c) vmlal_u8(a, vget_high_u8(b), vget_high_u8(c)) +#define vmlal_high_u16(a, b, c) vmlal_u16(a, vget_high_u16(b), vget_high_u16(c)) +#define vaddw_high_u8(a, b) vaddw_u8(a, vget_high_u8(b)) +#endif + +#ifdef ARM_NEON + +#define vqsubq_u16_x4_x1(out, a, b) do { \ + out.val[0] = vqsubq_u16(a.val[0], b); \ + out.val[1] = vqsubq_u16(a.val[1], b); \ + out.val[2] = vqsubq_u16(a.val[2], b); \ + out.val[3] = vqsubq_u16(a.val[3], b); \ +} while (0) + + +# ifndef ARM_NEON_HASLD4 + +static inline uint16x8x4_t vld1q_u16_x4(uint16_t const *a) { + uint16x8x4_t ret = (uint16x8x4_t) {{ + vld1q_u16(a), + vld1q_u16(a+8), + vld1q_u16(a+16), + vld1q_u16(a+24)}}; + return ret; +} + +static inline uint8x16x4_t vld1q_u8_x4(uint8_t const *a) { + uint8x16x4_t ret = (uint8x16x4_t) {{ + vld1q_u8(a), + vld1q_u8(a+16), + vld1q_u8(a+32), + vld1q_u8(a+48)}}; + return ret; +} + +static inline void vst1q_u16_x4(uint16_t *p, uint16x8x4_t a) { + vst1q_u16(p, a.val[0]); + vst1q_u16(p + 8, a.val[1]); + vst1q_u16(p + 16, a.val[2]); + vst1q_u16(p + 24, a.val[3]); +} +# endif // HASLD4 check +#endif + +#endif // include guard ARM_NEON_INTRINS_H diff --git a/internal-complibs/zlib-ng-2.1.2/arch/arm/slide_hash_neon.c b/internal-complibs/zlib-ng-2.1.2/arch/arm/slide_hash_neon.c new file mode 100644 index 000000000..a96ca1179 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/arm/slide_hash_neon.c @@ -0,0 +1,46 @@ +/* slide_hash_neon.c -- Optimized hash table shifting for ARM with support for NEON instructions + * Copyright (C) 2017-2020 Mika T. Lindqvist + * + * Authors: + * Mika T. Lindqvist + * Jun He + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../deflate.h" + +/* SIMD version of hash_chain rebase */ +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + Z_REGISTER uint16x8_t v; + uint16x8x4_t p0, p1; + Z_REGISTER size_t n; + + size_t size = entries*sizeof(table[0]); + Assert((size % sizeof(uint16x8_t) * 8 == 0), "hash table size err"); + + Assert(sizeof(Pos) == 2, "Wrong Pos size"); + v = vdupq_n_u16(wsize); + + n = size / (sizeof(uint16x8_t) * 8); + do { + p0 = vld1q_u16_x4(table); + p1 = vld1q_u16_x4(table+32); + vqsubq_u16_x4_x1(p0, p0, v); + vqsubq_u16_x4_x1(p1, p1, v); + vst1q_u16_x4(table, p0); + vst1q_u16_x4(table+32, p1); + table += 64; + } while (--n); +} + +Z_INTERNAL void slide_hash_neon(deflate_state *s) { + unsigned int wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/generic/Makefile.in b/internal-complibs/zlib-ng-2.1.2/arch/generic/Makefile.in new file mode 100644 index 000000000..c717026f8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/generic/Makefile.in @@ -0,0 +1,24 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: + + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/generic/chunk_permute_table.h b/internal-complibs/zlib-ng-2.1.2/arch/generic/chunk_permute_table.h new file mode 100644 index 000000000..bad66ccc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/generic/chunk_permute_table.h @@ -0,0 +1,53 @@ +/* chunk_permute_table.h - shared AVX/SSSE3 permutation table for use with chunkmemset family of functions. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CHUNK_PERMUTE_TABLE_H_ +#define CHUNK_PERMUTE_TABLE_H_ + +#include "zbuild.h" + +/* Need entries for all numbers not an even modulus for 1, 2, 4, 8, 16 & 32 */ +static const ALIGNED_(32) uint8_t permute_table[26*32] = { + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, /* dist 3 */ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, /* dist 5 */ + 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, /* dist 6 */ + 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, /* dist 7 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, /* dist 9 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, /* dist 10 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 11 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 12 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, /* dist 13 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, /* dist 14 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, /* dist 15 */ + + /* Beyond dists of 15 means we have to permute from a vector > len(m128i). Because AVX couldn't permute + * beyond 128 bit lanes until AVX512 for sub 4-byte sequences, we have to do some math here for an eventual + * blend with a comparison. That means we need to wrap the indices with yet another derived table. For simplicity, + * we'll use absolute indexing here to derive a blend vector. This is actually a lot simpler with ARM's TBL, but, + * this is what we're dealt. + */ + + 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* dist 17 */ + 16, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, /* dist 18 */ + 16, 17, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, /* dist 19 */ + 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* dist 20 */ + 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, /* dist 21 */ + 16, 17, 18, 19, 20, 21, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 22 */ + 16, 17, 18, 19, 20, 21, 22, 0, 1, 2, 3, 4, 5, 6, 7, 8, /* dist 23 */ + 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 24 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4, 5, 6, /* dist 25 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 1, 2, 3, 4, 5, /* dist 26 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 1, 2, 3, 4, /* dist 27 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3, /* dist 28 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, 1, 2, /* dist 29 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 1, /* dist 30 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, /* dist 31 */ +}; + +typedef struct lut_rem_pair_s { + uint16_t idx; + uint16_t remval; +} lut_rem_pair; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/Makefile.in b/internal-complibs/zlib-ng-2.1.2/arch/power/Makefile.in new file mode 100644 index 000000000..e2bec5e51 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/Makefile.in @@ -0,0 +1,93 @@ +# Makefile for POWER-specific files +# Copyright (C) 2020 Matheus Castanho , IBM +# Copyright (C) 2021 Mika T. Lindqvist +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +P8FLAGS=-mcpu=power8 +P9FLAGS=-mcpu=power9 +PPCFLAGS=-maltivec +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: power_features.o \ + power_features.lo \ + adler32_power8.o \ + adler32_power8.lo \ + adler32_vmx.o \ + adler32_vmx.lo \ + chunkset_power8.o \ + chunkset_power8.lo \ + compare256_power9.o \ + compare256_power9.lo \ + crc32_power8.o \ + crc32_power8.lo \ + slide_hash_power8.o \ + slide_hash_power8.lo \ + slide_hash_vmx.o \ + slide_hash_vmx.lo + +power_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +power_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +adler32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_vmx.o: + $(CC) $(CFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +adler32_vmx.lo: + $(CC) $(SFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +chunkset_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +chunkset_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +compare256_power9.o: + $(CC) $(CFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +compare256_power9.lo: + $(CC) $(SFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +crc32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +crc32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +slide_hash_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_vmx.o: + $(CC) $(CFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +slide_hash_vmx.lo: + $(CC) $(SFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_power8.c b/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_power8.c new file mode 100644 index 000000000..4aaea9f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_power8.c @@ -0,0 +1,153 @@ +/* Adler32 for POWER8 using VSX instructions. + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate adler32 checksum for 16 bytes at once using POWER8+ VSX (vector) + * instructions. + * + * If adler32 do 1 byte at time on the first iteration s1 is s1_0 (_n means + * iteration n) is the initial value of adler - at start _0 is 1 unless + * adler initial value is different than 1. So s1_1 = s1_0 + c[0] after + * the first calculation. For the iteration s1_2 = s1_1 + c[1] and so on. + * Hence, for iteration N, s1_N = s1_(N-1) + c[N] is the value of s1 on + * after iteration N. + * + * Therefore, for s2 and iteration N, s2_N = s2_0 + N*s1_N + N*c[0] + + * N-1*c[1] + ... + c[N] + * + * In a more general way: + * + * s1_N = s1_0 + sum(i=1 to N)c[i] + * s2_N = s2_0 + N*s1 + sum (i=1 to N)(N-i+1)*c[i] + * + * Where s1_N, s2_N are the values for s1, s2 after N iterations. So if we + * can process N-bit at time we can do this at once. + * + * Since VSX can support 16-bit vector instructions, we can process + * 16-bit at time using N = 16 we have: + * + * s1 = s1_16 = s1_(16-1) + c[16] = s1_0 + sum(i=1 to 16)c[i] + * s2 = s2_16 = s2_0 + 16*s1 + sum(i=1 to 16)(16-i+1)*c[i] + * + * After the first iteration we calculate the adler32 checksum for 16 bytes. + * + * For more background about adler32 please check the RFC: + * https://www.ietf.org/rfc/rfc1950.txt + */ + +#ifdef POWER8_VSX + +#include +#include "zbuild.h" +#include "adler32_p.h" + +/* Vector across sum unsigned int (saturate). */ +static inline vector unsigned int vec_sumsu(vector unsigned int __a, vector unsigned int __b) { + __b = vec_sld(__a, __a, 8); + __b = vec_add(__b, __a); + __a = vec_sld(__b, __b, 4); + __a = vec_add(__a, __b); + + return __a; +} + +Z_INTERNAL uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(s1, buf, s2); + + /* If buffer is empty or len=0 we need to return adler initial value. */ + if (UNLIKELY(buf == NULL)) + return 1; + + /* This is faster than VSX code for len < 64. */ + if (len < 64) + return adler32_len_64(s1, buf, len, s2); + + /* Use POWER VSX instructions for len >= 64. */ + const vector unsigned int v_zeros = { 0 }; + const vector unsigned char v_mul = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, + 6, 5, 4, 3, 2, 1}; + const vector unsigned char vsh = vec_splat_u8(4); + const vector unsigned int vmask = {0xffffffff, 0x0, 0x0, 0x0}; + vector unsigned int vs1 = { 0 }; + vector unsigned int vs2 = { 0 }; + vector unsigned int vs1_save = { 0 }; + vector unsigned int vsum1, vsum2; + vector unsigned char vbuf; + int n; + + vs1[0] = s1; + vs2[0] = s2; + + /* Do length bigger than NMAX in blocks of NMAX size. */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; + do { + vbuf = vec_xl(0, (unsigned char *) buf); + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } while (--n); + /* Once each block of NMAX size. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + + /* vs1[0] = (s1_i + sum(i=1 to 16)buf[i]) mod 65521. */ + vs1[0] = vs1[0] % BASE; + /* vs2[0] = s2_i + 16*s1_save + + sum(i=1 to 16)(16-i+1)*buf[i] mod 65521. */ + vs2[0] = vs2[0] % BASE; + + vs1 = vec_and(vs1, vmask); + vs2 = vec_and(vs2, vmask); + vs1_save = v_zeros; + } + + /* len is less than NMAX one modulo is needed. */ + if (len >= 16) { + while (len >= 16) { + len -= 16; + + vbuf = vec_xl(0, (unsigned char *) buf); + + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } + /* Since the size will be always less than NMAX we do this once. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + } + /* Copy result back to s1, s2 (mod 65521). */ + s1 = vs1[0] % BASE; + s2 = vs2[0] % BASE; + + /* Process tail (len < 16). */ + return adler32_len_16(s1, buf, len, s2); +} + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_vmx.c b/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_vmx.c new file mode 100644 index 000000000..ef1649b58 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/adler32_vmx.c @@ -0,0 +1,181 @@ +/* adler32_vmx.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 2017-2021 Mika T. Lindqvist + * Copyright (C) 2021 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef PPC_VMX +#include +#include "zbuild.h" +#include "adler32_p.h" + +#define vmx_zero() (vec_splat_u32(0)) + +static inline void vmx_handle_head_or_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +static void vmx_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + /* Different taps for the separable components of sums */ + const vector unsigned char t0 = {64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49}; + const vector unsigned char t1 = {48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33}; + const vector unsigned char t2 = {32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17}; + const vector unsigned char t3 = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + /* As silly and inefficient as it seems, creating 1 permutation vector to permute + * a 2 element vector from a single load + a subsequent shift is just barely faster + * than doing 2 indexed insertions into zero initialized vectors from unaligned memory. */ + const vector unsigned char s0_perm = {0, 1, 2, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + const vector unsigned char shift_vec = vec_sl(vec_splat_u8(8), vec_splat_u8(2)); + vector unsigned int adacc, s2acc; + vector unsigned int pair_vec = vec_ld(0, s); + adacc = vec_perm(pair_vec, pair_vec, s0_perm); + s2acc = vec_slo(pair_vec, shift_vec); + + vector unsigned int zero = vmx_zero(); + vector unsigned int s3acc = zero; + vector unsigned int s3acc_0 = zero; + vector unsigned int adacc_prev = adacc; + vector unsigned int adacc_prev_0 = zero; + + vector unsigned int s2acc_0 = zero; + vector unsigned int s2acc_1 = zero; + vector unsigned int s2acc_2 = zero; + + /* Maintain a running sum of a second half, this might help use break yet another + * data dependency bubble in the sum */ + vector unsigned int adacc_0 = zero; + + int num_iter = len / 4; + int rem = len & 3; + + for (int i = 0; i < num_iter; ++i) { + vector unsigned char d0 = vec_ld(0, buf); + vector unsigned char d1 = vec_ld(16, buf); + vector unsigned char d2 = vec_ld(32, buf); + vector unsigned char d3 = vec_ld(48, buf); + + /* The core operation of the loop, basically + * what is being unrolled below */ + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s3acc_0 = vec_add(s3acc_0, adacc_prev_0); + s2acc = vec_msum(t0, d0, s2acc); + + /* interleave dependent sums in here */ + adacc_0 = vec_sum4s(d1, adacc_0); + s2acc_0 = vec_msum(t1, d1, s2acc_0); + adacc = vec_sum4s(d2, adacc); + s2acc_1 = vec_msum(t2, d2, s2acc_1); + s2acc_2 = vec_msum(t3, d3, s2acc_2); + adacc_0 = vec_sum4s(d3, adacc_0); + + adacc_prev = adacc; + adacc_prev_0 = adacc_0; + buf += 64; + } + + adacc = vec_add(adacc, adacc_0); + s3acc = vec_add(s3acc, s3acc_0); + s3acc = vec_sl(s3acc, vec_splat_u32(6)); + + if (rem) { + adacc_prev = vec_add(adacc_prev_0, adacc_prev); + adacc_prev = vec_sl(adacc_prev, vec_splat_u32(4)); + while (rem--) { + vector unsigned char d0 = vec_ld(0, buf); + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s2acc = vec_msum(t3, d0, s2acc); + adacc_prev = vec_sl(adacc, vec_splat_u32(4)); + buf += 16; + } + } + + + /* Sum up independent second sums */ + s2acc = vec_add(s2acc, s2acc_0); + s2acc_2 = vec_add(s2acc_1, s2acc_2); + s2acc = vec_add(s2acc, s2acc_2); + + s2acc = vec_add(s2acc, s3acc); + + adacc = vec_add(adacc, vec_sld(adacc, adacc, 8)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 8)); + adacc = vec_add(adacc, vec_sld(adacc, adacc, 4)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 4)); + + vec_ste(adacc, 0, s); + vec_ste(s2acc, 0, s+1); +} + +Z_INTERNAL uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + uint32_t pair[16] ALIGNED_(16); + memset(&pair[2], 0, 14); + int n = NMAX; + unsigned int done = 0, i; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + pair[0] = adler; + pair[1] = sum2; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + // Align buffer + unsigned int al = 0; + if ((uintptr_t)buf & 0xf) { + al = 16-((uintptr_t)buf & 0xf); + if (al > len) { + al=len; + } + vmx_handle_head_or_tail(pair, buf, al); + + done += al; + /* Rather than rebasing, we can reduce the max sums for the + * first round only */ + n -= al; + } + for (i = al; i < len; i += n) { + int remaining = (int)(len-i); + n = MIN(remaining, (i == al) ? n : NMAX); + + if (n < 16) + break; + + vmx_accum32(pair, buf + i, n / 16); + pair[0] %= BASE; + pair[1] %= BASE; + + done += (n / 16) * 16; + } + + /* Handle the tail elements. */ + if (done < len) { + vmx_handle_head_or_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/chunkset_power8.c b/internal-complibs/zlib-ng-2.1.2/arch/power/chunkset_power8.c new file mode 100644 index 000000000..443aae92f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/chunkset_power8.c @@ -0,0 +1,55 @@ +/* chunkset_power8.c -- VSX inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX +#include +#include "../../zbuild.h" + +typedef vector unsigned char chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vec_xl(0, s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vec_xst(*chunk, 0, out); +} + +#define CHUNKSIZE chunksize_power8 +#define CHUNKCOPY chunkcopy_power8 +#define CHUNKUNROLL chunkunroll_power8 +#define CHUNKMEMSET chunkmemset_power8 +#define CHUNKMEMSET_SAFE chunkmemset_safe_power8 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_power8 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/compare256_power9.c b/internal-complibs/zlib-ng-2.1.2/arch/power/compare256_power9.c new file mode 100644 index 000000000..9b3e61701 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/compare256_power9.c @@ -0,0 +1,66 @@ +/* compare256_power9.c - Power9 version of compare256 + * Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER9 +#include +#include "../../zbuild.h" +#include "../../zendian.h" + +/* Older versions of GCC misimplemented semantics for these bit counting builtins. + * https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=3f30f2d1dbb3228b8468b26239fe60c2974ce2ac */ +#if defined(__GNUC__) && (__GNUC__ < 12) +# define zng_vec_vctzlsbb(vc, len) __asm__ volatile("vctzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +# define zng_vec_vclzlsbb(vc, len) __asm__ volatile("vclzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +#else +# define zng_vec_vctzlsbb(vc, len) len = __builtin_vec_vctzlsbb(vc) +# define zng_vec_vclzlsbb(vc, len) len = __builtin_vec_vclzlsbb(vc) +#endif + +static inline uint32_t compare256_power9_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0, cmplen; + + do { + vector unsigned char vsrc0, vsrc1, vc; + + vsrc0 = *((vector unsigned char *)src0); + vsrc1 = *((vector unsigned char *)src1); + + /* Compare 16 bytes at a time. Each byte of vc will be either + * all ones or all zeroes, depending on the result of the comparison. */ + vc = (vector unsigned char)vec_cmpne(vsrc0, vsrc1); + + /* Since the index of matching bytes will contain only zeroes + * on vc (since we used cmpne), counting the number of consecutive + * bytes where LSB == 0 is the same as counting the length of the match. */ +#if BYTE_ORDER == LITTLE_ENDIAN + zng_vec_vctzlsbb(vc, cmplen); +#else + zng_vec_vclzlsbb(vc, cmplen); +#endif + if (cmplen != 16) + return len + cmplen; + + src0 += 16, src1 += 16, len += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1) { + return compare256_power9_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_constants.h b/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_constants.h new file mode 100644 index 000000000..8c8f2153b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_constants.h @@ -0,0 +1,1123 @@ +/* Constants table used by crc32_power8.c + * Copyright (C) 2021 IBM Corporation + * + * This file was automatically generated, DO NOT EDIT IT MANUALLY. + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zendian.h" +#include "zbuild.h" + +/* Reduce 262144 kbits to 1024 bits */ +static const __vector unsigned long long vcrc_const[255] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x0000000099ea94a8, 0x00000001651797d2 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x00000000945a8420, 0x0000000021e0d56c }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x0000000030762706, 0x000000000f95ecaa }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001a52fc582, 0x00000001ebd224ac }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x00000001a4a7167a, 0x000000000ccb97ca }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x000000000c18249a, 0x00000001006ec8a8 }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x00000000a924ae7c, 0x000000014f58f196 }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001e12ccc12, 0x00000001a7192ca6 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x00000000a0b9d4ac, 0x000000019a64bab2 }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000095e8ddfe, 0x0000000014f4ed2e }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x00000000233fddc4, 0x000000011092b6a2 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000001b4529b62, 0x00000000c8a1629c }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x00000001a7fa0e64, 0x000000017bf32e8e }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001b5334592, 0x00000001f8cc6582 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000011f8ee1b4, 0x000000008631ddf0 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000006252e632, 0x000000007e5a76d0 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x00000000ab973e84, 0x000000002b09b31c }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x000000007734f5ec, 0x00000001b2df1f84 }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x000000007c547798, 0x00000001d6f56afc }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x000000007ec40210, 0x00000001b9b5e70c }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x00000001ab1695a8, 0x0000000034b626d2 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x0000000090494bba, 0x000000014c53479a }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001123fb816, 0x00000001a6d179a4 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x00000001e188c74c, 0x000000015abd16b4 }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000001c2d3451c, 0x00000000018f9852 }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x00000000f55cf1ca, 0x000000001fb3084a }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000001a0531540, 0x00000000c53dfb04 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x0000000132cd7ebc, 0x00000000e10c9ad6 }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000073ab7f36, 0x0000000025aa994a }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x0000000041aed1c2, 0x00000000fa3a74c4 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000136c53800, 0x0000000033eb3f40 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x0000000126835a30, 0x000000017193f296 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x000000006241b502, 0x0000000043f6c86a }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x00000000d5196ad4, 0x000000016b513ec6 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x000000009cfa769a, 0x00000000c8f25b4e }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000000920e5df4, 0x00000001a45048ec }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x0000000169dc310e, 0x000000000c441004 }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x0000000009fc331c, 0x000000000e17cad6 }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x000000010d94a81e, 0x00000001253ae964 }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x0000000027a20ab2, 0x00000001d7c88ebc }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x0000000114f87504, 0x00000001e7ca913a }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x000000004b076d96, 0x0000000033ed078a }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000da4d1e74, 0x00000000e1839c78 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x000000001b81f672, 0x00000001322b267e }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x000000009367c988, 0x00000000638231b6 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001717214ca, 0x00000001ee7f16f4 }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x000000009f47d820, 0x0000000117d9924a }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x000000010d9a47d2, 0x00000000e1a9e0c4 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000000a696c58c, 0x00000001403731dc }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x000000002aa28ec6, 0x00000001a5ea9682 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x00000001fe18fd9a, 0x0000000101c5c578 }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x000000019d4fc1ae, 0x00000000dddf6494 }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000001ba0e3dea, 0x00000000f1c3db28 }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x0000000074b59a5e, 0x000000013112fb9c }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000f2b5ea98, 0x00000000b680b906 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x0000000187132676, 0x000000001a282932 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x000000010a8c6ad4, 0x0000000089406e7e }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001e21dfe70, 0x00000001def6be8c }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x00000001da0050e4, 0x0000000075258728 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x00000000772172ae, 0x000000019536090a }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000e47724aa, 0x00000000f2455bfc }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000003cd63ac4, 0x000000018c40baf4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x00000001bf47d352, 0x000000004cd390d4 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x000000018dc1d708, 0x00000001e4ece95a }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000002d4620a4, 0x000000001a3ee918 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x0000000058fd1740, 0x000000007c652fb8 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x00000000dadd9bfc, 0x000000011c67842c }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000001ea2140be, 0x00000000254f759c }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000009de128ba, 0x000000007ece94ca }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x000000013ac3aa8e, 0x0000000038f258c2 }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x0000000099980562, 0x00000001cdf17b00 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x00000001c1579c86, 0x000000011f882c16 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000068dbbf94, 0x0000000100093fc8 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x000000004509fb04, 0x00000001cd684f16 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x00000001202f6398, 0x000000004bc6a70a }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000013aea243e, 0x000000004fc7e8e4 }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x00000001b4052ae6, 0x0000000130103f1c }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x00000001cd2a0ae8, 0x0000000111b0024c }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x00000001fe4aa8b4, 0x000000010b3079da }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x00000001d1559a42, 0x000000010192bcc2 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x00000001f3e05ecc, 0x0000000074838d50 }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x0000000104ddd2cc, 0x000000001b20f520 }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x000000015393153c, 0x0000000050c3590a }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x0000000057e942c6, 0x00000000b41cac8e }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000012c633850, 0x000000000c72cc78 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x00000000ebcaae4c, 0x0000000030cdb032 }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013ee532a6, 0x000000013e09fc32 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x00000001bf0cbc7e, 0x000000001ed624d2 }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000d50b7a5a, 0x00000000781aee1a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x0000000002fca6e8, 0x00000001c4d8348c }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x000000007af40044, 0x0000000057a40336 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000016178744, 0x0000000085544940 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000014c177458, 0x000000019cd21e80 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000011b6ddf04, 0x000000013eb95bc0 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001f3e29ccc, 0x00000001dfc9fdfc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x0000000135ae7562, 0x00000000cd028bc2 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000190ef812c, 0x0000000090db8c44 }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x0000000067a2c786, 0x000000010010a4ce }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x0000000048b9496c, 0x00000001c8f4c72c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000015a422de6, 0x000000001c26170c }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000001ef0e3640, 0x00000000e3fccf68 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000001006d2d26, 0x00000000d513ed24 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000001170d56d6, 0x00000000141beada }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x00000000a5fb613c, 0x000000011071aea0 }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x0000000040bbf7fc, 0x000000012e19080a }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x000000016ac3a5b2, 0x0000000100ecf826 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x00000000abf16230, 0x0000000069b09412 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x00000001ebe23fac, 0x0000000122297bac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x000000008b6a0894, 0x00000000e9e4b068 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x00000001288ea478, 0x000000004b38651a }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x000000016619c442, 0x00000001468360e2 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x0000000086230038, 0x00000000121c2408 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x000000017746a756, 0x00000000da7e7d08 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x0000000191b8f8f8, 0x00000001058d7652 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000008e167708, 0x000000014a098a90 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000148b22d54, 0x0000000020dbe72e }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x0000000044ba2c3c, 0x000000011e7323e8 }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000b54d2b52, 0x00000000d5d4bf94 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000005a4fd8a, 0x0000000199d8746c }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x0000000139f9fc46, 0x00000000ce9ca8a0 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x000000015a1fa824, 0x00000000136edece }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000000a61ae4c, 0x000000019b92a068 }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000145e9113e, 0x0000000071d62206 }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x000000006a348448, 0x00000000dfc50158 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x000000004d80a08c, 0x00000001517626bc }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x000000014b6837a0, 0x0000000148d1e4fa }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x000000016896a7fc, 0x0000000094d8266e }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x000000014f187140, 0x00000000606c5e34 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019581b9da, 0x000000019766beaa }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001091bc984, 0x00000001d80c506c }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001067223c, 0x000000001e73837c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x00000001ab16ea02, 0x0000000064d587de }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x000000013c4598a8, 0x00000000f4a507b0 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x00000000b3735430, 0x0000000040e342fc }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001bb3fc0c0, 0x00000001d5ad9c3a }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x00000001570ae19c, 0x0000000094a691a4 }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001ea910712, 0x00000001271ecdfa }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x0000000167127128, 0x000000009e54475a }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x0000000019e790a2, 0x00000000c9c099ee }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000003788f710, 0x000000009a2f736c }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000001682a160e, 0x00000000bb9f4996 }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x000000007f0ebd2e, 0x00000001db688050 }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x000000002b032080, 0x00000000e9b10af4 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x00000000cfd1664a, 0x000000012d4545e4 }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x00000000aa1181c2, 0x000000000361139c }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000000ddd08002, 0x00000001a5a1a3a8 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x00000000e8dd0446, 0x000000006844e0b0 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000001bbd94a00, 0x00000000c3762f28 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000000ab6cd180, 0x00000001d26287a2 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x0000000031803ce2, 0x00000001f6f0bba8 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x0000000024f40b0c, 0x000000002ffabd62 }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000001ba1d9834, 0x00000000fb4516b8 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x0000000104de61aa, 0x000000018cfa961c }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x0000000113e40d46, 0x000000019e588d52 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001415598a0, 0x00000001180f0bbc }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000bf6c8c90, 0x00000000e1d9177a }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x00000001788b0504, 0x0000000105abc27c }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x0000000038385d02, 0x00000000972e4a58 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x00000001b6c83844, 0x0000000183499a5e }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x0000000051061a8a, 0x00000001c96a8cca }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x000000017351388a, 0x00000001a1a5b60c }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x0000000132928f92, 0x00000000e4b6ac9c }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000000e6b4f48a, 0x00000001807e7f5a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x0000000039d15e90, 0x000000017a7e3bc8 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000312d6074, 0x00000000d73975da }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017bbb2cc4, 0x000000017375d038 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x000000016ded3e18, 0x00000000193680bc }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000f1638b16, 0x00000000999b06f6 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001d38b9ecc, 0x00000001f685d2b8 }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x000000018b8d09dc, 0x00000001f4ecbed2 }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000e7bc27d2, 0x00000000ba16f1a0 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x00000000275e1e96, 0x0000000115aceac4 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000000e2e3031e, 0x00000001aeff6292 }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x00000001041c84d8, 0x000000009640124c }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x00000000706ce672, 0x0000000114f41f02 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000015d5070da, 0x000000009c5f3586 }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x0000000038f9493a, 0x00000001878275fa }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000a3348a76, 0x00000000ddc42ce8 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x00000001ad0aab92, 0x0000000181d2c73a }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x000000019e85f712, 0x0000000141c9320a }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000005a871e76, 0x000000015235719a }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x000000017249c662, 0x00000000be27d804 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000003a084712, 0x000000006242d45a }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x00000000ed438478, 0x000000009a53638e }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000000abac34cc, 0x00000001001ecfb6 }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000005f35ef3e, 0x000000016d7c2d64 }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x0000000047d6608c, 0x00000001d0ce46c0 }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x000000002d01470e, 0x0000000124c907b4 }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000158bbc7b0, 0x0000000018a555ca }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x00000000c0a23e8e, 0x000000006b0980bc }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x00000001ebd85c88, 0x000000008bbba964 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x000000019ee20bb2, 0x00000001070a5a1e }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x00000001acabf2d6, 0x000000002204322a }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000001b7963d56, 0x00000000a27524d0 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x000000017bffa1fe, 0x0000000020b1e4ba }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x000000001f15333e, 0x0000000032cc27fc }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x000000018593129e, 0x0000000044dd22b8 }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x000000019cb32602, 0x00000000dffc9e0a }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x0000000142b05cc8, 0x00000001b7a0ed14 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000001be49e7a4, 0x00000000c7842488 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x0000000108f69d6c, 0x00000001c02a4fee }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000006c0971f0, 0x000000003c273778 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x000000005b16467a, 0x00000001d63f8894 }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x00000001551a628e, 0x000000006be557d6 }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000019e42ea92, 0x000000006a7806ea }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000012fa83ff2, 0x000000016155aa0c }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x000000011ca9cde0, 0x00000000908650ac }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000c8e5cd74, 0x00000000aa5a8084 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000096c27f0c, 0x0000000191bb500a }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x000000002baed926, 0x0000000064e9bed0 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000017c8de8d2, 0x000000009444f302 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x00000000d43d6068, 0x000000019db07d3c }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000000cb2c4b26, 0x00000001359e3e6e }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x0000000145b8da26, 0x00000001e4f10dd2 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x000000018fff4b08, 0x0000000124f5735e }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000150b58ed0, 0x0000000124760a4c }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x00000001549f39bc, 0x000000000f1fc186 }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000ef4d2f42, 0x00000000150e4cc4 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x00000001b1468572, 0x000000002a6204e8 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x000000013d7403b2, 0x00000000beb1d432 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x00000001a4681842, 0x0000000135f3f1f0 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000167714492, 0x0000000074fe2232 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x00000001e599099a, 0x000000001ac6e2ba }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x00000000fe128194, 0x0000000013fca91e }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000077e8b990, 0x0000000183f4931e }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000001a267f63a, 0x00000000b6d9b4e4 }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000001945c245a, 0x00000000b5188656 }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000149002e76, 0x0000000027a81a84 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x00000001bb8310a4, 0x0000000125699258 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x000000019ec60bcc, 0x00000001b23de796 }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x000000012d8590ae, 0x00000000fe4365dc }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x0000000065b00684, 0x00000000c68f497a }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x000000015e5aeadc, 0x00000000fbf521ee }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x00000000b77ff2b0, 0x000000015eac3378 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000188da2ff6, 0x0000000134914b90 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000063da929a, 0x0000000016335cfe }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x00000001389caa80, 0x000000010372d10c }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000013db599d2, 0x000000015097b908 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x0000000122505a86, 0x00000001227a7572 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000016bd72746, 0x000000009a8f75c0 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000001c3faf1d4, 0x00000000682c77a2 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000001111c826c, 0x00000000231f091c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x00000000153e9fb2, 0x000000007d4439f2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000002b1f7b60, 0x000000017e221efc }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x00000000b1dba570, 0x0000000167457c38 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000001f6397b76, 0x00000000bdf081c4 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x0000000156335214, 0x000000016286d6b0 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000001d70e3986, 0x00000000c84f001c }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x000000003701a774, 0x0000000064efe7c0 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x00000000ac81ef72, 0x000000000ac2d904 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x0000000133212464, 0x00000000fd226d14 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x00000000e4e45610, 0x000000011cfd42e0 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000000c1bd370, 0x000000016e5a5678 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001a7b9e7a6, 0x00000001d888fe22 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x000000007d657a10, 0x00000001af77fcd4 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x00000001651797d2, 0x0000000099ea94a8 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x0000000021e0d56c, 0x00000000945a8420 }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x000000000f95ecaa, 0x0000000030762706 }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001ebd224ac, 0x00000001a52fc582 }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x000000000ccb97ca, 0x00000001a4a7167a }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x00000001006ec8a8, 0x000000000c18249a }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x000000014f58f196, 0x00000000a924ae7c }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001a7192ca6, 0x00000001e12ccc12 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x000000019a64bab2, 0x00000000a0b9d4ac }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000014f4ed2e, 0x0000000095e8ddfe }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x000000011092b6a2, 0x00000000233fddc4 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000000c8a1629c, 0x00000001b4529b62 }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x000000017bf32e8e, 0x00000001a7fa0e64 }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001f8cc6582, 0x00000001b5334592 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000008631ddf0, 0x000000011f8ee1b4 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000007e5a76d0, 0x000000006252e632 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x000000002b09b31c, 0x00000000ab973e84 }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x00000001b2df1f84, 0x000000007734f5ec }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x00000001d6f56afc, 0x000000007c547798 }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x00000001b9b5e70c, 0x000000007ec40210 }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x0000000034b626d2, 0x00000001ab1695a8 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x000000014c53479a, 0x0000000090494bba }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001a6d179a4, 0x00000001123fb816 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x000000015abd16b4, 0x00000001e188c74c }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000000018f9852, 0x00000001c2d3451c }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x000000001fb3084a, 0x00000000f55cf1ca }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000000c53dfb04, 0x00000001a0531540 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x00000000e10c9ad6, 0x0000000132cd7ebc }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000025aa994a, 0x0000000073ab7f36 }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x00000000fa3a74c4, 0x0000000041aed1c2 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000033eb3f40, 0x0000000136c53800 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x000000017193f296, 0x0000000126835a30 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x0000000043f6c86a, 0x000000006241b502 }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x000000016b513ec6, 0x00000000d5196ad4 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x00000000c8f25b4e, 0x000000009cfa769a }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000001a45048ec, 0x00000000920e5df4 }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x000000000c441004, 0x0000000169dc310e }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x000000000e17cad6, 0x0000000009fc331c }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x00000001253ae964, 0x000000010d94a81e }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x00000001d7c88ebc, 0x0000000027a20ab2 }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x00000001e7ca913a, 0x0000000114f87504 }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x0000000033ed078a, 0x000000004b076d96 }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000e1839c78, 0x00000000da4d1e74 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x00000001322b267e, 0x000000001b81f672 }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x00000000638231b6, 0x000000009367c988 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001ee7f16f4, 0x00000001717214ca }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x0000000117d9924a, 0x000000009f47d820 }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x00000000e1a9e0c4, 0x000000010d9a47d2 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000001403731dc, 0x00000000a696c58c }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x00000001a5ea9682, 0x000000002aa28ec6 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x0000000101c5c578, 0x00000001fe18fd9a }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x00000000dddf6494, 0x000000019d4fc1ae }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000000f1c3db28, 0x00000001ba0e3dea }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x000000013112fb9c, 0x0000000074b59a5e }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000b680b906, 0x00000000f2b5ea98 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x000000001a282932, 0x0000000187132676 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x0000000089406e7e, 0x000000010a8c6ad4 }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001def6be8c, 0x00000001e21dfe70 }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x0000000075258728, 0x00000001da0050e4 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x000000019536090a, 0x00000000772172ae }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000f2455bfc, 0x00000000e47724aa }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000018c40baf4, 0x000000003cd63ac4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x000000004cd390d4, 0x00000001bf47d352 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x00000001e4ece95a, 0x000000018dc1d708 }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000001a3ee918, 0x000000002d4620a4 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x000000007c652fb8, 0x0000000058fd1740 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x000000011c67842c, 0x00000000dadd9bfc }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000000254f759c, 0x00000001ea2140be }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000007ece94ca, 0x000000009de128ba }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x0000000038f258c2, 0x000000013ac3aa8e }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x00000001cdf17b00, 0x0000000099980562 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x000000011f882c16, 0x00000001c1579c86 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000100093fc8, 0x0000000068dbbf94 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x00000001cd684f16, 0x000000004509fb04 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x000000004bc6a70a, 0x00000001202f6398 }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000004fc7e8e4, 0x000000013aea243e }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x0000000130103f1c, 0x00000001b4052ae6 }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x0000000111b0024c, 0x00000001cd2a0ae8 }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x000000010b3079da, 0x00000001fe4aa8b4 }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x000000010192bcc2, 0x00000001d1559a42 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x0000000074838d50, 0x00000001f3e05ecc }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x000000001b20f520, 0x0000000104ddd2cc }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x0000000050c3590a, 0x000000015393153c }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x00000000b41cac8e, 0x0000000057e942c6 }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000000c72cc78, 0x000000012c633850 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x0000000030cdb032, 0x00000000ebcaae4c }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013e09fc32, 0x000000013ee532a6 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x000000001ed624d2, 0x00000001bf0cbc7e }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000781aee1a, 0x00000000d50b7a5a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x00000001c4d8348c, 0x0000000002fca6e8 }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x0000000057a40336, 0x000000007af40044 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000085544940, 0x0000000016178744 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000019cd21e80, 0x000000014c177458 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000013eb95bc0, 0x000000011b6ddf04 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001dfc9fdfc, 0x00000001f3e29ccc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x00000000cd028bc2, 0x0000000135ae7562 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000090db8c44, 0x0000000190ef812c }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x000000010010a4ce, 0x0000000067a2c786 }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x00000001c8f4c72c, 0x0000000048b9496c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000001c26170c, 0x000000015a422de6 }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000000e3fccf68, 0x00000001ef0e3640 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000000d513ed24, 0x00000001006d2d26 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000000141beada, 0x00000001170d56d6 }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x000000011071aea0, 0x00000000a5fb613c }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x000000012e19080a, 0x0000000040bbf7fc }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x0000000100ecf826, 0x000000016ac3a5b2 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x0000000069b09412, 0x00000000abf16230 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x0000000122297bac, 0x00000001ebe23fac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x00000000e9e4b068, 0x000000008b6a0894 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x000000004b38651a, 0x00000001288ea478 }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x00000001468360e2, 0x000000016619c442 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x00000000121c2408, 0x0000000086230038 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x00000000da7e7d08, 0x000000017746a756 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x00000001058d7652, 0x0000000191b8f8f8 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000014a098a90, 0x000000008e167708 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000020dbe72e, 0x0000000148b22d54 }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x000000011e7323e8, 0x0000000044ba2c3c }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000d5d4bf94, 0x00000000b54d2b52 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000199d8746c, 0x0000000005a4fd8a }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x00000000ce9ca8a0, 0x0000000139f9fc46 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x00000000136edece, 0x000000015a1fa824 }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000019b92a068, 0x000000000a61ae4c }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000071d62206, 0x0000000145e9113e }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x00000000dfc50158, 0x000000006a348448 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x00000001517626bc, 0x000000004d80a08c }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x0000000148d1e4fa, 0x000000014b6837a0 }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x0000000094d8266e, 0x000000016896a7fc }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x00000000606c5e34, 0x000000014f187140 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019766beaa, 0x000000019581b9da }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001d80c506c, 0x00000001091bc984 }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001e73837c, 0x000000001067223c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x0000000064d587de, 0x00000001ab16ea02 }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x00000000f4a507b0, 0x000000013c4598a8 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x0000000040e342fc, 0x00000000b3735430 }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001d5ad9c3a, 0x00000001bb3fc0c0 }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x0000000094a691a4, 0x00000001570ae19c }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001271ecdfa, 0x00000001ea910712 }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x000000009e54475a, 0x0000000167127128 }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x00000000c9c099ee, 0x0000000019e790a2 }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000009a2f736c, 0x000000003788f710 }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000000bb9f4996, 0x00000001682a160e }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x00000001db688050, 0x000000007f0ebd2e }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x00000000e9b10af4, 0x000000002b032080 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x000000012d4545e4, 0x00000000cfd1664a }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x000000000361139c, 0x00000000aa1181c2 }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000001a5a1a3a8, 0x00000000ddd08002 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x000000006844e0b0, 0x00000000e8dd0446 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000000c3762f28, 0x00000001bbd94a00 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000001d26287a2, 0x00000000ab6cd180 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x00000001f6f0bba8, 0x0000000031803ce2 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x000000002ffabd62, 0x0000000024f40b0c }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000000fb4516b8, 0x00000001ba1d9834 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x000000018cfa961c, 0x0000000104de61aa }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x000000019e588d52, 0x0000000113e40d46 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001180f0bbc, 0x00000001415598a0 }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000e1d9177a, 0x00000000bf6c8c90 }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x0000000105abc27c, 0x00000001788b0504 }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x00000000972e4a58, 0x0000000038385d02 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x0000000183499a5e, 0x00000001b6c83844 }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x00000001c96a8cca, 0x0000000051061a8a }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x00000001a1a5b60c, 0x000000017351388a }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x00000000e4b6ac9c, 0x0000000132928f92 }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000001807e7f5a, 0x00000000e6b4f48a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x000000017a7e3bc8, 0x0000000039d15e90 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000d73975da, 0x00000000312d6074 }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017375d038, 0x000000017bbb2cc4 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x00000000193680bc, 0x000000016ded3e18 }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000999b06f6, 0x00000000f1638b16 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001f685d2b8, 0x00000001d38b9ecc }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x00000001f4ecbed2, 0x000000018b8d09dc }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000ba16f1a0, 0x00000000e7bc27d2 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x0000000115aceac4, 0x00000000275e1e96 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000001aeff6292, 0x00000000e2e3031e }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x000000009640124c, 0x00000001041c84d8 }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x0000000114f41f02, 0x00000000706ce672 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000009c5f3586, 0x000000015d5070da }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x00000001878275fa, 0x0000000038f9493a }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000ddc42ce8, 0x00000000a3348a76 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x0000000181d2c73a, 0x00000001ad0aab92 }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x0000000141c9320a, 0x000000019e85f712 }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000015235719a, 0x000000005a871e76 }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x00000000be27d804, 0x000000017249c662 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000006242d45a, 0x000000003a084712 }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x000000009a53638e, 0x00000000ed438478 }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000001001ecfb6, 0x00000000abac34cc }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000016d7c2d64, 0x000000005f35ef3e }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x00000001d0ce46c0, 0x0000000047d6608c }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x0000000124c907b4, 0x000000002d01470e }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000018a555ca, 0x0000000158bbc7b0 }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x000000006b0980bc, 0x00000000c0a23e8e }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x000000008bbba964, 0x00000001ebd85c88 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x00000001070a5a1e, 0x000000019ee20bb2 }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x000000002204322a, 0x00000001acabf2d6 }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000000a27524d0, 0x00000001b7963d56 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x0000000020b1e4ba, 0x000000017bffa1fe }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x0000000032cc27fc, 0x000000001f15333e }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x0000000044dd22b8, 0x000000018593129e }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x00000000dffc9e0a, 0x000000019cb32602 }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x00000001b7a0ed14, 0x0000000142b05cc8 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000000c7842488, 0x00000001be49e7a4 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x00000001c02a4fee, 0x0000000108f69d6c }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000003c273778, 0x000000006c0971f0 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x00000001d63f8894, 0x000000005b16467a }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x000000006be557d6, 0x00000001551a628e }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000006a7806ea, 0x000000019e42ea92 }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000016155aa0c, 0x000000012fa83ff2 }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x00000000908650ac, 0x000000011ca9cde0 }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000aa5a8084, 0x00000000c8e5cd74 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000191bb500a, 0x0000000096c27f0c }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x0000000064e9bed0, 0x000000002baed926 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000009444f302, 0x000000017c8de8d2 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x000000019db07d3c, 0x00000000d43d6068 }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000001359e3e6e, 0x00000000cb2c4b26 }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x00000001e4f10dd2, 0x0000000145b8da26 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x0000000124f5735e, 0x000000018fff4b08 }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000124760a4c, 0x0000000150b58ed0 }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x000000000f1fc186, 0x00000001549f39bc }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000150e4cc4, 0x00000000ef4d2f42 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x000000002a6204e8, 0x00000001b1468572 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x00000000beb1d432, 0x000000013d7403b2 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x0000000135f3f1f0, 0x00000001a4681842 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000074fe2232, 0x0000000167714492 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x000000001ac6e2ba, 0x00000001e599099a }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x0000000013fca91e, 0x00000000fe128194 }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000183f4931e, 0x0000000077e8b990 }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000000b6d9b4e4, 0x00000001a267f63a }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000000b5188656, 0x00000001945c245a }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000027a81a84, 0x0000000149002e76 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x0000000125699258, 0x00000001bb8310a4 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x00000001b23de796, 0x000000019ec60bcc }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x00000000fe4365dc, 0x000000012d8590ae }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x00000000c68f497a, 0x0000000065b00684 }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x00000000fbf521ee, 0x000000015e5aeadc }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x000000015eac3378, 0x00000000b77ff2b0 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000134914b90, 0x0000000188da2ff6 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000016335cfe, 0x0000000063da929a }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x000000010372d10c, 0x00000001389caa80 }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000015097b908, 0x000000013db599d2 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x00000001227a7572, 0x0000000122505a86 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000009a8f75c0, 0x000000016bd72746 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000000682c77a2, 0x00000001c3faf1d4 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000000231f091c, 0x00000001111c826c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x000000007d4439f2, 0x00000000153e9fb2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000017e221efc, 0x000000002b1f7b60 }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x0000000167457c38, 0x00000000b1dba570 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000000bdf081c4, 0x00000001f6397b76 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x000000016286d6b0, 0x0000000156335214 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000000c84f001c, 0x00000001d70e3986 }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x0000000064efe7c0, 0x000000003701a774 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x000000000ac2d904, 0x00000000ac81ef72 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x00000000fd226d14, 0x0000000133212464 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x000000011cfd42e0, 0x00000000e4e45610 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000016e5a5678, 0x000000000c1bd370 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001d888fe22, 0x00000001a7b9e7a6 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x00000001af77fcd4, 0x000000007d657a10 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros */ + +static const __vector unsigned long long vcrc_short_const[16] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0x99168a18ec447f11, 0xed837b2613e8221e }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xe23e954e8fd2cd3c, 0xc8acdd8147b9ce5a }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0x92f8befe6b1d2b53, 0xd9ad6d87d4277e25 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xf38a3556291ea462, 0xc10ec5e033fbca3b }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0x974ac56262b6ca4b, 0xc0b55b0e82e02e2f }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x855712b3784d2a56, 0x71aa1df0e172334d }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xa5abe9f80eaee722, 0xfee3053e3969324d }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0x1fa0943ddb54814c, 0xf44779b93eb2bd08 }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xa53ff440d7bbfe6a, 0xf5449b3f00cc3374 }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0xebe7e3566325605c, 0x6f8346e1d777606e }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xc65a272ce5b592b8, 0xe3ab4f2ac0b95347 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0x5705a9ca4721589f, 0xaa2215ea329ecc11 }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0xe3720acb88d14467, 0x1ed8f66ed95efd26 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0xba1aca0315141c31, 0x78ed02d5a700e96a }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xad2a31b3ed627dae, 0xba8ccbe832b39da3 }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0x6655004fa06a2517, 0xedb88320b1e6b092 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0xed837b2613e8221e, 0x99168a18ec447f11 }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xc8acdd8147b9ce5a, 0xe23e954e8fd2cd3c }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0xd9ad6d87d4277e25, 0x92f8befe6b1d2b53 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xc10ec5e033fbca3b, 0xf38a3556291ea462 }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0xc0b55b0e82e02e2f, 0x974ac56262b6ca4b }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x71aa1df0e172334d, 0x855712b3784d2a56 }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xfee3053e3969324d, 0xa5abe9f80eaee722 }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0xf44779b93eb2bd08, 0x1fa0943ddb54814c }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xf5449b3f00cc3374, 0xa53ff440d7bbfe6a }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0x6f8346e1d777606e, 0xebe7e3566325605c }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xe3ab4f2ac0b95347, 0xc65a272ce5b592b8 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0xaa2215ea329ecc11, 0x5705a9ca4721589f }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0x1ed8f66ed95efd26, 0xe3720acb88d14467 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0x78ed02d5a700e96a, 0xba1aca0315141c31 }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xba8ccbe832b39da3, 0xad2a31b3ed627dae }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0xedb88320b1e6b092, 0x6655004fa06a2517 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Barrett constants */ +/* 33 bit reflected Barrett constant m - (4^32)/n */ + +static const __vector unsigned long long v_Barrett_const[2] ALIGNED_(16) = { + /* x^64 div p(x) */ +#if BYTE_ORDER == LITTLE_ENDIAN + { 0x00000001f7011641, 0x0000000000000000 }, + { 0x00000001db710641, 0x0000000000000000 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + { 0x0000000000000000, 0x00000001f7011641 }, + { 0x0000000000000000, 0x00000001db710641 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_power8.c b/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_power8.c new file mode 100644 index 000000000..1cb5f299f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/crc32_power8.c @@ -0,0 +1,589 @@ +/* crc32 for POWER8 using VSX instructions + * Copyright (C) 2021 IBM Corporation + * + * Author: Rogerio Alves + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate the checksum of data that is 16 byte aligned and a multiple of + * 16 bytes. + * + * The first step is to reduce it to 1024 bits. We do this in 8 parallel + * chunks in order to mask the latency of the vpmsum instructions. If we + * have more than 32 kB of data to checksum we repeat this step multiple + * times, passing in the previous 1024 bits. + * + * The next step is to reduce the 1024 bits to 64 bits. This step adds + * 32 bits of 0s to the end - this matches what a CRC does. We just + * calculate constants that land the data in this 32 bits. + * + * We then use fixed point Barrett reduction to compute a mod n over GF(2) + * for n = CRC using POWER8 instructions. We use x = 32. + * + * http://en.wikipedia.org/wiki/Barrett_reduction + * + * This code uses gcc vector builtins instead using assembly directly. + */ + +#include +#include "zendian.h" +#include "zbuild.h" + +#include "crc32_constants.h" +#include "crc32_braid_tbl.h" + +#if defined (__clang__) +#include "fallback_builtins.h" +#endif + +#define MAX_SIZE 32768 +#define VMX_ALIGN 16 +#define VMX_ALIGN_MASK (VMX_ALIGN-1) + +static unsigned int crc32_align(unsigned int crc, const unsigned char *p, unsigned long len) { + while (len--) + crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); + return crc; +} + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len); + +Z_INTERNAL uint32_t crc32_power8(uint32_t crc, const unsigned char *p, size_t _len) { + unsigned int prealign; + unsigned int tail; + + unsigned long len = (unsigned long) _len; + + if (p == (const unsigned char *) 0x0) + return 0; + + crc ^= 0xffffffff; + + if (len < VMX_ALIGN + VMX_ALIGN_MASK) { + crc = crc32_align(crc, p, len); + goto out; + } + + if ((unsigned long)p & VMX_ALIGN_MASK) { + prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK); + crc = crc32_align(crc, p, prealign); + len -= prealign; + p += prealign; + } + + crc = __crc32_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); + + tail = len & VMX_ALIGN_MASK; + if (tail) { + p += len & ~VMX_ALIGN_MASK; + crc = crc32_align(crc, p, tail); + } + +out: + crc ^= 0xffffffff; + + return crc; +} + +/* When we have a load-store in a single-dispatch group and address overlap + * such that forward is not allowed (load-hit-store) the group must be flushed. + * A group ending NOP prevents the flush. + */ +#define GROUP_ENDING_NOP __asm__("ori 2,2,0" ::: "memory") + +#if BYTE_ORDER == BIG_ENDIAN +#define BYTESWAP_DATA +#endif + +#ifdef BYTESWAP_DATA +#define VEC_PERM(vr, va, vb, vc) vr = vec_perm(va, vb, (__vector unsigned char) vc) +#if BYTE_ORDER == LITTLE_ENDIAN +/* Byte reverse permute constant LE. */ +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x08090A0B0C0D0E0FUL, 0x0001020304050607UL }; +#else +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x0F0E0D0C0B0A0908UL, 0X0706050403020100UL }; +#endif +#else +#define VEC_PERM(vr, va, vb, vc) +#endif + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len) { + + const __vector unsigned long long vzero = {0,0}; + const __vector unsigned long long vones = {0xffffffffffffffffUL, 0xffffffffffffffffUL}; + + const __vector unsigned long long vmask_32bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 4); + + const __vector unsigned long long vmask_64bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 8); + + __vector unsigned long long vcrc; + + __vector unsigned long long vconst1, vconst2; + + /* vdata0-vdata7 will contain our data (p). */ + __vector unsigned long long vdata0, vdata1, vdata2, vdata3, vdata4, vdata5, vdata6, vdata7; + + /* v0-v7 will contain our checksums */ + __vector unsigned long long v0 = {0,0}; + __vector unsigned long long v1 = {0,0}; + __vector unsigned long long v2 = {0,0}; + __vector unsigned long long v3 = {0,0}; + __vector unsigned long long v4 = {0,0}; + __vector unsigned long long v5 = {0,0}; + __vector unsigned long long v6 = {0,0}; + __vector unsigned long long v7 = {0,0}; + + + /* Vector auxiliary variables. */ + __vector unsigned long long va0, va1, va2, va3, va4, va5, va6, va7; + + unsigned int offset; /* Constant table offset. */ + + unsigned long i; /* Counter. */ + unsigned long chunks; + + unsigned long block_size; + int next_block = 0; + + /* Align by 128 bits. The last 128 bit block will be processed at end. */ + unsigned long length = len & 0xFFFFFFFFFFFFFF80UL; + + vcrc = (__vector unsigned long long)__builtin_pack_vector_int128(0UL, crc); + + /* Short version. */ + if (len < 256) { + /* Calculate where in the constant table we need to start. */ + offset = 256 - len; + + vconst1 = vec_ld(offset, vcrc_short_const); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + + /* xor initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + + for (i = 16; i < len; i += 16) { + vconst1 = vec_ld(offset + i, vcrc_short_const); + vdata0 = vec_ld(i, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + } + } else { + + /* Load initial values. */ + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + /* xor in initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + p = (char *)p + 128; + + do { + /* Checksum in blocks of MAX_SIZE. */ + block_size = length; + if (block_size > MAX_SIZE) { + block_size = MAX_SIZE; + } + + length = length - block_size; + + /* + * Work out the offset into the constants table to start at. Each + * constant is 16 bytes, and it is used against 128 bytes of input + * data - 128 / 16 = 8 + */ + offset = (MAX_SIZE/8) - (block_size/8); + /* We reduce our final 128 bytes in a separate step */ + chunks = (block_size/128)-1; + + vconst1 = vec_ld(offset, vcrc_const); + + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + + if (chunks > 1) { + offset += 16; + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + + /* + * main loop. Each iteration calculates the CRC for a 128-byte + * block. + */ + for (i = 0; i < chunks-2; i++) { + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + GROUP_ENDING_NOP; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst2); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst2); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long) + vdata2, (__vector unsigned long long)vconst2); + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst2); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + } + + /* First cool down */ + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + }/* else */ + + /* Second cool down. */ + v0 = vec_xor(v0, va0); + v1 = vec_xor(v1, va1); + v2 = vec_xor(v2, va2); + v3 = vec_xor(v3, va3); + v4 = vec_xor(v4, va4); + v5 = vec_xor(v5, va5); + v6 = vec_xor(v6, va6); + v7 = vec_xor(v7, va7); + + /* + * vpmsumd produces a 96 bit result in the least significant bits + * of the register. Since we are bit reflected we have to shift it + * left 32 bits so it occupies the least significant bits in the + * bit reflected domain. + */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v1, + (__vector unsigned char)vzero, 4); + v2 = (__vector unsigned long long)vec_sld((__vector unsigned char)v2, + (__vector unsigned char)vzero, 4); + v3 = (__vector unsigned long long)vec_sld((__vector unsigned char)v3, + (__vector unsigned char)vzero, 4); + v4 = (__vector unsigned long long)vec_sld((__vector unsigned char)v4, + (__vector unsigned char)vzero, 4); + v5 = (__vector unsigned long long)vec_sld((__vector unsigned char)v5, + (__vector unsigned char)vzero, 4); + v6 = (__vector unsigned long long)vec_sld((__vector unsigned char)v6, + (__vector unsigned char)vzero, 4); + v7 = (__vector unsigned long long)vec_sld((__vector unsigned char)v7, + (__vector unsigned char)vzero, 4); + + /* xor with the last 1024 bits. */ + va0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(va0, va0, va0, vperm_const); + + va1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(va1, va1, va1, vperm_const); + + va2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(va2, va2, va2, vperm_const); + + va3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(va3, va3, va3, vperm_const); + + va4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(va4, va4, va4, vperm_const); + + va5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(va5, va5, va5, vperm_const); + + va6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(va6, va6, va6, vperm_const); + + va7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(va7, va7, va7, vperm_const); + + p = (char *)p + 128; + + vdata0 = vec_xor(v0, va0); + vdata1 = vec_xor(v1, va1); + vdata2 = vec_xor(v2, va2); + vdata3 = vec_xor(v3, va3); + vdata4 = vec_xor(v4, va4); + vdata5 = vec_xor(v5, va5); + vdata6 = vec_xor(v6, va6); + vdata7 = vec_xor(v7, va7); + + /* Check if we have more blocks to process */ + next_block = 0; + if (length != 0) { + next_block = 1; + + /* zero v0-v7 */ + v0 = vec_xor(v0, v0); + v1 = vec_xor(v1, v1); + v2 = vec_xor(v2, v2); + v3 = vec_xor(v3, v3); + v4 = vec_xor(v4, v4); + v5 = vec_xor(v5, v5); + v6 = vec_xor(v6, v6); + v7 = vec_xor(v7, v7); + } + length = length + 128; + + } while (next_block); + + /* Calculate how many bytes we have left. */ + length = (len & 127); + + /* Calculate where in (short) constant table we need to start. */ + offset = 128 - length; + + v0 = vec_ld(offset, vcrc_short_const); + v1 = vec_ld(offset + 16, vcrc_short_const); + v2 = vec_ld(offset + 32, vcrc_short_const); + v3 = vec_ld(offset + 48, vcrc_short_const); + v4 = vec_ld(offset + 64, vcrc_short_const); + v5 = vec_ld(offset + 80, vcrc_short_const); + v6 = vec_ld(offset + 96, vcrc_short_const); + v7 = vec_ld(offset + 112, vcrc_short_const); + + offset += 128; + + v0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)v0); + v1 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata1, (__vector unsigned int)v1); + v2 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata2, (__vector unsigned int)v2); + v3 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata3, (__vector unsigned int)v3); + v4 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata4, (__vector unsigned int)v4); + v5 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata5, (__vector unsigned int)v5); + v6 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata6, (__vector unsigned int)v6); + v7 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata7, (__vector unsigned int)v7); + + /* Now reduce the tail (0-112 bytes). */ + for (i = 0; i < length; i+=16) { + vdata0 = vec_ld(i,(__vector unsigned long long*)p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + va0 = vec_ld(offset + i,vcrc_short_const); + va0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)va0); + v0 = vec_xor(v0, va0); + } + + /* xor all parallel chunks together. */ + v0 = vec_xor(v0, v1); + v2 = vec_xor(v2, v3); + v4 = vec_xor(v4, v5); + v6 = vec_xor(v6, v7); + + v0 = vec_xor(v0, v2); + v4 = vec_xor(v4, v6); + + v0 = vec_xor(v0, v4); + } + + /* Barrett Reduction */ + vconst1 = vec_ld(0, v_Barrett_const); + vconst2 = vec_ld(16, v_Barrett_const); + + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)v0, 8); + v0 = vec_xor(v1,v0); + + /* shift left one bit */ + __vector unsigned char vsht_splat = vec_splat_u8 (1); + v0 = (__vector unsigned long long)vec_sll((__vector unsigned char)v0, vsht_splat); + + v0 = vec_and(v0, vmask_64bit); + + /* + * The reflected version of Barrett reduction. Instead of bit + * reflecting our data (which is expensive to do), we bit reflect our + * constants and our algorithm, which means the intermediate data in + * our vector registers goes from 0-63 instead of 63-0. We can reflect + * the algorithm because we don't carry in mod 2 arithmetic. + */ + + /* bottom 32 bits of a */ + v1 = vec_and(v0, vmask_32bit); + + /* ma */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst1); + + /* bottom 32bits of ma */ + v1 = vec_and(v1, vmask_32bit); + /* qn */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst2); + /* a - qn, subtraction is xor in GF(2) */ + v0 = vec_xor (v0, v1); + + /* + * Since we are bit reflected, the result (ie the low 32 bits) is in + * the high 32 bits. We just need to shift it left 4 bytes + * V0 [ 0 1 X 3 ] + * V0 [ 0 X 2 3 ] + */ + + /* shift result into top 64 bits of */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + +#if BYTE_ORDER == BIG_ENDIAN + return v0[0]; +#else + return v0[1]; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.2/arch/power/fallback_builtins.h new file mode 100644 index 000000000..ed9584617 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/fallback_builtins.h @@ -0,0 +1,31 @@ +/* Helper functions to work around issues with clang builtins + * Copyright (C) 2021 IBM Corporation + * + * Authors: + * Daniel Black + * Rogerio Alves + * Tulio Magno Quites Machado Filho + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_BUILTINS_H +#define POWER_BUILTINS_H + +/* + * These stubs fix clang incompatibilities with GCC builtins. + */ + +#ifndef __builtin_crypto_vpmsumw +#define __builtin_crypto_vpmsumw __builtin_crypto_vpmsumb +#endif +#ifndef __builtin_crypto_vpmsumd +#define __builtin_crypto_vpmsumd __builtin_crypto_vpmsumb +#endif + +static inline __vector unsigned long long __attribute__((overloadable)) +vec_ld(int __a, const __vector unsigned long long* __b) { + return (__vector unsigned long long)__builtin_altivec_lvx(__a, __b); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.c b/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.c new file mode 100644 index 000000000..003a4c6e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.c @@ -0,0 +1,42 @@ +/* power_features.c - POWER feature check + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021-2022 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef HAVE_SYS_AUXV_H +# include +#endif +#ifdef __FreeBSD__ +# include +#endif +#include "../../zbuild.h" +#include "power_features.h" + +void Z_INTERNAL power_check_features(struct power_cpu_features *features) { +#ifdef PPC_FEATURES + unsigned long hwcap; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); +#else + hwcap = getauxval(AT_HWCAP); +#endif + + if (hwcap & PPC_FEATURE_HAS_ALTIVEC) + features->has_altivec = 1; +#endif + +#ifdef POWER_FEATURES + unsigned long hwcap2; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); +#else + hwcap2 = getauxval(AT_HWCAP2); +#endif + + if (hwcap2 & PPC_FEATURE2_ARCH_2_07) + features->has_arch_2_07 = 1; + if (hwcap2 & PPC_FEATURE2_ARCH_3_00) + features->has_arch_3_00 = 1; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.h b/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.h new file mode 100644 index 000000000..9252364cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/power_features.h @@ -0,0 +1,18 @@ +/* power_features.h -- check for POWER CPU features + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_H_ +#define POWER_H_ + +struct power_cpu_features { + int has_altivec; + int has_arch_2_07; + int has_arch_3_00; +}; + +void Z_INTERNAL power_check_features(struct power_cpu_features *features); + +#endif /* POWER_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_power8.c b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_power8.c new file mode 100644 index 000000000..d01e0acd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_power8.c @@ -0,0 +1,12 @@ +/* Optimized slide_hash for POWER processors + * Copyright (C) 2019-2020 IBM Corporation + * Author: Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX + +#define SLIDE_PPC slide_hash_power8 +#include "slide_ppc_tpl.h" + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_vmx.c b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_vmx.c new file mode 100644 index 000000000..5a87ef7d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_hash_vmx.c @@ -0,0 +1,10 @@ +/* Optimized slide_hash for PowerPC processors with VMX instructions + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef PPC_VMX + +#define SLIDE_PPC slide_hash_vmx +#include "slide_ppc_tpl.h" + +#endif /* PPC_VMX */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/power/slide_ppc_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_ppc_tpl.h new file mode 100644 index 000000000..5c17e38fb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/power/slide_ppc_tpl.h @@ -0,0 +1,31 @@ +/* Optimized slide_hash for PowerPC processors + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" + +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + const vector unsigned short vmx_wsize = vec_splats(wsize); + Pos *p = table; + + do { + vector unsigned short value, result; + + value = vec_ld(0, p); + result = vec_subs(value, vmx_wsize); + vec_st(result, 0, p); + + p += 8; + entries -= 8; + } while (entries > 0); +} + +void Z_INTERNAL SLIDE_PPC(deflate_state *s) { + uint16_t wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/riscv/README.md b/internal-complibs/zlib-ng-2.1.2/arch/riscv/README.md new file mode 100644 index 000000000..b4309e1a0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/riscv/README.md @@ -0,0 +1,45 @@ +# Building RISC-V Target with Cmake # + +> **Warning** +> We cannot detect rvv support at runtime, running the rvv code on a no-rvv target is a risk. Users should disable the rvv when the target does not support it. +> +> We will have a better solution when the kernels update `hwcap` or `hwprobe` for risc-v. + +## Prerequisite: Build RISC-V Clang Toolchain and QEMU ## + +If you don't have prebuilt clang and riscv64 qemu, you can refer to the [script](https://github.com/sifive/prepare-riscv-toolchain-qemu/blob/main/prepare_riscv_toolchain_qemu.sh) to get the source. Copy the script to the zlib-ng root directory, and run it to download the source and build them. Modify the content according to your conditions (e.g., toolchain version). + +```bash +./prepare_riscv_toolchain_qemu.sh +``` + +After running script, clang & qemu are built in `build-toolchain-qemu/riscv-clang/` & `build-toolchain-qemu/riscv-qemu/`. + +`build-toolchain-qemu/riscv-clang/` is your `TOOLCHAIN_PATH`. +`build-toolchain-qemu/riscv-qemu/bin/qemu-riscv64` is your `QEMU_PATH`. + +You can also download the prebuilt toolchain & qemu from [the release page](https://github.com/sifive/prepare-riscv-toolchain-qemu/releases), and enjoy using them. + +## Cross-Compile for RISC-V Target ## + +```bash +cmake -G Ninja -B ./build-riscv \ + -D CMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake \ + -D CMAKE_INSTALL_PREFIX=./build-riscv/install \ + -D TOOLCHAIN_PATH={TOOLCHAIN_PATH} \ + -D QEMU_PATH={QEMU_PATH} \ + . + +cmake --build ./build-riscv +``` + +Disable the option if there is no RVV support: +``` +-D WITH_RVV=OFF +``` + +## Run Unittests on User Mode QEMU ## + +```bash +cd ./build-riscv && ctest --verbose +``` diff --git a/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.c b/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.c new file mode 100644 index 000000000..362d71483 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "../../zbuild.h" +#include "riscv_features.h" + +/* TODO: detect risc-v cpu info at runtime when the kernel updates hwcap or hwprobe for risc-v */ +void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features) { +#if defined(__riscv_v) && defined(__linux__) + features->has_rvv = 1; +#else + features->has_rvv = 0; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.h b/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.h new file mode 100644 index 000000000..f933fc9ac --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/riscv/riscv_features.h @@ -0,0 +1,18 @@ +/* riscv_features.h -- check for riscv features. + * + * Copyright (C) 2023 SiFive, Inc. All rights reserved. + * Contributed by Alex Chiang + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef RISCV_H_ +#define RISCV_H_ + +struct riscv_cpu_features { + int has_rvv; +}; + +void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features); + +#endif /* RISCV_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/Makefile.in b/internal-complibs/zlib-ng-2.1.2/arch/s390/Makefile.in new file mode 100644 index 000000000..6b4fba777 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/Makefile.in @@ -0,0 +1,54 @@ +# Makefile for zlib-ng +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= +VGFMAFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +s390_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +s390_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +dfltcc_common.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_common.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_deflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_deflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_inflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +dfltcc_inflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +crc32-vx.o: + $(CC) $(CFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +crc32-vx.lo: + $(CC) $(SFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/README.md b/internal-complibs/zlib-ng-2.1.2/arch/s390/README.md new file mode 100644 index 000000000..2c3165412 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/README.md @@ -0,0 +1,284 @@ +# Introduction + +This directory contains SystemZ deflate hardware acceleration support. +It can be enabled using the following build commands: + + $ ./configure --with-dfltcc-deflate --with-dfltcc-inflate + $ make + +or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 -DWITH_DFLTCC_INFLATE=1 . + $ make + +When built like this, zlib-ng would compress using hardware on level 1, +and using software on all other levels. Decompression will always happen +in hardware. In order to enable hardware compression for levels 1-6 +(i.e. to make it used by default) one could add +`-DDFLTCC_LEVEL_MASK=0x7e` to CFLAGS when building zlib-ng. + +SystemZ deflate hardware acceleration is available on [IBM z15]( +https://www.ibm.com/products/z15) and newer machines under the name [ +"Integrated Accelerator for zEnterprise Data Compression"]( +https://www.ibm.com/support/z-content-solutions/compression/). The +programming interface to it is a machine instruction called DEFLATE +CONVERSION CALL (DFLTCC). It is documented in Chapter 26 of [Principles +of Operation](https://publibfp.dhe.ibm.com/epubs/pdf/a227832c.pdf). Both +the code and the rest of this document refer to this feature simply as +"DFLTCC". + +# Performance + +Performance figures are published [here]( +https://github.com/iii-i/zlib-ng/wiki/Performance-with-dfltcc-patch-applied-and-dfltcc-support-built-on-dfltcc-enabled-machine +). The compression speed-up can be as high as 110x and the decompression +speed-up can be as high as 15x. + +# Limitations + +Two DFLTCC compression calls with identical inputs are not guaranteed to +produce identical outputs. Therefore care should be taken when using +hardware compression when reproducible results are desired. In +particular, zlib-ng-specific `zng_deflateSetParams` call allows setting +`Z_DEFLATE_REPRODUCIBLE` parameter, which disables DFLTCC support for a +particular stream. + +DFLTCC does not support every single zlib-ng feature, in particular: + +* `inflate(Z_BLOCK)` and `inflate(Z_TREES)` +* `inflateMark()` +* `inflatePrime()` +* `inflateSyncPoint()` + +When used, these functions will either switch to software, or, in case +this is not possible, gracefully fail. + +# Code structure + +All SystemZ-specific code lives in `arch/s390` directory and is +integrated with the rest of zlib-ng using hook macros. + +## Hook macros + +DFLTCC takes as arguments a parameter block, an input buffer, an output +buffer and a window. `ZALLOC_DEFLATE_STATE()`, `ZALLOC_INFLATE_STATE()`, +`ZFREE_STATE()`, `ZCOPY_DEFLATE_STATE()`, `ZCOPY_INFLATE_STATE()`, +`ZALLOC_WINDOW()`, `ZCOPY_WINDOW()` and `TRY_FREE_WINDOW()` macros encapsulate +allocation details for the parameter block (which is allocated alongside +zlib-ng state) and the window (which must be page-aligned and large enough). + +Software and hardware window formats do not match, therefore, +`deflateSetDictionary()`, `deflateGetDictionary()`, `inflateSetDictionary()` +and `inflateGetDictionary()` need special handling, which is triggered using +`DEFLATE_SET_DICTIONARY_HOOK()`, `DEFLATE_GET_DICTIONARY_HOOK()`, +`INFLATE_SET_DICTIONARY_HOOK()` and `INFLATE_GET_DICTIONARY_HOOK()` macros. + +`deflateResetKeep()` and `inflateResetKeep()` update the DFLTCC +parameter block using `DEFLATE_RESET_KEEP_HOOK()` and +`INFLATE_RESET_KEEP_HOOK()` macros. + +`INFLATE_PRIME_HOOK()`, `INFLATE_MARK_HOOK()` and +`INFLATE_SYNC_POINT_HOOK()` macros make the respective unsupported +calls gracefully fail. + +`DEFLATE_PARAMS_HOOK()` implements switching between hardware and +software compression mid-stream using `deflateParams()`. Switching +normally entails flushing the current block, which might not be possible +in low memory situations. `deflateParams()` uses `DEFLATE_DONE()` hook +in order to detect and gracefully handle such situations. + +The algorithm implemented in hardware has different compression ratio +than the one implemented in software. `DEFLATE_BOUND_ADJUST_COMPLEN()` +and `DEFLATE_NEED_CONSERVATIVE_BOUND()` macros make `deflateBound()` +return the correct results for the hardware implementation. + +Actual compression and decompression are handled by `DEFLATE_HOOK()` and +`INFLATE_TYPEDO_HOOK()` macros. Since inflation with DFLTCC manages the +window on its own, calling `updatewindow()` is suppressed using +`INFLATE_NEED_UPDATEWINDOW()` macro. + +In addition to compression, DFLTCC computes CRC-32 and Adler-32 +checksums, therefore, whenever it's used, software checksumming is +suppressed using `DEFLATE_NEED_CHECKSUM()` and `INFLATE_NEED_CHECKSUM()` +macros. + +While software always produces reproducible compression results, this +is not the case for DFLTCC. Therefore, zlib-ng users are given the +ability to specify whether or not reproducible compression results +are required. While it is always possible to specify this setting +before the compression begins, it is not always possible to do so in +the middle of a deflate stream - the exact conditions for that are +determined by `DEFLATE_CAN_SET_REPRODUCIBLE()` macro. + +## SystemZ-specific code + +When zlib-ng is built with DFLTCC, the hooks described above are +converted to calls to functions, which are implemented in +`arch/s390/dfltcc_*` files. The functions can be grouped in three broad +categories: + +* Base DFLTCC support, e.g. wrapping the machine instruction - + `dfltcc()` and allocating aligned memory - `dfltcc_alloc_state()`. +* Translating between software and hardware data formats, e.g. + `dfltcc_deflate_set_dictionary()`. +* Translating between software and hardware state machines, e.g. + `dfltcc_deflate()` and `dfltcc_inflate()`. + +The functions from the first two categories are fairly simple, however, +various quirks in both software and hardware state machines make the +functions from the third category quite complicated. + +### `dfltcc_deflate()` function + +This function is called by `deflate()` and has the following +responsibilities: + +* Checking whether DFLTCC can be used with the current stream. If this + is not the case, then it returns `0`, making `deflate()` use some + other function in order to compress in software. Otherwise it returns + `1`. +* Block management and Huffman table generation. DFLTCC ends blocks only + when explicitly instructed to do so by the software. Furthermore, + whether to use fixed or dynamic Huffman tables must also be determined + by the software. Since looking at data in order to gather statistics + would negate performance benefits, the following approach is used: the + first `DFLTCC_FIRST_FHT_BLOCK_SIZE` bytes are placed into a fixed + block, and every next `DFLTCC_BLOCK_SIZE` bytes are placed into + dynamic blocks. +* Writing EOBS. Block Closing Control bit in the parameter block + instructs DFLTCC to write EOBS, however, certain conditions need to be + met: input data length must be non-zero or Continuation Flag must be + set. To put this in simpler terms, DFLTCC will silently refuse to + write EOBS if this is the only thing that it is asked to do. Since the + code has to be able to emit EOBS in software anyway, in order to avoid + tricky corner cases Block Closing Control is never used. Whether to + write EOBS is instead controlled by `soft_bcc` variable. +* Triggering block post-processing. Depending on flush mode, `deflate()` + must perform various additional actions when a block or a stream ends. + `dfltcc_deflate()` informs `deflate()` about this using + `block_state *result` parameter. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `wrap` and Check Value Type or `bi_valid` + and Sub-Byte Boundary. Certain fields cannot be translated and must + persist untouched in the parameter block between calls, for example, + Continuation Flag or Continuation State Buffer. +* Handling flush modes and low-memory situations. These aspects are + quite intertwined and pervasive. The general idea here is that the + code must not do anything in software - whether explicitly by e.g. + calling `send_eobs()`, or implicitly - by returning to `deflate()` + with certain return and `*result` values, when Continuation Flag is + set. +* Ending streams. When a new block is started and flush mode is + `Z_FINISH`, Block Header Final parameter block bit is used to mark + this block as final. However, sometimes an empty final block is + needed, and, unfortunately, just like with EOBS, DFLTCC will silently + refuse to do this. The general idea of DFLTCC implementation is to + rely as much as possible on the existing code. Here in order to do + this, the code pretends that it does not support DFLTCC, which makes + `deflate()` call a software compression function, which writes an + empty final block. Whether this is required is controlled by + `need_empty_block` variable. +* Error handling. This is simply converting + Operation-Ending-Supplemental Code to string. Errors can only happen + due to things like memory corruption, and therefore they don't affect + the `deflate()` return code. + +### `dfltcc_inflate()` function + +This function is called by `inflate()` from the `TYPEDO` state (that is, +when all the metadata is parsed and the stream is positioned at the type +bits of deflate block header) and it's responsible for the following: + +* Falling back to software when flush mode is `Z_BLOCK` or `Z_TREES`. + Unfortunately, there is no way to ask DFLTCC to stop decompressing on + block or tree boundary. +* `inflate()` decompression loop management. This is controlled using + the return value, which can be either `DFLTCC_INFLATE_BREAK` or + `DFLTCC_INFLATE_CONTINUE`. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `whave` and History Length or `wnext` and + History Offset. +* Ending streams. This instructs `inflate()` to return `Z_STREAM_END` + and is controlled by `last` state field. +* Error handling. Like deflate, error handling comprises + Operation-Ending-Supplemental Code to string conversion. Unlike + deflate, errors may happen due to bad inputs, therefore they are + propagated to `inflate()` by setting `mode` field to `MEM` or `BAD`. + +# Testing + +Given complexity of DFLTCC machine instruction, it is not clear whether +QEMU TCG will ever support it. At the time of writing, one has to have +access to an IBM z15+ VM or LPAR in order to test DFLTCC support. Since +DFLTCC is a non-privileged instruction, neither special VM/LPAR +configuration nor root are required. + +zlib-ng CI uses an IBM-provided z15 self-hosted builder for the DFLTCC +testing. There are no IBM Z builds of GitHub Actions runner, and +stable qemu-user has problems with .NET apps, so the builder runs the +x86_64 runner version with qemu-user built from the master branch. + +## Configuring the builder. + +### Install prerequisites. + +``` +$ sudo dnf install docker +``` + +### Add services. + +``` +$ sudo cp self-hosted-builder/*.service /etc/systemd/system/ +$ sudo systemctl daemon-reload +``` + +### Create a config file. + +``` +$ sudo tee /etc/actions-runner +repo=/ +access_token= +``` + +Access token should have the repo scope, consult +https://docs.github.com/en/rest/reference/actions#create-a-registration-token-for-a-repository +for details. + +### Autostart the x86_64 emulation support. + +``` +$ sudo systemctl enable --now qemu-user-static +``` + +### Autostart the runner. + +``` +$ sudo systemctl enable --now actions-runner +``` + +## Rebuilding the image + +In order to update the `iiilinuxibmcom/actions-runner` image, e.g. to get the +latest OS security fixes, use the following commands: + +``` +$ sudo docker build \ + --pull \ + -f self-hosted-builder/actions-runner.Dockerfile \ + -t iiilinuxibmcom/actions-runner +$ sudo systemctl restart actions-runner +``` + +## Removing persistent data + +The `actions-runner` service stores various temporary data, such as runner +registration information, work directories and logs, in the `actions-runner` +volume. In order to remove it and start from scratch, e.g. when switching the +runner to a different repository, use the following commands: + +``` +$ sudo systemctl stop actions-runner +$ sudo docker rm -f actions-runner +$ sudo docker volume rm actions-runner +``` diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/crc32-vx.c b/internal-complibs/zlib-ng-2.1.2/arch/s390/crc32-vx.c new file mode 100644 index 000000000..acfa21887 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/crc32-vx.c @@ -0,0 +1,222 @@ +/* + * Hardware-accelerated CRC-32 variants for Linux on z Systems + * + * Use the z/Architecture Vector Extension Facility to accelerate the + * computing of bitreflected CRC-32 checksums. + * + * This CRC-32 implementation algorithm is bitreflected and processes + * the least-significant bit first (Little-Endian). + * + * This code was originally written by Hendrik Brueckner + * for use in the Linux kernel and has been + * relicensed under the zlib license. + */ + +#include "../../zbuild.h" +#include "crc32_braid_p.h" + +#include + +typedef unsigned char uv16qi __attribute__((vector_size(16))); +typedef unsigned int uv4si __attribute__((vector_size(16))); +typedef unsigned long long uv2di __attribute__((vector_size(16))); + +static uint32_t crc32_le_vgfm_16(uint32_t crc, const uint8_t *buf, size_t len) { + /* + * The CRC-32 constant block contains reduction constants to fold and + * process particular chunks of the input data stream in parallel. + * + * For the CRC-32 variants, the constants are precomputed according to + * these definitions: + * + * R1 = [(x4*128+32 mod P'(x) << 32)]' << 1 + * R2 = [(x4*128-32 mod P'(x) << 32)]' << 1 + * R3 = [(x128+32 mod P'(x) << 32)]' << 1 + * R4 = [(x128-32 mod P'(x) << 32)]' << 1 + * R5 = [(x64 mod P'(x) << 32)]' << 1 + * R6 = [(x32 mod P'(x) << 32)]' << 1 + * + * The bitreflected Barret reduction constant, u', is defined as + * the bit reversal of floor(x**64 / P(x)). + * + * where P(x) is the polynomial in the normal domain and the P'(x) is the + * polynomial in the reversed (bitreflected) domain. + * + * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials: + * + * P(x) = 0x04C11DB7 + * P'(x) = 0xEDB88320 + */ + const uv16qi perm_le2be = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; /* BE->LE mask */ + const uv2di r2r1 = {0x1C6E41596, 0x154442BD4}; /* R2, R1 */ + const uv2di r4r3 = {0x0CCAA009E, 0x1751997D0}; /* R4, R3 */ + const uv2di r5 = {0, 0x163CD6124}; /* R5 */ + const uv2di ru_poly = {0, 0x1F7011641}; /* u' */ + const uv2di crc_poly = {0, 0x1DB710641}; /* P'(x) << 1 */ + + /* + * Load the initial CRC value. + * + * The CRC value is loaded into the rightmost word of the + * vector register and is later XORed with the LSB portion + * of the loaded input data. + */ + uv2di v0 = {0, 0}; + v0 = (uv2di)vec_insert(crc, (uv4si)v0, 3); + + /* Load a 64-byte data chunk and XOR with CRC */ + uv2di v1 = vec_perm(((uv2di *)buf)[0], ((uv2di *)buf)[0], perm_le2be); + uv2di v2 = vec_perm(((uv2di *)buf)[1], ((uv2di *)buf)[1], perm_le2be); + uv2di v3 = vec_perm(((uv2di *)buf)[2], ((uv2di *)buf)[2], perm_le2be); + uv2di v4 = vec_perm(((uv2di *)buf)[3], ((uv2di *)buf)[3], perm_le2be); + + v1 ^= v0; + buf += 64; + len -= 64; + + while (len >= 64) { + /* Load the next 64-byte data chunk */ + uv16qi part1 = vec_perm(((uv16qi *)buf)[0], ((uv16qi *)buf)[0], perm_le2be); + uv16qi part2 = vec_perm(((uv16qi *)buf)[1], ((uv16qi *)buf)[1], perm_le2be); + uv16qi part3 = vec_perm(((uv16qi *)buf)[2], ((uv16qi *)buf)[2], perm_le2be); + uv16qi part4 = vec_perm(((uv16qi *)buf)[3], ((uv16qi *)buf)[3], perm_le2be); + + /* + * Perform a GF(2) multiplication of the doublewords in V1 with + * the R1 and R2 reduction constants in V0. The intermediate result + * is then folded (accumulated) with the next data chunk in PART1 and + * stored in V1. Repeat this step for the register contents + * in V2, V3, and V4 respectively. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r2r1, v1, part1); + v2 = (uv2di)vec_gfmsum_accum_128(r2r1, v2, part2); + v3 = (uv2di)vec_gfmsum_accum_128(r2r1, v3, part3); + v4 = (uv2di)vec_gfmsum_accum_128(r2r1, v4, part4); + + buf += 64; + len -= 64; + } + + /* + * Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3 + * and R4 and accumulating the next 128-bit chunk until a single 128-bit + * value remains. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v3); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v4); + + while (len >= 16) { + /* Load next data chunk */ + v2 = vec_perm(*(uv2di *)buf, *(uv2di *)buf, perm_le2be); + + /* Fold next data chunk */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + + buf += 16; + len -= 16; + } + + /* + * Set up a vector register for byte shifts. The shift value must + * be loaded in bits 1-4 in byte element 7 of a vector register. + * Shift by 8 bytes: 0x40 + * Shift by 4 bytes: 0x20 + */ + uv16qi v9 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + v9 = vec_insert((unsigned char)0x40, v9, 7); + + /* + * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes + * to move R4 into the rightmost doubleword and set the leftmost + * doubleword to 0x1. + */ + v0 = vec_srb(r4r3, (uv2di)v9); + v0[0] = 1; + + /* + * Compute GF(2) product of V1 and V0. The rightmost doubleword + * of V1 is multiplied with R4. The leftmost doubleword of V1 is + * multiplied by 0x1 and is then XORed with rightmost product. + * Implicitly, the intermediate leftmost product becomes padded + */ + v1 = (uv2di)vec_gfmsum_128(v0, v1); + + /* + * Now do the final 32-bit fold by multiplying the rightmost word + * in V1 with R5 and XOR the result with the remaining bits in V1. + * + * To achieve this by a single VGFMAG, right shift V1 by a word + * and store the result in V2 which is then accumulated. Use the + * vector unpack instruction to load the rightmost half of the + * doubleword into the rightmost doubleword element of V1; the other + * half is loaded in the leftmost doubleword. + * The vector register with CONST_R5 contains the R5 constant in the + * rightmost doubleword and the leftmost doubleword is zero to ignore + * the leftmost product of V1. + */ + v9 = vec_insert((unsigned char)0x20, v9, 7); + v2 = vec_srb(v1, (uv2di)v9); + v1 = vec_unpackl((uv4si)v1); /* Split rightmost doubleword */ + v1 = (uv2di)vec_gfmsum_accum_128(r5, v1, (uv16qi)v2); + + /* + * Apply a Barret reduction to compute the final 32-bit CRC value. + * + * The input values to the Barret reduction are the degree-63 polynomial + * in V1 (R(x)), degree-32 generator polynomial, and the reduction + * constant u. The Barret reduction result is the CRC value of R(x) mod + * P(x). + * + * The Barret reduction algorithm is defined as: + * + * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u + * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x) + * 3. C(x) = R(x) XOR T2(x) mod x^32 + * + * Note: The leftmost doubleword of vector register containing + * CONST_RU_POLY is zero and, thus, the intermediate GF(2) product + * is zero and does not contribute to the final result. + */ + + /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */ + v2 = vec_unpackl((uv4si)v1); + v2 = (uv2di)vec_gfmsum_128(ru_poly, v2); + + /* + * Compute the GF(2) product of the CRC polynomial with T1(x) in + * V2 and XOR the intermediate result, T2(x), with the value in V1. + * The final result is stored in word element 2 of V2. + */ + v2 = vec_unpackl((uv4si)v2); + v2 = (uv2di)vec_gfmsum_accum_128(crc_poly, v2, (uv16qi)v1); + + return ((uv4si)v2)[2]; +} + +#define VX_MIN_LEN 64 +#define VX_ALIGNMENT 16L +#define VX_ALIGN_MASK (VX_ALIGNMENT - 1) + +uint32_t Z_INTERNAL crc32_s390_vx(uint32_t crc, const unsigned char *buf, size_t len) { + size_t prealign, aligned, remaining; + + if (len < VX_MIN_LEN + VX_ALIGN_MASK) + return PREFIX(crc32_braid)(crc, buf, len); + + if ((uintptr_t)buf & VX_ALIGN_MASK) { + prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK); + len -= prealign; + crc = PREFIX(crc32_braid)(crc, buf, prealign); + buf += prealign; + } + aligned = len & ~VX_ALIGN_MASK; + remaining = len & VX_ALIGN_MASK; + + crc = crc32_le_vgfm_16(crc ^ 0xffffffff, buf, aligned) ^ 0xffffffff; + + if (remaining) + crc = PREFIX(crc32_braid)(crc, buf + aligned, remaining); + + return crc; +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.c b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.c new file mode 100644 index 000000000..78be71811 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.c @@ -0,0 +1,40 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL general support. */ + +#include "zbuild.h" +#include "dfltcc_common.h" +#include "dfltcc_detail.h" + +/* + Memory management. + + DFLTCC requires parameter blocks and window to be aligned. zlib-ng allows + users to specify their own allocation functions, so using e.g. + `posix_memalign' is not an option. Thus, we overallocate and take the + aligned portion of the buffer. +*/ + +static const int PAGE_ALIGN = 0x1000; + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size) { + void *p; + void *w; + + /* To simplify freeing, we store the pointer to the allocated buffer right + * before the window. Note that DFLTCC always uses HB_SIZE bytes. + */ + p = ZALLOC(strm, sizeof(void *) + MAX(items * size, HB_SIZE) + PAGE_ALIGN, sizeof(unsigned char)); + if (p == NULL) + return NULL; + w = ALIGN_UP((char *)p + sizeof(void *), PAGE_ALIGN); + *(void **)((char *)w - sizeof(void *)) = p; + return w; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n) { + memcpy(dest, src, MAX(n, HB_SIZE)); +} + +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w) { + if (w) + ZFREE(strm, *(void **)((unsigned char *)w - sizeof(void *))); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.h b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.h new file mode 100644 index 000000000..b73437411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_common.h @@ -0,0 +1,44 @@ +#ifndef DFLTCC_COMMON_H +#define DFLTCC_COMMON_H + +#include "zutil.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size); +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n); +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w); + +#define ZFREE_STATE ZFREE + +#define ZALLOC_WINDOW PREFIX(dfltcc_alloc_window) + +#define ZCOPY_WINDOW PREFIX(dfltcc_copy_window) + +#define ZFREE_WINDOW PREFIX(dfltcc_free_window) + +#define TRY_FREE_WINDOW PREFIX(dfltcc_free_window) + +#define DFLTCC_BLOCK_HEADER_BITS 3 +#define DFLTCC_HLITS_COUNT_BITS 5 +#define DFLTCC_HDISTS_COUNT_BITS 5 +#define DFLTCC_HCLENS_COUNT_BITS 4 +#define DFLTCC_MAX_HCLENS 19 +#define DFLTCC_HCLEN_BITS 3 +#define DFLTCC_MAX_HLITS 286 +#define DFLTCC_MAX_HDISTS 30 +#define DFLTCC_MAX_HLIT_HDIST_BITS 7 +#define DFLTCC_MAX_SYMBOL_BITS 16 +#define DFLTCC_MAX_EOBS_BITS 15 +#define DFLTCC_MAX_PADDING_BITS 7 + +#define DEFLATE_BOUND_COMPLEN(source_len) \ + ((DFLTCC_BLOCK_HEADER_BITS + \ + DFLTCC_HLITS_COUNT_BITS + \ + DFLTCC_HDISTS_COUNT_BITS + \ + DFLTCC_HCLENS_COUNT_BITS + \ + DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ + (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ + (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ + DFLTCC_MAX_EOBS_BITS + \ + DFLTCC_MAX_PADDING_BITS) >> 3) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.c b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.c new file mode 100644 index 000000000..3ad988afc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.c @@ -0,0 +1,404 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL compression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC compression support: + + $ ./configure --with-dfltcc-deflate + or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "deflate.h" +#include "trees_emit.h" +#include "dfltcc_deflate.h" +#include "dfltcc_detail.h" + +struct dfltcc_deflate_state { + struct dfltcc_state common; + uint16_t level_mask; /* Levels on which to use DFLTCC */ + uint32_t block_size; /* New block each X bytes */ + size_t block_threshold; /* New block after total_in > X */ + uint32_t dht_threshold; /* New block only if avail_in >= X */ +}; + +#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state)) + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp) strm) { + return dfltcc_alloc_state(strm, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + dfltcc_reset_state(&dfltcc_state->common); + + /* Initialize tuning parameters */ + dfltcc_state->level_mask = DFLTCC_LEVEL_MASK; + dfltcc_state->block_size = DFLTCC_BLOCK_SIZE; + dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE; + dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src) { + dfltcc_copy_state(dst, src, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +static inline int dfltcc_can_deflate_with_params(PREFIX3(streamp) strm, int level, uInt window_bits, int strategy, + int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + /* Unsupported compression settings */ + if ((dfltcc_state->level_mask & (1 << level)) == 0) + return 0; + if (window_bits != HB_BITS) + return 0; + if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) + return 0; + if (reproducible) + return 0; + + /* Unsupported hardware */ + if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) || + !is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) || + !is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0)) + return 0; + + return 1; +} + +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + + return dfltcc_can_deflate_with_params(strm, state->level, state->w_bits, state->strategy, state->reproducible); +} + +static inline void dfltcc_gdht(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + + dfltcc(DFLTCC_GDHT, param, NULL, NULL, &strm->next_in, &avail_in, NULL); +} + +static inline dfltcc_cc dfltcc_cmpr(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->total_in += (strm->avail_in - avail_in); + strm->total_out += (strm->avail_out - avail_out); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +static inline void send_eobs(PREFIX3(streamp) strm, const struct dfltcc_param_v0 *param) { + deflate_state *state = (deflate_state *)strm->state; + + send_bits(state, PREFIX(bi_reverse)(param->eobs >> (15 - param->eobl), param->eobl), param->eobl, state->bi_buf, state->bi_valid); + PREFIX(flush_pending)(strm); + if (state->pending != 0) { + /* The remaining data is located in pending_out[0:pending]. If someone + * calls put_byte() - this might happen in deflate() - the byte will be + * placed into pending_buf[pending], which is incorrect. Move the + * remaining data to the beginning of pending_buf so that put_byte() is + * usable again. + */ + memmove(state->pending_buf, state->pending_out, state->pending); + state->pending_out = state->pending_buf; + } +#ifdef ZLIB_DEBUG + state->compressed_len += param->eobl; +#endif +} + +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->common.param; + uInt masked_avail_in; + dfltcc_cc cc; + int need_empty_block; + int soft_bcc; + int no_flush; + + if (!PREFIX(dfltcc_can_deflate)(strm)) { + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + return 0; + } + +again: + masked_avail_in = 0; + soft_bcc = 0; + no_flush = flush == Z_NO_FLUSH; + + /* No input data. Return, except when Continuation Flag is set, which means + * that DFLTCC has buffered some output in the parameter block and needs to + * be called again in order to flush it. + */ + if (strm->avail_in == 0 && !param->cf) { + /* A block is still open, and the hardware does not support closing + * blocks without adding data. Thus, close it manually. + */ + if (!no_flush && param->bcf) { + send_eobs(strm, param); + param->bcf = 0; + } + /* Let one of deflate_* functions write a trailing empty block. */ + if (flush == Z_FINISH) + return 0; + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + /* Trigger block post-processing if necessary. */ + *result = no_flush ? need_more : block_done; + return 1; + } + + /* There is an open non-BFINAL block, we are not going to close it just + * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see + * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new + * DHT in order to adapt to a possibly changed input data distribution. + */ + if (param->bcf && no_flush && + strm->total_in > dfltcc_state->block_threshold && + strm->avail_in >= dfltcc_state->dht_threshold) { + if (param->cf) { + /* We need to flush the DFLTCC buffer before writing the + * End-of-block Symbol. Mask the input data and proceed as usual. + */ + masked_avail_in += strm->avail_in; + strm->avail_in = 0; + no_flush = 0; + } else { + /* DFLTCC buffer is empty, so we can manually write the + * End-of-block Symbol right away. + */ + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } + } + + /* No space for compressed data. If we proceed, dfltcc_cmpr() will return + * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still + * set BCF=1, which is wrong. Avoid complications and return early. + */ + if (strm->avail_out == 0) { + *result = need_more; + return 1; + } + + /* The caller gave us too much data. Pass only one block worth of + * uncompressed data to DFLTCC and mask the rest, so that on the next + * iteration we start a new block. + */ + if (no_flush && strm->avail_in > dfltcc_state->block_size) { + masked_avail_in += (strm->avail_in - dfltcc_state->block_size); + strm->avail_in = dfltcc_state->block_size; + } + + /* When we have an open non-BFINAL deflate block and caller indicates that + * the stream is ending, we need to close an open deflate block and open a + * BFINAL one. + */ + need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; + + /* Translate stream to parameter block */ + param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; + if (!no_flush) + /* We need to close a block. Always do this in software - when there is + * no input data, the hardware will not honor BCC. */ + soft_bcc = 1; + if (flush == Z_FINISH && !param->bcf) + /* We are about to open a BFINAL block, set Block Header Final bit + * until the stream ends. + */ + param->bhf = 1; + /* DFLTCC-CMPR will write to next_out, so make sure that buffers with + * higher precedence are empty. + */ + Assert(state->pending == 0, "There must be no pending bytes"); + Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); + param->sbb = (unsigned int)state->bi_valid; + if (param->sbb > 0) + *strm->next_out = (unsigned char)state->bi_buf; + /* Honor history and check value */ + param->nt = 0; + if (state->wrap == 1) + param->cv = strm->adler; + else if (state->wrap == 2) + param->cv = ZSWAP32(state->crc_fold.value); + + /* When opening a block, choose a Huffman-Table Type */ + if (!param->bcf) { + if (state->strategy == Z_FIXED || (strm->total_in == 0 && dfltcc_state->block_threshold > 0)) + param->htt = HTT_FIXED; + else { + param->htt = HTT_DYNAMIC; + dfltcc_gdht(strm); + } + } + + /* Deflate */ + do { + cc = dfltcc_cmpr(strm); + if (strm->avail_in < 4096 && masked_avail_in > 0) + /* We are about to call DFLTCC with a small input buffer, which is + * inefficient. Since there is masked data, there will be at least + * one more DFLTCC call, so skip the current one and make the next + * one handle more data. + */ + break; + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc); + state->bi_valid = param->sbb; + if (state->bi_valid == 0) + state->bi_buf = 0; /* Avoid accessing next_out */ + else + state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); + if (state->wrap == 1) + strm->adler = param->cv; + else if (state->wrap == 2) + state->crc_fold.value = ZSWAP32(param->cv); + + /* Unmask the input data */ + strm->avail_in += masked_avail_in; + masked_avail_in = 0; + + /* If we encounter an error, it means there is a bug in DFLTCC call */ + Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); + + /* Update Block-Continuation Flag. It will be used to check whether to call + * GDHT the next time. + */ + if (cc == DFLTCC_CC_OK) { + if (soft_bcc) { + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } else + param->bcf = 1; + if (flush == Z_FINISH) { + if (need_empty_block) + /* Make the current deflate() call also close the stream */ + return 0; + else { + bi_windup(state); + *result = finish_done; + } + } else { + if (flush == Z_FULL_FLUSH) + param->hl = 0; /* Clear history */ + *result = flush == Z_NO_FLUSH ? need_more : block_done; + } + } else { + param->bcf = 1; + *result = need_more; + } + if (strm->avail_in != 0 && strm->avail_out != 0) + goto again; /* deflate() must use all input or all output */ + return 1; +} + +/* + Switching between hardware and software compression. + + DFLTCC does not support all zlib settings, e.g. generation of non-compressed + blocks or alternative window sizes. When such settings are applied on the + fly with deflateParams, we need to convert between hardware and software + window formats. +*/ +static int dfltcc_was_deflate_used(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return strm->total_in > 0 || param->nt == 0 || param->hl > 0; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush) { + deflate_state *state = (deflate_state *)strm->state; + int could_deflate = PREFIX(dfltcc_can_deflate)(strm); + int can_deflate = dfltcc_can_deflate_with_params(strm, level, state->w_bits, strategy, state->reproducible); + + if (can_deflate == could_deflate) + /* We continue to work in the same mode - no changes needed */ + return Z_OK; + + if (!dfltcc_was_deflate_used(strm)) + /* DFLTCC was not used yet - no changes needed */ + return Z_OK; + + /* For now, do not convert between window formats - simply get rid of the old data instead */ + *flush = Z_FULL_FLUSH; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might + * close the block without resetting the compression state. Detect this + * situation and return that deflation is not done. + */ + if (flush == Z_FULL_FLUSH && strm->avail_out == 0) + return 0; + + /* Return that deflation is not done if DFLTCC is used and either it + * buffered some data (Continuation Flag is set), or has not written EOBS + * yet (Block-Continuation Flag is set). + */ + return !PREFIX(dfltcc_can_deflate)(strm) || (!param->cf && !param->bcf); +} + +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + + return reproducible != state->reproducible && !dfltcc_was_deflate_used(strm); +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + append_history(param, state->window, dictionary, dict_length); + state->strstart = 1; /* Add FDICT to zlib header */ + state->block_start = state->strstart; /* Make deflate_stored happy */ + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt *dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.h b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.h new file mode 100644 index 000000000..cb261b156 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_deflate.h @@ -0,0 +1,60 @@ +#ifndef DFLTCC_DEFLATE_H +#define DFLTCC_DEFLATE_H + +#include "dfltcc_common.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src); +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result); +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush); +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush); +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible); +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_DEFLATE_STATE PREFIX(dfltcc_alloc_deflate_state) +#define ZCOPY_DEFLATE_STATE PREFIX(dfltcc_copy_deflate_state) + +#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_deflate_state) + +#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ + do { \ + int err; \ +\ + err = PREFIX(dfltcc_deflate_params)((strm), (level), (strategy), (hook_flush)); \ + if (err == Z_STREAM_ERROR) \ + return err; \ + } while (0) + +#define DEFLATE_DONE PREFIX(dfltcc_deflate_done) + +#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ + do { \ + if (deflateStateCheck((strm)) || PREFIX(dfltcc_can_deflate)((strm))) \ + (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ + } while (0) + +#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_HOOK PREFIX(dfltcc_deflate) + +#define DEFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_CAN_SET_REPRODUCIBLE PREFIX(dfltcc_can_set_reproducible) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_detail.h b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_detail.h new file mode 100644 index 000000000..354c2f555 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_detail.h @@ -0,0 +1,312 @@ +#include "../../zbuild.h" +#include + +#ifdef HAVE_SYS_SDT_H +#include +#endif + +/* + Tuning parameters. + */ +#ifndef DFLTCC_LEVEL_MASK +#define DFLTCC_LEVEL_MASK 0x2 +#endif +#ifndef DFLTCC_BLOCK_SIZE +#define DFLTCC_BLOCK_SIZE 1048576 +#endif +#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE +#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 +#endif +#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE +#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 +#endif +#ifndef DFLTCC_RIBM +#define DFLTCC_RIBM 0 +#endif + +/* + Parameter Block for Query Available Functions. + */ +#define static_assert(c, msg) __attribute__((unused)) static char static_assert_failed_ ## msg[c ? 1 : -1] + +struct dfltcc_qaf_param { + char fns[16]; + char reserved1[8]; + char fmts[2]; + char reserved2[6]; +}; + +#define DFLTCC_SIZEOF_QAF 32 +static_assert(sizeof(struct dfltcc_qaf_param) == DFLTCC_SIZEOF_QAF, qaf); + +static inline int is_bit_set(const char *bits, int n) { + return bits[n / 8] & (1 << (7 - (n % 8))); +} + +static inline void clear_bit(char *bits, int n) { + bits[n / 8] &= ~(1 << (7 - (n % 8))); +} + +#define DFLTCC_FACILITY 151 + +static inline int is_dfltcc_enabled(void) { + uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; + Z_REGISTER uint8_t r0 __asm__("r0"); + + memset(facilities, 0, sizeof(facilities)); + r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; + /* STFLE is supported since z9-109 and only in z/Architecture mode. When + * compiling with -m31, gcc defaults to ESA mode, however, since the kernel + * is 64-bit, it's always z/Architecture mode at runtime. + */ + __asm__ volatile( +#ifndef __clang__ + ".machinemode push\n" + ".machinemode zarch\n" +#endif + "stfle %[facilities]\n" +#ifndef __clang__ + ".machinemode pop\n" +#endif + : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc"); + return is_bit_set((const char *)facilities, DFLTCC_FACILITY); +} + +#define DFLTCC_FMT0 0 + +/* + Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. + */ +#define CVT_CRC32 0 +#define CVT_ADLER32 1 +#define HTT_FIXED 0 +#define HTT_DYNAMIC 1 + +struct dfltcc_param_v0 { + uint16_t pbvn; /* Parameter-Block-Version Number */ + uint8_t mvn; /* Model-Version Number */ + uint8_t ribm; /* Reserved for IBM use */ + uint32_t reserved32 : 31; + uint32_t cf : 1; /* Continuation Flag */ + uint8_t reserved64[8]; + uint32_t nt : 1; /* New Task */ + uint32_t reserved129 : 1; + uint32_t cvt : 1; /* Check Value Type */ + uint32_t reserved131 : 1; + uint32_t htt : 1; /* Huffman-Table Type */ + uint32_t bcf : 1; /* Block-Continuation Flag */ + uint32_t bcc : 1; /* Block Closing Control */ + uint32_t bhf : 1; /* Block Header Final */ + uint32_t reserved136 : 1; + uint32_t reserved137 : 1; + uint32_t dhtgc : 1; /* DHT Generation Control */ + uint32_t reserved139 : 5; + uint32_t reserved144 : 5; + uint32_t sbb : 3; /* Sub-Byte Boundary */ + uint8_t oesc; /* Operation-Ending-Supplemental Code */ + uint32_t reserved160 : 12; + uint32_t ifs : 4; /* Incomplete-Function Status */ + uint16_t ifl; /* Incomplete-Function Length */ + uint8_t reserved192[8]; + uint8_t reserved256[8]; + uint8_t reserved320[4]; + uint16_t hl; /* History Length */ + uint32_t reserved368 : 1; + uint16_t ho : 15; /* History Offset */ + uint32_t cv; /* Check Value */ + uint32_t eobs : 15; /* End-of-block Symbol */ + uint32_t reserved431: 1; + uint8_t eobl : 4; /* End-of-block Length */ + uint32_t reserved436 : 12; + uint32_t reserved448 : 4; + uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table + Length */ + uint8_t reserved464[6]; + uint8_t cdht[288]; /* Compressed-Dynamic-Huffman Table */ + uint8_t reserved[24]; + uint8_t ribm2[8]; /* Reserved for IBM use */ + uint8_t csb[1152]; /* Continuation-State Buffer */ +}; + +#define DFLTCC_SIZEOF_GDHT_V0 384 +#define DFLTCC_SIZEOF_CMPR_XPND_V0 1536 +static_assert(offsetof(struct dfltcc_param_v0, csb) == DFLTCC_SIZEOF_GDHT_V0, gdht_v0); +static_assert(sizeof(struct dfltcc_param_v0) == DFLTCC_SIZEOF_CMPR_XPND_V0, cmpr_xpnd_v0); + +static inline z_const char *oesc_msg(char *buf, int oesc) { + if (oesc == 0x00) + return NULL; /* Successful completion */ + else { + sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); + return buf; + } +} + +/* + C wrapper for the DEFLATE CONVERSION CALL instruction. + */ +typedef enum { + DFLTCC_CC_OK = 0, + DFLTCC_CC_OP1_TOO_SHORT = 1, + DFLTCC_CC_OP2_TOO_SHORT = 2, + DFLTCC_CC_OP2_CORRUPT = 2, + DFLTCC_CC_AGAIN = 3, +} dfltcc_cc; + +#define DFLTCC_QAF 0 +#define DFLTCC_GDHT 1 +#define DFLTCC_CMPR 2 +#define DFLTCC_XPND 4 +#define HBT_CIRCULAR (1 << 7) +#define DFLTCC_FN_MASK ((1 << 7) - 1) +#define HB_BITS 15 +#define HB_SIZE (1 << HB_BITS) + +static inline dfltcc_cc dfltcc(int fn, void *param, + unsigned char **op1, size_t *len1, + z_const unsigned char **op2, size_t *len2, void *hist) { + unsigned char *t2 = op1 ? *op1 : NULL; +#ifdef Z_MEMORY_SANITIZER + unsigned char *orig_t2 = t2; +#endif + size_t t3 = len1 ? *len1 : 0; + z_const unsigned char *t4 = op2 ? *op2 : NULL; + size_t t5 = len2 ? *len2 : 0; + Z_REGISTER int r0 __asm__("r0") = fn; + Z_REGISTER void *r1 __asm__("r1") = param; + Z_REGISTER unsigned char *r2 __asm__("r2") = t2; + Z_REGISTER size_t r3 __asm__("r3") = t3; + Z_REGISTER z_const unsigned char *r4 __asm__("r4") = t4; + Z_REGISTER size_t r5 __asm__("r5") = t5; + int cc; + + __asm__ volatile( +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_entry, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_exit, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + "ipm %[cc]\n" + : [r2] "+r" (r2) + , [r3] "+r" (r3) + , [r4] "+r" (r4) + , [r5] "+r" (r5) + , [cc] "=r" (cc) + : [r0] "r" (r0) + , [r1] "r" (r1) + , [hist] "r" (hist) +#ifdef HAVE_SYS_SDT_H + , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist) +#endif + : "cc", "memory"); + t2 = r2; t3 = r3; t4 = r4; t5 = r5; + +#ifdef Z_MEMORY_SANITIZER + switch (fn & DFLTCC_FN_MASK) { + case DFLTCC_QAF: + __msan_unpoison(param, DFLTCC_SIZEOF_QAF); + break; + case DFLTCC_GDHT: + __msan_unpoison(param, DFLTCC_SIZEOF_GDHT_V0); + break; + case DFLTCC_CMPR: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2 + (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1)); + break; + case DFLTCC_XPND: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2); + break; + } +#endif + + if (op1) + *op1 = t2; + if (len1) + *len1 = t3; + if (op2) + *op2 = t4; + if (len2) + *len2 = t5; + return (cc >> 28) & 3; +} + +/* + Extension of inflate_state and deflate_state. Must be doubleword-aligned. +*/ +struct dfltcc_state { + struct dfltcc_param_v0 param; /* Parameter block. */ + struct dfltcc_qaf_param af; /* Available functions. */ + char msg[64]; /* Buffer for strm->msg */ +}; + +#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1)) + +#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8))) + +static inline void *dfltcc_alloc_state(PREFIX3(streamp) strm, uInt size, uInt extension_size) { + return ZALLOC(strm, 1, ALIGN_UP(size, 8) + extension_size); +} + +static inline void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) { + /* Initialize available functions */ + if (is_dfltcc_enabled()) { + dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL); + memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af)); + } else + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + + /* Initialize parameter block */ + memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); + dfltcc_state->param.nt = 1; + dfltcc_state->param.ribm = DFLTCC_RIBM; +} + +static inline void dfltcc_copy_state(void *dst, const void *src, uInt size, uInt extension_size) { + memcpy(dst, src, ALIGN_UP(size, 8) + extension_size); +} + +static inline void append_history(struct dfltcc_param_v0 *param, unsigned char *history, + const unsigned char *buf, uInt count) { + size_t offset; + size_t n; + + /* Do not use more than 32K */ + if (count > HB_SIZE) { + buf += count - HB_SIZE; + count = HB_SIZE; + } + offset = (param->ho + param->hl) % HB_SIZE; + if (offset + count <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(history + offset, buf, count); + else { + /* Circular history buffer wraps - copy two chunks */ + n = HB_SIZE - offset; + memcpy(history + offset, buf, n); + memcpy(history, buf + n, count - n); + } + n = param->hl + count; + if (n <= HB_SIZE) + /* All history fits into buffer - no need to discard anything */ + param->hl = n; + else { + /* History does not fit into buffer - discard extra bytes */ + param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE; + param->hl = HB_SIZE; + } +} + +static inline void get_history(struct dfltcc_param_v0 *param, const unsigned char *history, + unsigned char *buf) { + if (param->ho + param->hl <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(buf, history + param->ho, param->hl); + else { + /* Circular history buffer wraps - copy two chunks */ + memcpy(buf, history + param->ho, HB_SIZE - param->ho); + memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE); + } +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.c b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.c new file mode 100644 index 000000000..f0d3951b5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.c @@ -0,0 +1,205 @@ +/* dfltcc_inflate.c - IBM Z DEFLATE CONVERSION CALL decompression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC decompression support: + + $ ./configure --with-dfltcc-inflate + or + + $ cmake -DWITH_DFLTCC_INFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "dfltcc_inflate.h" +#include "dfltcc_detail.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm) { + return (struct inflate_state *)dfltcc_alloc_state(strm, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + dfltcc_reset_state(dfltcc_state); +} + +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src) { + dfltcc_copy_state(dst, src, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + /* Unsupported hardware */ + return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); +} + +static inline dfltcc_cc dfltcc_xpnd(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + dfltcc_cc cc; + + if (flush == Z_BLOCK || flush == Z_TREES) { + /* DFLTCC does not support stopping on block boundaries */ + if (PREFIX(dfltcc_inflate_disable)(strm)) { + *ret = Z_STREAM_ERROR; + return DFLTCC_INFLATE_BREAK; + } else + return DFLTCC_INFLATE_SOFTWARE; + } + + if (state->last) { + if (state->bits != 0) { + strm->next_in++; + strm->avail_in--; + state->bits = 0; + } + state->mode = CHECK; + return DFLTCC_INFLATE_CONTINUE; + } + + if (strm->avail_in == 0 && !param->cf) + return DFLTCC_INFLATE_BREAK; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return DFLTCC_INFLATE_CONTINUE; + } + + /* Translate stream to parameter block */ + param->cvt = ((state->wrap & 4) && state->flags) ? CVT_CRC32 : CVT_ADLER32; + param->sbb = state->bits; + if (param->hl) + param->nt = 0; /* Honor history for the first block */ + if (state->wrap & 4) + param->cv = state->flags ? ZSWAP32(state->check) : state->check; + + /* Inflate */ + do { + cc = dfltcc_xpnd(strm); + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); + state->last = cc == DFLTCC_CC_OK; + state->bits = param->sbb; + if (state->wrap & 4) + strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv; + if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { + /* Report an error if stream is corrupted */ + state->mode = BAD; + return DFLTCC_INFLATE_CONTINUE; + } + state->mode = TYPEDO; + /* Break if operands are exhausted, otherwise continue looping */ + return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? + DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; +} + +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return !param->nt; +} + +/* + Rotates a circular buffer. + The implementation is based on https://cplusplus.com/reference/algorithm/rotate/ + */ +static void rotate(unsigned char *start, unsigned char *pivot, unsigned char *end) { + unsigned char *p = pivot; + unsigned char tmp; + + while (p != start) { + tmp = *start; + *start = *p; + *p = tmp; + + start++; + p++; + + if (p == end) + p = pivot; + else if (start == pivot) + pivot = p; + } +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (!PREFIX(dfltcc_can_inflate)(strm)) + return 0; + if (PREFIX(dfltcc_was_inflate_used)(strm)) + /* DFLTCC has already decompressed some data. Since there is not + * enough information to resume decompression in software, the call + * must fail. + */ + return 1; + /* DFLTCC was not used yet - decompress in software */ + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + /* Convert the window from the hardware to the software format */ + rotate(state->window, state->window + param->ho, state->window + HB_SIZE); + state->whave = state->wnext = MIN(param->hl, state->wsize); + return 0; +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + + append_history(param, state->window, dictionary, dict_length); + state->havedict = 1; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt *dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary && state->window) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.h b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.h new file mode 100644 index 000000000..632fada62 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/dfltcc_inflate.h @@ -0,0 +1,70 @@ +#ifndef DFLTCC_INFLATE_H +#define DFLTCC_INFLATE_H + +#include "dfltcc_common.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src); +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm); +typedef enum { + DFLTCC_INFLATE_CONTINUE, + DFLTCC_INFLATE_BREAK, + DFLTCC_INFLATE_SOFTWARE, +} dfltcc_inflate_action; +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret); +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_INFLATE_STATE PREFIX(dfltcc_alloc_inflate_state) +#define ZCOPY_INFLATE_STATE PREFIX(dfltcc_copy_inflate_state) + +#define INFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_inflate_state) + +#define INFLATE_PRIME_HOOK(strm, bits, value) \ + do { if (PREFIX(dfltcc_inflate_disable)((strm))) return Z_STREAM_ERROR; } while (0) + +#define INFLATE_TYPEDO_HOOK(strm, flush) \ + if (PREFIX(dfltcc_can_inflate)((strm))) { \ + dfltcc_inflate_action action; \ +\ + RESTORE(); \ + action = PREFIX(dfltcc_inflate)((strm), (flush), &ret); \ + LOAD(); \ + if (action == DFLTCC_INFLATE_CONTINUE) \ + break; \ + else if (action == DFLTCC_INFLATE_BREAK) \ + goto inf_leave; \ + } + +#define INFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_NEED_UPDATEWINDOW(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_MARK_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return -(1L << 16); \ + } while (0) + +#define INFLATE_SYNC_POINT_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return Z_STREAM_ERROR; \ + } while (0) + +#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.c b/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.c new file mode 100644 index 000000000..82901060e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.c @@ -0,0 +1,14 @@ +#include "../../zbuild.h" +#include "s390_features.h" + +#ifdef HAVE_SYS_AUXV_H +# include +#endif + +#ifndef HWCAP_S390_VXRS +#define HWCAP_S390_VXRS HWCAP_S390_VX +#endif + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features) { + features->has_vx = getauxval(AT_HWCAP) & HWCAP_S390_VXRS; +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.h b/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.h new file mode 100644 index 000000000..b8ffef74d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/s390_features.h @@ -0,0 +1,10 @@ +#ifndef S390_FEATURES_H_ +#define S390_FEATURES_H_ + +struct s390_cpu_features { + int has_vx; +}; + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.Dockerfile b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.Dockerfile new file mode 100644 index 000000000..136eec77a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.Dockerfile @@ -0,0 +1,45 @@ +# Self-Hosted IBM Z Github Actions Runner. + +# Temporary image: amd64 dependencies. +FROM amd64/ubuntu:20.04 as ld-prefix +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install ca-certificates libicu66 libssl1.1 + +# Main image. +FROM s390x/ubuntu:20.04 + +# Packages for zlib-ng testing. +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install \ + clang-11 \ + cmake \ + curl \ + gcc \ + git \ + jq \ + libxml2-dev \ + libxslt-dev \ + llvm-11-tools \ + ninja-build \ + python-is-python3 \ + python3 \ + python3-dev \ + python3-pip + +# amd64 dependencies. +COPY --from=ld-prefix / /usr/x86_64-linux-gnu/ +RUN ln -fs ../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /usr/x86_64-linux-gnu/lib64/ +RUN ln -fs /etc/resolv.conf /usr/x86_64-linux-gnu/etc/ +ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu + +# amd64 Github Actions Runner. +RUN useradd -m actions-runner +USER actions-runner +WORKDIR /home/actions-runner +RUN curl -L https://github.com/actions/runner/releases/download/v2.287.1/actions-runner-linux-x64-2.287.1.tar.gz | tar -xz +VOLUME /home/actions-runner + +# Scripts. +COPY fs/ / +ENTRYPOINT ["/usr/bin/entrypoint"] +CMD ["/usr/bin/actions-runner"] diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.service b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.service new file mode 100644 index 000000000..71053a79d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/actions-runner.service @@ -0,0 +1,24 @@ +[Unit] +Description=Self-Hosted IBM Z Github Actions Runner +Wants=qemu-user-static +After=qemu-user-static +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +ExecStartPre=-/usr/bin/docker rm --force actions-runner +ExecStart=/usr/bin/docker run \ + --env-file=/etc/actions-runner \ + --init \ + --interactive \ + --name=actions-runner \ + --rm \ + --volume=actions-runner:/home/actions-runner \ + iiilinuxibmcom/actions-runner +ExecStop=/bin/sh -c "docker exec actions-runner kill -INT -- -1" +ExecStop=/bin/sh -c "docker wait actions-runner" +ExecStop=/bin/sh -c "docker rm actions-runner" + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner new file mode 100755 index 000000000..c9d8227d4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Ephemeral runner startup script. +# +# Expects the following environment variables: +# +# - repo=/ +# - access_token= +# + +set -e -u + +# Check the cached registration token. +token_file=registration-token.json +set +e +expires_at=$(jq --raw-output .expires_at "$token_file" 2>/dev/null) +status=$? +set -e +if [[ $status -ne 0 || $(date +%s) -ge $(date -d "$expires_at" +%s) ]]; then + # Refresh the cached registration token. + curl \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $access_token" \ + "https://api.github.com/repos/$repo/actions/runners/registration-token" \ + -o "$token_file" +fi + +# (Re-)register the runner. +registration_token=$(jq --raw-output .token "$token_file") +./config.sh remove --token "$registration_token" || true +./config.sh \ + --url "https://github.com/$repo" \ + --token "$registration_token" \ + --labels z15 \ + --ephemeral + +# Run one job. +./run.sh diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint new file mode 100755 index 000000000..eb8772bec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint @@ -0,0 +1,30 @@ +#!/bin/bash + +# +# Container entrypoint that waits for all spawned processes. +# + +set -e -u + +# Create a FIFO and start reading from its read end. +tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX") +trap 'rm -r "$tempdir"' EXIT +done="$tempdir/pipe" +mkfifo "$done" +cat "$done" & waiter=$! + +# Start the workload. Its descendants will inherit the FIFO's write end. +status=0 +if [ "$#" -eq 0 ]; then + bash 9>"$done" || status=$? +else + "$@" 9>"$done" || status=$? +fi + +# When the workload and all of its descendants exit, the FIFO's write end will +# be closed and `cat "$done"` will exit. Wait until it happens. This is needed +# in order to handle SelfUpdater, which the workload may start in background +# before exiting. +wait "$waiter" + +exit "$status" diff --git a/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/qemu-user-static.service b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/qemu-user-static.service new file mode 100644 index 000000000..301f3edd9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/s390/self-hosted-builder/qemu-user-static.service @@ -0,0 +1,11 @@ +[Unit] +Description=Support for transparent execution of non-native binaries with QEMU user emulation + +[Service] +Type=oneshot +# The source code for iiilinuxibmcom/qemu-user-static is at https://github.com/iii-i/qemu-user-static/tree/v6.1.0-1 +# TODO: replace it with multiarch/qemu-user-static once version >6.1 is available +ExecStart=/usr/bin/docker run --rm --interactive --privileged iiilinuxibmcom/qemu-user-static --reset -p yes + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/Makefile.in b/internal-complibs/zlib-ng-2.1.2/arch/x86/Makefile.in new file mode 100644 index 000000000..7c052469b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/Makefile.in @@ -0,0 +1,147 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +AVX512FLAG=-mavx512f -mavx512dq -mavx512vl -mavx512bw +AVX512VNNIFLAG=-mavx512vnni +AVX2FLAG=-mavx2 +SSE2FLAG=-msse2 +SSSE3FLAG=-mssse3 +SSE42FLAG=-msse4.2 +PCLMULFLAG=-mpclmul +VPCLMULFLAG=-mvpclmulqdq +XSAVEFLAG=-mxsave +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + x86_features.o x86_features.lo \ + adler32_avx2.o adler32_avx2.lo \ + adler32_avx512.o adler32_avx512.lo \ + adler32_avx512_vnni.o adler32_avx512_vnni.lo \ + adler32_sse42.o adler32_sse42.lo \ + adler32_ssse3.o adler32_ssse3.lo \ + chunkset_avx2.o chunkset_avx2.lo \ + chunkset_sse2.o chunkset_sse2.lo \ + chunkset_ssse3.o chunkset_ssse3.lo \ + compare256_avx2.o compare256_avx2.lo \ + compare256_sse2.o compare256_sse2.lo \ + insert_string_sse42.o insert_string_sse42.lo \ + crc32_pclmulqdq.o crc32_pclmulqdq.lo \ + crc32_vpclmulqdq.o crc32_vpclmulqdq.lo \ + slide_hash_avx2.o slide_hash_avx2.lo \ + slide_hash_sse2.o slide_hash_sse2.lo + +x86_features.o: + $(CC) $(CFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +x86_features.lo: + $(CC) $(SFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +chunkset_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_ssse3.o: + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +chunkset_ssse3.lo: + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +compare256_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +compare256_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +insert_string_sse42.o: + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +insert_string_sse42.lo: + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +crc32_pclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_pclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_vpclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +crc32_vpclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +slide_hash_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +slide_hash_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +adler32_avx2.o: $(SRCDIR)/adler32_avx2.c + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx2.lo: $(SRCDIR)/adler32_avx2.c + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx512.o: $(SRCDIR)/adler32_avx512.c + $(CC) $(CFLAGS) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512.lo: $(SRCDIR)/adler32_avx512.c + $(CC) $(SFLAGS) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512_vnni.o: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(CFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_avx512_vnni.lo: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(SFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_ssse3.o: $(SRCDIR)/adler32_ssse3.c + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_ssse3.lo: $(SRCDIR)/adler32_ssse3.c + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_sse42.o: $(SRCDIR)/adler32_sse42.c + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +adler32_sse42.lo: $(SRCDIR)/adler32_sse42.c + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: clean + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2.c new file mode 100644 index 000000000..797d299e0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2.c @@ -0,0 +1,17 @@ +/* adler32_avx2.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#ifdef X86_AVX2 + +#include "adler32_avx2_tpl.h" + +#define COPY +#include "adler32_avx2_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_p.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_p.h new file mode 100644 index 000000000..f0f8a4a88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_p.h @@ -0,0 +1,32 @@ +/* adler32_avx2_p.h -- adler32 avx2 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_AVX2_P_H_ +#define ADLER32_AVX2_P_H_ + +#if defined(X86_AVX2) || defined(X86_AVX512VNNI) + +/* 32 bit horizontal sum, adapted from Agner Fog's vector library. */ +static inline uint32_t hsum256(__m256i x) { + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(x, 1), + _mm256_castsi256_si128(x)); + __m128i sum2 = _mm_add_epi32(sum1, _mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +static inline uint32_t partial_hsum256(__m256i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros */ + const __m256i perm_vec = _mm256_setr_epi32(0, 2, 4, 6, 1, 1, 1, 1); + __m256i non_zero = _mm256_permutevar8x32_epi32(x, perm_vec); + __m128i non_zero_sse = _mm256_castsi256_si128(non_zero); + __m128i sum2 = _mm_add_epi32(non_zero_sse,_mm_unpackhi_epi64(non_zero_sse, non_zero_sse)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_tpl.h new file mode 100644 index 000000000..a94f44b4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx2_tpl.h @@ -0,0 +1,141 @@ +/* adler32_avx2_tpl.h -- adler32 avx2 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include +#include "../../adler32_fold.h" +#include "../../adler32_p.h" +#include "../../fallback_builtins.h" +#include "adler32_avx2_p.h" + +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *src, size_t len); + +#define copy_sub32(a, b, c, d) adler32_fold_copy_sse42(a, b, c, d) +#define sub32(a, b, c) adler32_ssse3(a, b, c) +#else +#define copy_sub32(a, b, c, d) adler32_copy_len_16(adler0, c, b, d, adler1) +#define sub32(a, b, c) adler32_len_16(adler0, b, c, adler1) +#endif + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx2(uint32_t adler, const uint8_t *src, size_t len) { +#endif + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { +#ifdef COPY + return adler32_copy_len_16(adler0, src, dst, len, adler1); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } else if (len < 32) { +#ifdef COPY + return copy_sub32(adler, dst, src, len); +#else + return sub32(adler, src, len); +#endif + } + + __m256i vs1, vs2; + + const __m256i dot2v = _mm256_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m256i dot3v = _mm256_set1_epi16(1); + const __m256i zero = _mm256_setzero_si256(); + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 32 vs1 + sum( (32-i+1) c[i] ) + */ + __m256i vbuf = _mm256_loadu_si256((__m256i*)src); + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf, zero); // Sum of abs diff, resulting in 2 x int32's + // +#ifdef COPY + _mm256_storeu_si256((__m256i*)dst, vbuf); + dst += 32; +#endif + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + __m256i v_short_sum2 = _mm256_maddubs_epi16(vbuf, dot2v); // sum 32 uint8s to 16 shorts + __m256i vsum2 = _mm256_madd_epi16(v_short_sum2, dot3v); // sum 16 shorts to 8 uint32s + vs2 = _mm256_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + /* Defer the multiplication with 32 to outside of the loop */ + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + + /* The compiler is generating the following sequence for this integer modulus + * when done the scalar way, in GPRs: + + adler = (s1_unpack[0] % BASE) + (s1_unpack[1] % BASE) + (s1_unpack[2] % BASE) + (s1_unpack[3] % BASE) + + (s1_unpack[4] % BASE) + (s1_unpack[5] % BASE) + (s1_unpack[6] % BASE) + (s1_unpack[7] % BASE); + + mov $0x80078071,%edi // move magic constant into 32 bit register %edi + ... + vmovd %xmm1,%esi // move vector lane 0 to 32 bit register %esi + mov %rsi,%rax // zero-extend this value to 64 bit precision in %rax + imul %rdi,%rsi // do a signed multiplication with magic constant and vector element + shr $0x2f,%rsi // shift right by 47 + imul $0xfff1,%esi,%esi // do a signed multiplication with value truncated to 32 bits with 0xfff1 + sub %esi,%eax // subtract lower 32 bits of original vector value from modified one above + ... + // repeats for each element with vpextract instructions + + This is tricky with AVX2 for a number of reasons: + 1.) There's no 64 bit multiplication instruction, but there is a sequence to get there + 2.) There's ways to extend vectors to 64 bit precision, but no simple way to truncate + back down to 32 bit precision later (there is in AVX512) + 3.) Full width integer multiplications aren't cheap + + We can, however, and do a relatively cheap sequence for horizontal sums. + Then, we simply do the integer modulus on the resulting 64 bit GPR, on a scalar value. It was + previously thought that casting to 64 bit precision was needed prior to the horizontal sum, but + that is simply not the case, as NMAX is defined as the maximum number of scalar sums that can be + performed on the maximum possible inputs before overflow + */ + + + /* In AVX2-land, this trip through GPRs will probably be unvoidable, as there's no cheap and easy + * conversion from 64 bit integer to 32 bit (needed for the inexpensive modulus with a constant). + * This casting to 32 bit is cheap through GPRs (just register aliasing). See above for exactly + * what the compiler is doing to avoid integer divisions. */ + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + if (len) { + goto rem_peel; + } + + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512.c new file mode 100644 index 000000000..e6ebb05dc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512.c @@ -0,0 +1,16 @@ +/* adler32_avx512.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512 + +#include "adler32_avx512_tpl.h" + +#define COPY +#include "adler32_avx512_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_p.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_p.h new file mode 100644 index 000000000..5b79d2ab6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_p.h @@ -0,0 +1,46 @@ +#ifndef AVX512_FUNCS_H +#define AVX512_FUNCS_H + +#include +#include +/* Written because *_add_epi32(a) sets off ubsan */ +static inline uint32_t _mm512_reduce_add_epu32(__m512i x) { + __m256i a = _mm512_extracti64x4_epi64(x, 1); + __m256i b = _mm512_extracti64x4_epi64(x, 0); + + __m256i a_plus_b = _mm256_add_epi32(a, b); + __m128i c = _mm256_extracti128_si256(a_plus_b, 1); + __m128i d = _mm256_extracti128_si256(a_plus_b, 0); + __m128i c_plus_d = _mm_add_epi32(c, d); + + __m128i sum1 = _mm_unpackhi_epi64(c_plus_d, c_plus_d); + __m128i sum2 = _mm_add_epi32(sum1, c_plus_d); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + + return _mm_cvtsi128_si32(sum4); +} + +static inline uint32_t partial_hsum(__m512i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros. Marking this const so the compiler stands + * a better chance of keeping this resident in a register through entire + * loop execution. We certainly have enough zmm registers (32) */ + const __m512i perm_vec = _mm512_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14, + 1, 1, 1, 1, 1, 1, 1, 1); + + __m512i non_zero = _mm512_permutexvar_epi32(perm_vec, x); + + /* From here, it's a simple 256 bit wide reduction sum */ + __m256i non_zero_avx = _mm512_castsi512_si256(non_zero); + + /* See Agner Fog's vectorclass for a decent reference. Essentially, phadd is + * pretty slow, much slower than the longer instruction sequence below */ + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(non_zero_avx, 1), + _mm256_castsi256_si128(non_zero_avx)); + __m128i sum2 = _mm_add_epi32(sum1,_mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2,_mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_tpl.h new file mode 100644 index 000000000..7546afef5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_tpl.h @@ -0,0 +1,106 @@ +/* adler32_avx512_tpl.h -- adler32 avx512 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "adler32_avx512_p.h" + +#ifdef X86_AVX512 + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx512(uint32_t adler, const uint8_t *src, size_t len) { +#endif + + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 64) { + /* This handles the remaining copies, just call normal adler checksum after this */ +#ifdef COPY + __mmask64 storemask = (0xFFFFFFFFFFFFFFFFUL >> (64 - len)); + __m512i copy_vec = _mm512_maskz_loadu_epi8(storemask, src); + _mm512_mask_storeu_epi8(dst, storemask, copy_vec); +#endif + +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + __m512i vbuf, vs1_0, vs3; + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + const __m512i dot3v = _mm512_set1_epi16(1); + const __m512i zero = _mm512_setzero_si512(); + size_t k; + + while (len >= 64) { + __m512i vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + __m512i vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + vs1_0 = vs1; + vs3 = _mm512_setzero_si512(); + + k = MIN(len, NMAX); + k -= k % 64; + len -= k; + + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf = _mm512_loadu_si512(src); +#ifdef COPY + _mm512_storeu_si512(dst, vbuf); + dst += 64; +#endif + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf, zero); + __m512i v_short_sum2 = _mm512_maddubs_epi16(vbuf, dot2v); + vs1 = _mm512_add_epi32(vs1_sad, vs1); + vs3 = _mm512_add_epi32(vs3, vs1_0); + __m512i vsum2 = _mm512_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm512_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_vnni.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_vnni.c new file mode 100644 index 000000000..8dcc93d05 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_avx512_vnni.c @@ -0,0 +1,225 @@ +/* adler32_avx512_vnni.c -- compute the Adler-32 checksum of a data stream + * Based on Brian Bockelman's AVX2 version + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512VNNI + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "../../adler32_fold.h" +#include "adler32_avx512_p.h" +#include "adler32_avx2_p.h" + +Z_INTERNAL uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 32) +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + if (len < 64) +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + + const __m512i zero = _mm512_setzero_si512(); + __m512i vs1, vs2; + + while (len >= 64) { + vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 64; + len -= k; + __m512i vs1_0 = vs1; + __m512i vs3 = _mm512_setzero_si512(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m512i vs2_1 = _mm512_setzero_si512(); + __m512i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 128) { + vbuf1 = _mm512_loadu_si512((__m512i*)src); + + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + vs2 = _mm512_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 128) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm512_loadu_si512((__m512i*)src); + vbuf1 = _mm512_loadu_si512((__m512i*)(src + 64)); + src += 128; + k -= 128; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf0, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm512_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm512_add_epi32(vs3, vs1); + vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs2_1 = _mm512_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + vs2 = _mm512_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +Z_INTERNAL uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel_copy: + if (len < 32) { + /* This handles the remaining copies, just call normal adler checksum after this */ + __mmask32 storemask = (0xFFFFFFFFUL >> (32 - len)); + __m256i copy_vec = _mm256_maskz_loadu_epi8(storemask, src); + _mm256_mask_storeu_epi8(dst, storemask, copy_vec); + +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + const __m256i dot2v = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); + + const __m256i zero = _mm256_setzero_si256(); + __m256i vs1, vs2; + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m256i vs2_1 = _mm256_setzero_si256(); + __m256i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 64) { + vbuf1 = _mm256_loadu_si256((__m256i*)src); + _mm256_storeu_si256((__m256i*)dst, vbuf1); + dst += 32; + + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + vs2 = _mm256_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm256_loadu_si256((__m256i*)src); + vbuf1 = _mm256_loadu_si256((__m256i*)(src + 32)); + _mm256_storeu_si256((__m256i*)dst, vbuf0); + _mm256_storeu_si256((__m256i*)(dst + 32), vbuf1); + dst += 64; + src += 64; + k -= 64; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf0, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm256_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm256_add_epi32(vs3, vs1); + vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs2_1 = _mm256_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + vs2 = _mm256_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel_copy; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_sse42.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_sse42.c new file mode 100644 index 000000000..257a36098 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_sse42.c @@ -0,0 +1,121 @@ +/* adler32_sse42.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "adler32_ssse3_p.h" +#include + +#ifdef X86_SSE42 + +Z_INTERNAL uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { + return adler32_copy_len_16(adler0, src, dst, len, adler1); + } + + __m128i vbuf, vbuf_0; + __m128i vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + v_sad_sum2, vsum2, vsum2_0; + __m128i zero = _mm_setzero_si128(); + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + size_t k; + + while (len >= 16) { + + k = MIN(len, NMAX); + k -= k % 16; + len -= k; + + vs1 = _mm_cvtsi32_si128(adler0); + vs2 = _mm_cvtsi32_si128(adler1); + + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + vbuf_0 = _mm_loadu_si128((__m128i*)(src + 16)); + src += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + _mm_storeu_si128((__m128i*)dst, vbuf); + _mm_storeu_si128((__m128i*)(dst + 16), vbuf_0); + dst += 32; + + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + vs2 = _mm_add_epi32(vsum2, vs2); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + src += 16; + k -= 16; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + + _mm_storeu_si128((__m128i*)dst, vbuf); + dst += 16; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = hsum(vs2) % BASE; + } + + /* If this is true, there's fewer than 16 elements remaining */ + if (len) { + goto rem_peel; + } + + return adler0 | (adler1 << 16); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3.c new file mode 100644 index 000000000..99ce79582 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3.c @@ -0,0 +1,156 @@ +/* adler32_ssse3.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "adler32_ssse3_p.h" + +#ifdef X86_SSSE3 + +#include + +Z_INTERNAL uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + const __m128i zero = _mm_setzero_si128(); + + __m128i vbuf, vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + vbuf_0, v_sad_sum2, vsum2, vsum2_0; + + /* If our buffer is unaligned (likely), make the determination whether + * or not there's enough of a buffer to consume to make the scalar, aligning + * additions worthwhile or if it's worth it to just eat the cost of an unaligned + * load. This is a pretty simple test, just test if 16 - the remainder + len is + * < 16 */ + size_t max_iters = NMAX; + size_t rem = (uintptr_t)buf & 15; + size_t align_offset = 16 - rem; + size_t k = 0; + if (rem) { + if (len < 16 + align_offset) { + /* Let's eat the cost of this one unaligned load so that + * we don't completely skip over the vectorization. Doing + * 16 bytes at a time unaligned is is better than 16 + <= 15 + * sums */ + vbuf = _mm_loadu_si128((__m128i*)buf); + len -= 16; + buf += 16; + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs1_0 = vs1; + goto unaligned_jmp; + } + + for (size_t i = 0; i < align_offset; ++i) { + adler += *(buf++); + sum2 += adler; + } + + /* lop off the max number of sums based on the scalar sums done + * above */ + len -= align_offset; + max_iters -= align_offset; + } + + + while (len >= 16) { + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + k = (len < max_iters ? len : max_iters); + k -= k % 16; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + vbuf_0 = _mm_load_si128((__m128i*)(buf + 16)); + buf += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + vs2 = _mm_add_epi32(vsum2, vs2); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + buf += 16; + k -= 16; + +unaligned_jmp: + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + /* We don't actually need to do a full horizontal sum, since psadbw is actually doing + * a partial reduction sum implicitly and only summing to integers in vector positions + * 0 and 2. This saves us some contention on the shuffle port(s) */ + adler = partial_hsum(vs1) % BASE; + sum2 = hsum(vs2) % BASE; + max_iters = NMAX; + } + + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3_p.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3_p.h new file mode 100644 index 000000000..d7ec3fe0d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/adler32_ssse3_p.h @@ -0,0 +1,29 @@ +/* adler32_ssse3_p.h -- adler32 ssse3 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_SSSE3_P_H_ +#define ADLER32_SSSE3_P_H_ + +#ifdef X86_SSSE3 + +#include +#include + +static inline uint32_t partial_hsum(__m128i x) { + __m128i second_int = _mm_srli_si128(x, 8); + __m128i sum = _mm_add_epi32(x, second_int); + return _mm_cvtsi128_si32(sum); +} + +static inline uint32_t hsum(__m128i x) { + __m128i sum1 = _mm_unpackhi_epi64(x, x); + __m128i sum2 = _mm_add_epi32(x, sum1); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + return _mm_cvtsi128_si32(sum4); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_avx2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_avx2.c new file mode 100644 index 000000000..f309878b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_avx2.c @@ -0,0 +1,135 @@ +/* chunkset_avx2.c -- AVX2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" + +#ifdef X86_AVX2 +#include +#include "../generic/chunk_permute_table.h" + +typedef __m256i chunk_t; + +#define CHUNK_SIZE 32 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +/* Populate don't cares so that this is a direct lookup (with some indirection into the permute table), because dist can + * never be 0 - 2, we'll start with an offset, subtracting 3 from the input */ +static const lut_rem_pair perm_idx_lut[29] = { + { 0, 2}, /* 3 */ + { 0, 0}, /* don't care */ + { 1 * 32, 2}, /* 5 */ + { 2 * 32, 2}, /* 6 */ + { 3 * 32, 4}, /* 7 */ + { 0 * 32, 0}, /* don't care */ + { 4 * 32, 5}, /* 9 */ + { 5 * 32, 22}, /* 10 */ + { 6 * 32, 21}, /* 11 */ + { 7 * 32, 20}, /* 12 */ + { 8 * 32, 6}, /* 13 */ + { 9 * 32, 4}, /* 14 */ + {10 * 32, 2}, /* 15 */ + { 0 * 32, 0}, /* don't care */ + {11 * 32, 15}, /* 17 */ + {11 * 32 + 16, 14}, /* 18 */ + {11 * 32 + 16 * 2, 13}, /* 19 */ + {11 * 32 + 16 * 3, 12}, /* 20 */ + {11 * 32 + 16 * 4, 11}, /* 21 */ + {11 * 32 + 16 * 5, 10}, /* 22 */ + {11 * 32 + 16 * 6, 9}, /* 23 */ + {11 * 32 + 16 * 7, 8}, /* 24 */ + {11 * 32 + 16 * 8, 7}, /* 25 */ + {11 * 32 + 16 * 9, 6}, /* 26 */ + {11 * 32 + 16 * 10, 5}, /* 27 */ + {11 * 32 + 16 * 11, 4}, /* 28 */ + {11 * 32 + 16 * 12, 3}, /* 29 */ + {11 * 32 + 16 * 13, 2}, /* 30 */ + {11 * 32 + 16 * 14, 1} /* 31 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm256_loadu_si256((__m256i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm256_storeu_si256((__m256i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m256i ret_vec; + /* While technically we only need to read 4 or 8 bytes into this vector register for a lot of cases, GCC is + * compiling this to a shared load for all branches, preferring the simpler code. Given that the buf value isn't in + * GPRs to begin with the 256 bit load is _probably_ just as inexpensive */ + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 32 - dist); +#endif + + if (dist < 16) { + /* This simpler case still requires us to shuffle in 128 bit lanes, so we must apply a static offset after + * broadcasting the first vector register to both halves. This is _marginally_ faster than doing two separate + * shuffles and combining the halves later */ + const __m256i permute_xform = + _mm256_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16); + __m256i perm_vec = _mm256_load_si256((__m256i*)(permute_table+lut_rem.idx)); + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + perm_vec = _mm256_add_epi8(perm_vec, permute_xform); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + ret_vec = _mm256_shuffle_epi8(ret_vec, perm_vec); + } else if (dist == 16) { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + return _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + } else { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + __m128i ret_vec1 = _mm_loadu_si128((__m128i*)(buf + 16)); + /* Take advantage of the fact that only the latter half of the 256 bit vector will actually differ */ + __m128i perm_vec1 = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + __m128i xlane_permutes = _mm_cmpgt_epi8(_mm_set1_epi8(16), perm_vec1); + __m128i xlane_res = _mm_shuffle_epi8(ret_vec0, perm_vec1); + /* Since we can't wrap twice, we can simply keep the later half exactly how it is instead of having to _also_ + * shuffle those values */ + __m128i latter_half = _mm_blendv_epi8(ret_vec1, xlane_res, xlane_permutes); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), latter_half, 1); + } + + return ret_vec; +} + +#define CHUNKSIZE chunksize_avx2 +#define CHUNKCOPY chunkcopy_avx2 +#define CHUNKUNROLL chunkunroll_avx2 +#define CHUNKMEMSET chunkmemset_avx2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_avx2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_avx2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_sse2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_sse2.c new file mode 100644 index 000000000..c402c0ee1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_sse2.c @@ -0,0 +1,56 @@ +/* chunkset_sse2.c -- SSE2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#ifdef X86_SSE2 +#include + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +#define CHUNKSIZE chunksize_sse2 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 +#define CHUNKMEMSET chunkmemset_sse2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_sse2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_ssse3.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_ssse3.c new file mode 100644 index 000000000..0bd626385 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/chunkset_ssse3.c @@ -0,0 +1,103 @@ +/* chunkset_ssse3.c -- SSSE3 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +/* This requires SSE2 support. While it's implicit with SSSE3, we can minimize + * code size by sharing the chunkcopy functions, which will certainly compile + * to identical machine code */ +#if defined(X86_SSSE3) && defined(X86_SSE2) +#include +#include "../generic/chunk_permute_table.h" + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG +#define HAVE_CHUNKCOPY +#define HAVE_CHUNKUNROLL + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m128i perm_vec, ret_vec; +#ifdef Z_MEMORY_SANITIZER + /* Important to note: + * This is _not_ to subvert the memory sanitizer but to instead unpoison some + * bytes we willingly and purposefully load uninitialized that we swizzle over + * in a vector register, anyway. If what we assume is wrong about what is used, + * the memory sanitizer will still usefully flag it */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + ret_vec = _mm_loadu_si128((__m128i*)buf); + *chunk_rem = lut_rem.remval; + + perm_vec = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + ret_vec = _mm_shuffle_epi8(ret_vec, perm_vec); + + return ret_vec; +} + +extern uint8_t* chunkcopy_sse2(uint8_t *out, uint8_t const *from, unsigned len); +extern uint8_t* chunkunroll_sse2(uint8_t *out, unsigned *dist, unsigned *len); + +#define CHUNKSIZE chunksize_ssse3 +#define CHUNKMEMSET chunkmemset_ssse3 +#define CHUNKMEMSET_SAFE chunkmemset_safe_ssse3 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_ssse3 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_avx2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_avx2.c new file mode 100644 index 000000000..1318a0e33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_avx2.c @@ -0,0 +1,63 @@ +/* compare256_avx2.c -- AVX2 version of compare256 + * Copyright Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) + +#include +#ifdef _MSC_VER +# include +#endif + +static inline uint32_t compare256_avx2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + __m256i ymm_src0, ymm_src1, ymm_cmp; + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); /* non-identical bytes = 00, identical bytes = FF */ + unsigned mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); /* Invert bits so identical = 0 */ + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); + mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1) { + return compare256_avx2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_sse2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_sse2.c new file mode 100644 index 000000000..aad4bd240 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/compare256_sse2.c @@ -0,0 +1,96 @@ +/* compare256_sse2.c -- SSE2 version of compare256 + * Copyright Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) + +#include + +static inline uint32_t compare256_sse2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + int align_offset = ((uintptr_t)src0) & 15; + const uint8_t *end0 = src0 + 256; + const uint8_t *end1 = src1 + 256; + __m128i xmm_src0, xmm_src1, xmm_cmp; + + /* Do the first load unaligned, than all subsequent ones we have at least + * one aligned load. Sadly aligning both loads is probably unrealistic */ + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + unsigned mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + int align_adv = 16 - align_offset; + len += align_adv; + src0 += align_adv; + src1 += align_adv; + + /* Do a flooring division (should just be a shift right) */ + int num_iter = (256 - len) / 16; + + for (int i = 0; i < num_iter; ++i) { + xmm_src0 = _mm_load_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + len += 16, src0 += 16, src1 += 16; + } + + if (align_offset) { + src0 = end0 - 16; + src1 = end1 - 16; + len = 256 - 16; + + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + } + + return 256; +} + +Z_INTERNAL uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1) { + return compare256_sse2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_pclmulqdq_tpl.h new file mode 100644 index 000000000..3e7992831 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_pclmulqdq_tpl.h @@ -0,0 +1,186 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +Z_INTERNAL void CRC32_FOLD_COPY(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL void CRC32_FOLD(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { +#endif + unsigned long algn_diff; + __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i xmm_crc_part = _mm_setzero_si128(); +#ifdef COPY + char ALIGNED_(16) partial_buf[16] = { 0 }; +#else + __m128i xmm_initial = _mm_cvtsi32_si128(init_crc); + int32_t first = init_crc != 0; + + /* Technically the CRC functions don't even call this for input < 64, but a bare minimum of 31 + * bytes of input is needed for the aligning load that occurs. If there's an initial CRC, to + * carry it forward through the folded CRC there must be 16 - src % 16 + 16 bytes available, which + * by definition can be up to 15 bytes + one full vector load. */ + assert(len >= 31 || first == 0); +#endif + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + if (len < 16) { +#ifdef COPY + if (len == 0) + return; + + memcpy(partial_buf, src, len); + xmm_crc_part = _mm_load_si128((const __m128i *)partial_buf); + memcpy(dst, partial_buf, len); +#endif + goto partial; + } + + algn_diff = ((uintptr_t)16 - ((uintptr_t)src & 0xF)) & 0xF; + if (algn_diff) { + xmm_crc_part = _mm_loadu_si128((__m128i *)src); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_crc_part); + dst += algn_diff; +#else + XOR_INITIAL128(xmm_crc_part); + + if (algn_diff < 4 && init_crc != 0) { + xmm_t0 = xmm_crc_part; + xmm_crc_part = _mm_loadu_si128((__m128i*)src + 1); + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + src += 16; + len -= 16; + } +#endif + + partial_fold(algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + + src += algn_diff; + len -= algn_diff; + } + +#ifdef X86_VPCLMULQDQ + if (len >= 256) { +#ifdef COPY + size_t n = fold_16_vpclmulqdq_copy(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, dst, src, len); + dst += n; +#else + size_t n = fold_16_vpclmulqdq(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, src, len, + xmm_initial, first); + first = 0; +#endif + len -= n; + src += n; + } +#endif + + while (len >= 64) { + len -= 64; + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + xmm_t3 = _mm_load_si128((__m128i *)src + 3); + src += 64; + + fold_4(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + _mm_storeu_si128((__m128i *)dst + 3, xmm_t3); + dst += 64; +#else + XOR_INITIAL128(xmm_t0); +#endif + + xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); + } + + /* + * len = num bytes left - 64 + */ + if (len >= 48) { + len -= 48; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + src += 48; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + dst += 48; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_3(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); + } else if (len >= 32) { + len -= 32; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + src += 32; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + dst += 32; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_2(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); + } else if (len >= 16) { + len -= 16; + xmm_t0 = _mm_load_si128((__m128i *)src); + src += 16; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + dst += 16; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + } + +partial: + if (len) { + memcpy(&xmm_crc_part, src, len); +#ifdef COPY + _mm_storeu_si128((__m128i *)partial_buf, xmm_crc_part); + memcpy(dst, partial_buf, len); +#endif + partial_fold(len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + } + + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_vpclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_vpclmulqdq_tpl.h new file mode 100644 index 000000000..3ea5c3305 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_fold_vpclmulqdq_tpl.h @@ -0,0 +1,107 @@ +/* crc32_fold_vpclmulqdq_tpl.h -- VPCMULQDQ-based CRC32 folding template. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len) { +#else +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, + __m128i init_crc, int32_t first) { + __m512i zmm_initial = _mm512_zextsi128_si512(init_crc); +#endif + __m512i zmm_t0, zmm_t1, zmm_t2, zmm_t3; + __m512i zmm_crc0, zmm_crc1, zmm_crc2, zmm_crc3; + __m512i z0, z1, z2, z3; + size_t len_tmp = len; + const __m512i zmm_fold4 = _mm512_set4_epi32( + 0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596); + const __m512i zmm_fold16 = _mm512_set4_epi32( + 0x00000001, 0x1542778a, 0x00000001, 0x322d1430); + + // zmm register init + zmm_crc0 = _mm512_setzero_si512(); + zmm_t0 = _mm512_loadu_si512((__m512i *)src); +#ifndef COPY + XOR_INITIAL512(zmm_t0); +#endif + zmm_crc1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_crc2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_crc3 = _mm512_loadu_si512((__m512i *)src + 3); + + /* already have intermediate CRC in xmm registers + * fold4 with 4 xmm_crc to get zmm_crc0 + */ + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc0, 0); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc1, 1); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc2, 2); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc3, 3); + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_t0, 0x96); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_crc1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_crc2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_crc3); + dst += 256; +#endif + len -= 256; + src += 256; + + // fold-16 loops + while (len >= 256) { + zmm_t0 = _mm512_loadu_si512((__m512i *)src); + zmm_t1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_t2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_t3 = _mm512_loadu_si512((__m512i *)src + 3); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x01); + z1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x01); + z2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x01); + z3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x01); + + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x10); + zmm_crc1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x10); + zmm_crc2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x10); + zmm_crc3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x10); + + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_t0, 0x96); + zmm_crc1 = _mm512_ternarylogic_epi32(zmm_crc1, z1, zmm_t1, 0x96); + zmm_crc2 = _mm512_ternarylogic_epi32(zmm_crc2, z2, zmm_t2, 0x96); + zmm_crc3 = _mm512_ternarylogic_epi32(zmm_crc3, z3, zmm_t3, 0x96); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_t1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_t2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_t3); + dst += 256; +#endif + len -= 256; + src += 256; + } + // zmm_crc[0,1,2,3] -> zmm_crc0 + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc1, 0x96); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc2, 0x96); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc3, 0x96); + + // zmm_crc0 -> xmm_crc[0, 1, 2, 3] + *xmm_crc0 = _mm512_extracti32x4_epi32(zmm_crc0, 0); + *xmm_crc1 = _mm512_extracti32x4_epi32(zmm_crc0, 1); + *xmm_crc2 = _mm512_extracti32x4_epi32(zmm_crc0, 2); + *xmm_crc3 = _mm512_extracti32x4_epi32(zmm_crc0, 3); + + return (len_tmp - len); // return n bytes processed +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq.c new file mode 100644 index 000000000..9383b7a2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq.c @@ -0,0 +1,30 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_PCLMULQDQ_CRC + +#define CRC32_FOLD_COPY crc32_fold_pclmulqdq_copy +#define CRC32_FOLD crc32_fold_pclmulqdq +#define CRC32_FOLD_RESET crc32_fold_pclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_pclmulqdq_final +#define CRC32 crc32_pclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq_tpl.h new file mode 100644 index 000000000..0d66663cb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_pclmulqdq_tpl.h @@ -0,0 +1,363 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include +#include +#include // _mm_extract_epi32 +#ifdef X86_VPCLMULQDQ +# include +#endif + +#include "../../crc32_fold.h" +#include "../../crc32_braid_p.h" +#include "../../fallback_builtins.h" +#include + +#ifdef X86_VPCLMULQDQ +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, __m128i init_crc, + int32_t first); +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +static void fold_1(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc3, ps_res; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res = _mm_xor_ps(ps_crc0, ps_crc3); + + *xmm_crc0 = *xmm_crc1; + *xmm_crc1 = *xmm_crc2; + *xmm_crc2 = x_tmp3; + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static void fold_2(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3, x_tmp2; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res31, ps_res20; + + x_tmp3 = *xmm_crc3; + x_tmp2 = *xmm_crc2; + + *xmm_crc3 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res31 = _mm_xor_ps(ps_crc3, ps_crc1); + + *xmm_crc2 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res20 = _mm_xor_ps(ps_crc0, ps_crc2); + + *xmm_crc0 = x_tmp2; + *xmm_crc1 = x_tmp3; + *xmm_crc2 = _mm_castps_si128(ps_res20); + *xmm_crc3 = _mm_castps_si128(ps_res31); +} + +static void fold_3(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res32, ps_res21, ps_res10; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc2; + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res32 = _mm_xor_ps(ps_crc2, ps_crc3); + + *xmm_crc2 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res21 = _mm_xor_ps(ps_crc1, ps_crc2); + + *xmm_crc1 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res10 = _mm_xor_ps(ps_crc0, ps_crc1); + + *xmm_crc0 = x_tmp3; + *xmm_crc1 = _mm_castps_si128(ps_res10); + *xmm_crc2 = _mm_castps_si128(ps_res21); + *xmm_crc3 = _mm_castps_si128(ps_res32); +} + +static void fold_4(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp0, x_tmp1, x_tmp2, x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3; + __m128 ps_t0, ps_t1, ps_t2, ps_t3; + __m128 ps_res0, ps_res1, ps_res2, ps_res3; + + x_tmp0 = *xmm_crc0; + x_tmp1 = *xmm_crc1; + x_tmp2 = *xmm_crc2; + x_tmp3 = *xmm_crc3; + + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + x_tmp0 = _mm_clmulepi64_si128(x_tmp0, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_t0 = _mm_castsi128_ps(x_tmp0); + ps_res0 = _mm_xor_ps(ps_crc0, ps_t0); + + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + x_tmp1 = _mm_clmulepi64_si128(x_tmp1, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_t1 = _mm_castsi128_ps(x_tmp1); + ps_res1 = _mm_xor_ps(ps_crc1, ps_t1); + + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + x_tmp2 = _mm_clmulepi64_si128(x_tmp2, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_t2 = _mm_castsi128_ps(x_tmp2); + ps_res2 = _mm_xor_ps(ps_crc2, ps_t2); + + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x01); + x_tmp3 = _mm_clmulepi64_si128(x_tmp3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_t3 = _mm_castsi128_ps(x_tmp3); + ps_res3 = _mm_xor_ps(ps_crc3, ps_t3); + + *xmm_crc0 = _mm_castps_si128(ps_res0); + *xmm_crc1 = _mm_castps_si128(ps_res1); + *xmm_crc2 = _mm_castps_si128(ps_res2); + *xmm_crc3 = _mm_castps_si128(ps_res3); +} + +static const unsigned ALIGNED_(32) pshufb_shf_table[60] = { + 0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d, /* shl 15 (16 - 1)/shr1 */ + 0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e, /* shl 14 (16 - 3)/shr2 */ + 0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f, /* shl 13 (16 - 4)/shr3 */ + 0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100, /* shl 12 (16 - 4)/shr4 */ + 0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201, /* shl 11 (16 - 5)/shr5 */ + 0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302, /* shl 10 (16 - 6)/shr6 */ + 0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403, /* shl 9 (16 - 7)/shr7 */ + 0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504, /* shl 8 (16 - 8)/shr8 */ + 0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605, /* shl 7 (16 - 9)/shr9 */ + 0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706, /* shl 6 (16 -10)/shr10*/ + 0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807, /* shl 5 (16 -11)/shr11*/ + 0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908, /* shl 4 (16 -12)/shr12*/ + 0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09, /* shl 3 (16 -13)/shr13*/ + 0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a, /* shl 2 (16 -14)/shr14*/ + 0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b /* shl 1 (16 -15)/shr15*/ +}; + +static void partial_fold(const size_t len, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, + __m128i *xmm_crc3, __m128i *xmm_crc_part) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + const __m128i xmm_mask3 = _mm_set1_epi32((int32_t)0x80808080); + + __m128i xmm_shl, xmm_shr, xmm_tmp1, xmm_tmp2, xmm_tmp3; + __m128i xmm_a0_0, xmm_a0_1; + __m128 ps_crc3, psa0_0, psa0_1, ps_res; + + xmm_shl = _mm_load_si128((__m128i *)(pshufb_shf_table + (4 * (len - 1)))); + xmm_shr = xmm_shl; + xmm_shr = _mm_xor_si128(xmm_shr, xmm_mask3); + + xmm_a0_0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shl); + + *xmm_crc0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shr); + xmm_tmp1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shl); + *xmm_crc0 = _mm_or_si128(*xmm_crc0, xmm_tmp1); + + *xmm_crc1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shr); + xmm_tmp2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shl); + *xmm_crc1 = _mm_or_si128(*xmm_crc1, xmm_tmp2); + + *xmm_crc2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shr); + xmm_tmp3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shl); + *xmm_crc2 = _mm_or_si128(*xmm_crc2, xmm_tmp3); + + *xmm_crc3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shr); + *xmm_crc_part = _mm_shuffle_epi8(*xmm_crc_part, xmm_shl); + *xmm_crc3 = _mm_or_si128(*xmm_crc3, *xmm_crc_part); + + xmm_a0_1 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x10); + xmm_a0_0 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x01); + + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + psa0_0 = _mm_castsi128_ps(xmm_a0_0); + psa0_1 = _mm_castsi128_ps(xmm_a0_1); + + ps_res = _mm_xor_ps(ps_crc3, psa0_0); + ps_res = _mm_xor_ps(ps_res, psa0_1); + + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static inline void crc32_fold_load(__m128i *fold, __m128i *fold0, __m128i *fold1, __m128i *fold2, __m128i *fold3) { + *fold0 = _mm_load_si128(fold + 0); + *fold1 = _mm_load_si128(fold + 1); + *fold2 = _mm_load_si128(fold + 2); + *fold3 = _mm_load_si128(fold + 3); +} + +static inline void crc32_fold_save(__m128i *fold, const __m128i *fold0, const __m128i *fold1, + const __m128i *fold2, const __m128i *fold3) { + _mm_storeu_si128(fold + 0, *fold0); + _mm_storeu_si128(fold + 1, *fold1); + _mm_storeu_si128(fold + 2, *fold2); + _mm_storeu_si128(fold + 3, *fold3); +} + +Z_INTERNAL uint32_t CRC32_FOLD_RESET(crc32_fold *crc) { + __m128i xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); + __m128i xmm_zero = _mm_setzero_si128(); + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_zero, &xmm_zero, &xmm_zero); + return 0; +} + +#define ONCE(op) if (first) { first = 0; op; } +#define XOR_INITIAL128(where) ONCE(where = _mm_xor_si128(where, xmm_initial)) +#ifdef X86_VPCLMULQDQ +# define XOR_INITIAL512(where) ONCE(where = _mm512_xor_si512(where, zmm_initial)) +#endif + +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" +#define COPY +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" + +static const unsigned ALIGNED_(16) crc_k[] = { + 0xccaa009e, 0x00000000, /* rk1 */ + 0x751997d0, 0x00000001, /* rk2 */ + 0xccaa009e, 0x00000000, /* rk5 */ + 0x63cd6124, 0x00000001, /* rk6 */ + 0xf7011640, 0x00000001, /* rk7 */ + 0xdb710640, 0x00000001 /* rk8 */ +}; + +static const unsigned ALIGNED_(16) crc_mask[4] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 +}; + +static const unsigned ALIGNED_(16) crc_mask2[4] = { + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +Z_INTERNAL uint32_t CRC32_FOLD_FINAL(crc32_fold *crc) { + const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); + const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; + + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + /* + * k1 + */ + crc_fold = _mm_load_si128((__m128i *)crc_k); + + x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); + xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); + xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); + + x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); + xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); + xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); + + x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); + xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); + xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + + /* + * k5 + */ + crc_fold = _mm_load_si128((__m128i *)(crc_k + 4)); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); + + /* + * k7 + */ + xmm_crc1 = xmm_crc3; + xmm_crc2 = xmm_crc3; + crc_fold = _mm_load_si128((__m128i *)(crc_k + 8)); + + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); + + xmm_crc2 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); + + crc->value = ~((uint32_t)_mm_extract_epi32(xmm_crc3, 2)); + + return crc->value; +} + +Z_INTERNAL uint32_t CRC32(uint32_t crc32, const uint8_t *buf, size_t len) { + /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for + * these short lengths might also prove to be effective */ + if (len < 64) + return PREFIX(crc32_braid)(crc32, buf, len); + + crc32_fold ALIGNED_(16) crc_state; + CRC32_FOLD_RESET(&crc_state); + CRC32_FOLD(&crc_state, buf, len, crc32); + return CRC32_FOLD_FINAL(&crc_state); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_vpclmulqdq.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_vpclmulqdq.c new file mode 100644 index 000000000..ec641b432 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/crc32_vpclmulqdq.c @@ -0,0 +1,17 @@ +/* crc32_vpclmulqdq.c -- VPCMULQDQ-based CRC32 folding implementation. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + +#define X86_VPCLMULQDQ +#define CRC32_FOLD_COPY crc32_fold_vpclmulqdq_copy +#define CRC32_FOLD crc32_fold_vpclmulqdq +#define CRC32_FOLD_RESET crc32_fold_vpclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_vpclmulqdq_final +#define CRC32 crc32_vpclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/insert_string_sse42.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/insert_string_sse42.c new file mode 100644 index 000000000..565d92f97 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/insert_string_sse42.c @@ -0,0 +1,50 @@ +/* insert_string_sse42.c -- insert_string integer hash variant using SSE4.2's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "../../zbuild.h" +#include +#ifdef _MSC_VER +# include +#endif +#include "../../deflate.h" + +#ifdef X86_SSE42_CRC_INTRIN +# ifdef _MSC_VER +# define HASH_CALC(s, h, val)\ + h = _mm_crc32_u32(h, val) +# else +# define HASH_CALC(s, h, val)\ + h = __builtin_ia32_crc32si(h, val) +# endif +#else +# ifdef _MSC_VER +# define HASH_CALC(s, h, val) {\ + __asm mov edx, h\ + __asm mov eax, val\ + __asm crc32 eax, edx\ + __asm mov h, eax\ + } +# else +# define HASH_CALC(s, h, val) \ + __asm__ __volatile__ (\ + "crc32 %1,%0\n\t"\ + : "+r" (h)\ + : "r" (val)\ + ); +# endif +#endif + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_sse42 +#define INSERT_STRING insert_string_sse42 +#define QUICK_INSERT_STRING quick_insert_string_sse42 + +#ifdef X86_SSE42 +# include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_avx2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_avx2.c new file mode 100644 index 000000000..94fe10c7b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_avx2.c @@ -0,0 +1,39 @@ +/* + * AVX2 optimized hash slide, based on Intel's slide_sse implementation + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * Mika T. Lindqvist + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include + +static inline void slide_hash_chain(Pos *table, uint32_t entries, const __m256i wsize) { + table += entries; + table -= 16; + + do { + __m256i value, result; + + value = _mm256_loadu_si256((__m256i *)table); + result = _mm256_subs_epu16(value, wsize); + _mm256_storeu_si256((__m256i *)table, result); + + table -= 16; + entries -= 16; + } while (entries > 0); +} + +Z_INTERNAL void slide_hash_avx2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m256i ymm_wsize = _mm256_set1_epi16((short)wsize); + + slide_hash_chain(s->head, HASH_SIZE, ymm_wsize); + slide_hash_chain(s->prev, wsize, ymm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_sse2.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_sse2.c new file mode 100644 index 000000000..5daac4a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/slide_hash_sse2.c @@ -0,0 +1,62 @@ +/* + * SSE optimized hash slide + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include +#include + +static inline void slide_hash_chain(Pos *table0, Pos *table1, uint32_t entries0, + uint32_t entries1, const __m128i wsize) { + uint32_t entries; + Pos *table; + __m128i value0, value1, result0, result1; + + int on_chain = 0; + +next_chain: + table = (on_chain) ? table1 : table0; + entries = (on_chain) ? entries1 : entries0; + + table += entries; + table -= 16; + + /* ZALLOC allocates this pointer unless the user chose a custom allocator. + * Our alloc function is aligned to 64 byte boundaries */ + do { + value0 = _mm_load_si128((__m128i *)table); + value1 = _mm_load_si128((__m128i *)(table + 8)); + result0 = _mm_subs_epu16(value0, wsize); + result1 = _mm_subs_epu16(value1, wsize); + _mm_store_si128((__m128i *)table, result0); + _mm_store_si128((__m128i *)(table + 8), result1); + + table -= 16; + entries -= 16; + } while (entries > 0); + + ++on_chain; + if (on_chain > 1) { + return; + } else { + goto next_chain; + } +} + +Z_INTERNAL void slide_hash_sse2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m128i xmm_wsize = _mm_set1_epi16((short)wsize); + + assert(((uintptr_t)s->head & 15) == 0); + assert(((uintptr_t)s->prev & 15) == 0); + + slide_hash_chain(s->head, s->prev, HASH_SIZE, wsize, xmm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.c b/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.c new file mode 100644 index 000000000..3272e3fdd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.c @@ -0,0 +1,97 @@ +/* x86_features.c - x86 feature check + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Author: + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "x86_features.h" + +#ifdef _WIN32 +# include +#else +// Newer versions of GCC and clang come with cpuid.h +# include +#endif + +#include + +static inline void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuid((int *)registers, info); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid(info, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline void cpuidex(int info, int subinfo, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuidex((int *)registers, info, subinfo); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid_count(info, subinfo, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline uint64_t xgetbv(unsigned int xcr) { +#ifdef _WIN32 + return _xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ ( ".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (uint64_t)(edx) << 32 | eax; +#endif +} + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) { + unsigned eax, ebx, ecx, edx; + unsigned maxbasic; + + cpuid(0, &maxbasic, &ebx, &ecx, &edx); + cpuid(1 /*CPU_PROCINFO_AND_FEATUREBITS*/, &eax, &ebx, &ecx, &edx); + + features->has_sse2 = edx & 0x4000000; + features->has_ssse3 = ecx & 0x200; + features->has_sse42 = ecx & 0x100000; + features->has_pclmulqdq = ecx & 0x2; + + if (ecx & 0x08000000) { + uint64_t xfeature = xgetbv(0); + + features->has_os_save_ymm = ((xfeature & 0x06) == 0x06); + features->has_os_save_zmm = ((xfeature & 0xe6) == 0xe6); + } + + if (maxbasic >= 7) { + cpuidex(7, 0, &eax, &ebx, &ecx, &edx); + + // check BMI1 bit + // Reference: https://software.intel.com/sites/default/files/article/405250/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf + features->has_vpclmulqdq = ecx & 0x400; + + // check AVX2 bit if the OS supports saving YMM registers + if (features->has_os_save_ymm) { + features->has_avx2 = ebx & 0x20; + } + + // check AVX512 bits if the OS supports saving ZMM registers + if (features->has_os_save_zmm) { + features->has_avx512 = ebx & 0x00010000; + features->has_avx512vnni = ecx & 0x800; + } + } +} diff --git a/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.h b/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.h new file mode 100644 index 000000000..4a36bde83 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/arch/x86/x86_features.h @@ -0,0 +1,24 @@ +/* x86_features.h -- check for CPU features +* Copyright (C) 2013 Intel Corporation Jim Kukunas +* For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#ifndef X86_FEATURES_H_ +#define X86_FEATURES_H_ + +struct x86_cpu_features { + int has_avx2; + int has_avx512; + int has_avx512vnni; + int has_sse2; + int has_ssse3; + int has_sse42; + int has_pclmulqdq; + int has_vpclmulqdq; + int has_os_save_ymm; + int has_os_save_zmm; +}; + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features); + +#endif /* CPU_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/chunkset.c b/internal-complibs/zlib-ng-2.1.2/chunkset.c new file mode 100644 index 000000000..7b2bb7ba3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/chunkset.c @@ -0,0 +1,42 @@ +/* chunkset.c -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +typedef uint64_t chunk_t; + +#define CHUNK_SIZE 8 + +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint8_t *dest = (uint8_t *)chunk; + memcpy(dest, from, sizeof(uint32_t)); + memcpy(dest+4, from, sizeof(uint32_t)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + memcpy(chunk, from, sizeof(uint64_t)); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + memcpy(chunk, (uint8_t *)s, sizeof(uint64_t)); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + memcpy(out, chunk, sizeof(uint64_t)); +} + +#define CHUNKSIZE chunksize_c +#define CHUNKCOPY chunkcopy_c +#define CHUNKUNROLL chunkunroll_c +#define CHUNKMEMSET chunkmemset_c +#define CHUNKMEMSET_SAFE chunkmemset_safe_c + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_c + +#include "inffast_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.2/chunkset_tpl.h b/internal-complibs/zlib-ng-2.1.2/chunkset_tpl.h new file mode 100644 index 000000000..f909a1255 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/chunkset_tpl.h @@ -0,0 +1,200 @@ +/* chunkset_tpl.h -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include + +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) +extern uint8_t* chunkmemset_ssse3(uint8_t *out, unsigned dist, unsigned len); +#endif + +/* Returns the chunk size */ +Z_INTERNAL uint32_t CHUNKSIZE(void) { + return sizeof(chunk_t); +} + +/* Behave like memcpy, but assume that it's OK to overwrite at least + chunk_t bytes of output even if the length is shorter than this, + that the length is non-zero, and that `from` lags `out` by at least + sizeof chunk_t bytes (or that they don't overlap at all or simply that + the distance is less than the length of the copy). + + Aside from better memory bus utilisation, this means that short copies + (chunk_t bytes or fewer) will fall straight through the loop + without iteration, which will hopefully make the branch prediction more + reliable. */ +#ifndef HAVE_CHUNKCOPY +Z_INTERNAL uint8_t* CHUNKCOPY(uint8_t *out, uint8_t const *from, unsigned len) { + Assert(len > 0, "chunkcopy should never have a length 0"); + chunk_t chunk; + int32_t align = ((len - 1) % sizeof(chunk_t)) + 1; + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += align; + from += align; + len -= align; + while (len > 0) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += sizeof(chunk_t); + from += sizeof(chunk_t); + len -= sizeof(chunk_t); + } + return out; +} +#endif + +/* Perform short copies until distance can be rewritten as being at least + sizeof chunk_t. + + This assumes that it's OK to overwrite at least the first + 2*sizeof(chunk_t) bytes of output even if the copy is shorter than this. + This assumption holds because inflate_fast() starts every iteration with at + least 258 bytes of output space available (258 being the maximum length + output from a single token; see inflate_fast()'s assumptions below). */ +#ifndef HAVE_CHUNKUNROLL +Z_INTERNAL uint8_t* CHUNKUNROLL(uint8_t *out, unsigned *dist, unsigned *len) { + unsigned char const *from = out - *dist; + chunk_t chunk; + while (*dist < *len && *dist < sizeof(chunk_t)) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += *dist; + *len -= *dist; + *dist += *dist; + } + return out; +} +#endif + +#ifndef HAVE_CHUNK_MAG +/* Loads a magazine to feed into memory of the pattern */ +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + /* This code takes string of length dist from "from" and repeats + * it for as many times as can fit in a chunk_t (vector register) */ + uint32_t cpy_dist; + uint32_t bytes_remaining = sizeof(chunk_t); + chunk_t chunk_load; + uint8_t *cur_chunk = (uint8_t *)&chunk_load; + while (bytes_remaining) { + cpy_dist = MIN(dist, bytes_remaining); + memcpy(cur_chunk, buf, cpy_dist); + bytes_remaining -= cpy_dist; + cur_chunk += cpy_dist; + /* This allows us to bypass an expensive integer division since we're effectively + * counting in this loop, anyway */ + *chunk_rem = cpy_dist; + } + + return chunk_load; +} +#endif + +/* Copy DIST bytes from OUT - DIST into OUT + DIST * k, for 0 <= k < LEN/DIST. + Return OUT + LEN. */ +Z_INTERNAL uint8_t* CHUNKMEMSET(uint8_t *out, unsigned dist, unsigned len) { + /* Debug performance related issues when len < sizeof(uint64_t): + Assert(len >= sizeof(uint64_t), "chunkmemset should be called on larger chunks"); */ + Assert(dist > 0, "chunkmemset cannot have a distance 0"); + /* Only AVX2 */ +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) + if (len <= 16) { + return chunkmemset_ssse3(out, dist, len); + } +#endif + + uint8_t *from = out - dist; + + if (dist == 1) { + memset(out, *from, len); + return out + len; + } else if (dist > sizeof(chunk_t)) { + return CHUNKCOPY(out, out - dist, len); + } + + chunk_t chunk_load; + uint32_t chunk_mod = 0; + + /* TODO: possibly build up a permutation table for this if not an even modulus */ +#ifdef HAVE_CHUNKMEMSET_2 + if (dist == 2) { + chunkmemset_2(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_4 + if (dist == 4) { + chunkmemset_4(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_8 + if (dist == 8) { + chunkmemset_8(from, &chunk_load); + } else if (dist == sizeof(chunk_t)) { + loadchunk(from, &chunk_load); + } else +#endif + { + chunk_load = GET_CHUNK_MAG(from, &chunk_mod, dist); + } + + /* If we're lucky enough and dist happens to be an even modulus of our vector length, + * we can do two stores per loop iteration, which for most ISAs, especially x86, is beneficial */ + if (chunk_mod == 0) { + while (len >= (2 * sizeof(chunk_t))) { + storechunk(out, &chunk_load); + storechunk(out + sizeof(chunk_t), &chunk_load); + out += 2 * sizeof(chunk_t); + len -= 2 * sizeof(chunk_t); + } + } + + /* If we don't have a "dist" length that divides evenly into a vector + * register, we can write the whole vector register but we need only + * advance by the amount of the whole string that fits in our chunk_t. + * If we do divide evenly into the vector length, adv_amount = chunk_t size*/ + uint32_t adv_amount = sizeof(chunk_t) - chunk_mod; + while (len >= sizeof(chunk_t)) { + storechunk(out, &chunk_load); + len -= adv_amount; + out += adv_amount; + } + + if (len) { + memcpy(out, &chunk_load, len); + out += len; + } + + return out; +} + +Z_INTERNAL uint8_t* CHUNKMEMSET_SAFE(uint8_t *out, unsigned dist, unsigned len, unsigned left) { +#if !defined(UNALIGNED64_OK) +# if !defined(UNALIGNED_OK) + static const uint32_t align_mask = 7; +# else + static const uint32_t align_mask = 3; +# endif +#endif + + len = MIN(len, left); + uint8_t *from = out - dist; +#if !defined(UNALIGNED64_OK) + while (((uintptr_t)out & align_mask) && (len > 0)) { + *out++ = *from++; + --len; + --left; + } +#endif + if (left < (unsigned)(3 * sizeof(chunk_t))) { + while (len > 0) { + *out++ = *from++; + --len; + } + return out; + } + if (len) + return CHUNKMEMSET(out, dist, len); + + return out; +} diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.c b/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.c new file mode 100644 index 000000000..ff1a05a25 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.c @@ -0,0 +1,111 @@ +// archdetect.c -- Detect compiler architecture and raise preprocessor error +// containing a simple arch identifier. +// Copyright (C) 2019 Hans Kristian Rosbach +// Licensed under the Zlib license, see LICENSE.md for details + +// x86_64 +#if defined(__x86_64__) || defined(_M_X64) + #error archfound x86_64 + +// x86 +#elif defined(__i386) || defined(_M_IX86) + #error archfound i686 + +// ARM +#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) + #error archfound aarch64 +#elif defined(__arm__) || defined(__arm) || defined(_M_ARM) || defined(__TARGET_ARCH_ARM) + #if defined(__ARM64_ARCH_8__) || defined(__ARMv8__) || defined(__ARMv8_A__) + #error archfound armv8 + #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) + #error archfound armv7 + #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__) + #error archfound armv6 + #elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) + #error archfound armv5 + #elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARCH_5E__) + #error archfound armv4 + #elif defined(__ARM_ARCH_3__) || defined(__TARGET_ARCH_3M__) + #error archfound armv3 + #elif defined(__ARM_ARCH_2__) + #error archfound armv2 + #endif + +// PowerPC +#elif defined(__powerpc__) || defined(_ppc__) || defined(__PPC__) + #if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #error archfound powerpc64le + #else + #error archfound powerpc64 + #endif + #else + #error archfound powerpc + #endif + +// --------------- Less common architectures alphabetically below --------------- + +// ALPHA +#elif defined(__alpha__) || defined(__alpha) + #error archfound alpha + +// Blackfin +#elif defined(__BFIN__) + #error archfound blackfin + +// Itanium +#elif defined(__ia64) || defined(_M_IA64) + #error archfound ia64 + +// MIPS +#elif defined(__mips__) || defined(__mips) + #error archfound mips + +// Motorola 68000-series +#elif defined(__m68k__) + #error archfound m68k + +// SuperH +#elif defined(__sh__) + #error archfound sh + +// SPARC +#elif defined(__sparc__) || defined(__sparc) + #if defined(__sparcv9) || defined(__sparc_v9__) + #error archfound sparc9 + #elif defined(__sparcv8) || defined(__sparc_v8__) + #error archfound sparc8 + #endif + +// SystemZ +#elif defined(__370__) + #error archfound s370 +#elif defined(__s390__) + #error archfound s390 +#elif defined(__s390x) || defined(__zarch__) + #error archfound s390x + +// PARISC +#elif defined(__hppa__) + #error archfound parisc + +// RS-6000 +#elif defined(__THW_RS6000) + #error archfound rs6000 + +// RISC-V +#elif defined(__riscv) + #if __riscv_xlen == 64 + #error archfound riscv64 + #elif __riscv_xlen == 32 + #error archfound riscv32 + #endif + +// Emscripten (WebAssembly) +#elif defined(__EMSCRIPTEN__) + #error archfound wasm32 + +// return 'unrecognized' if we do not know what architecture this is +#else + #error archfound unrecognized +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.cmake new file mode 100644 index 000000000..21c237d61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-arch.cmake @@ -0,0 +1,101 @@ +# detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH +# Copyright (C) 2019 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details +set(ARCHDETECT_FOUND TRUE) + +if(CMAKE_OSX_ARCHITECTURES) + # If multiple architectures are requested (universal build), pick only the first + list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH) +elseif(MSVC) + if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86") + set(ARCH "i686") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64") + set(ARCH "x86_64") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7") + set(ARCH "arm") + elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64") + set(ARCH "aarch64") + endif() +elseif(EMSCRIPTEN) + set(ARCH "wasm32") +elseif(CMAKE_CROSSCOMPILING) + set(ARCH ${CMAKE_C_COMPILER_TARGET}) +else() + # Let preprocessor parse archdetect.c and raise an error containing the arch identifier + enable_language(C) + try_run( + run_result_unused + compile_result_unused + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_LIST_DIR}/detect-arch.c + COMPILE_OUTPUT_VARIABLE RAWOUTPUT + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Find basearch tag, and extract the arch word into BASEARCH variable + string(REGEX REPLACE ".*archfound ([a-zA-Z0-9_]+).*" "\\1" ARCH "${RAWOUTPUT}") + if(NOT ARCH) + set(ARCH unknown) + endif() +endif() + +# Make sure we have ARCH set +if(NOT ARCH OR ARCH STREQUAL "unknown") + set(ARCH ${CMAKE_SYSTEM_PROCESSOR}) + message(STATUS "Arch not recognized, falling back to cmake arch: '${ARCH}'") +else() + message(STATUS "Arch detected: '${ARCH}'") +endif() + +# Base arch detection +if("${ARCH}" MATCHES "(x86_64|AMD64|i[3-6]86)") + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) +elseif("${ARCH}" MATCHES "(arm(v[0-9])?|aarch64)") + set(BASEARCH "arm") + set(BASEARCH_ARM_FOUND TRUE) +elseif("${ARCH}" MATCHES "ppc(64(le)?)?|powerpc(64(le)?)?") + set(BASEARCH "ppc") + set(BASEARCH_PPC_FOUND TRUE) +elseif("${ARCH}" MATCHES "alpha") + set(BASEARCH "alpha") + set(BASEARCH_ALPHA_FOUND TRUE) +elseif("${ARCH}" MATCHES "blackfin") + set(BASEARCH "blackfin") + set(BASEARCH_BLACKFIN_FOUND TRUE) +elseif("${ARCH}" MATCHES "ia64") + set(BASEARCH "ia64") + set(BASEARCH_IA64_FOUND TRUE) +elseif("${ARCH}" MATCHES "mips") + set(BASEARCH "mips") + set(BASEARCH_MIPS_FOUND TRUE) +elseif("${ARCH}" MATCHES "m68k") + set(BASEARCH "m68k") + set(BASEARCH_M68K_FOUND TRUE) +elseif("${ARCH}" MATCHES "sh") + set(BASEARCH "sh") + set(BASEARCH_SH_FOUND TRUE) +elseif("${ARCH}" MATCHES "sparc[89]?") + set(BASEARCH "sparc") + set(BASEARCH_SPARC_FOUND TRUE) +elseif("${ARCH}" MATCHES "s3[679]0x?") + set(BASEARCH "s360") + set(BASEARCH_S360_FOUND TRUE) +elseif("${ARCH}" MATCHES "parisc") + set(BASEARCH "parisc") + set(BASEARCH_PARISC_FOUND TRUE) +elseif("${ARCH}" MATCHES "rs6000") + set(BASEARCH "rs6000") + set(BASEARCH_RS6000_FOUND TRUE) +elseif("${ARCH}" MATCHES "riscv(32|64)") + set(BASEARCH "riscv") + set(BASEARCH_RISCV_FOUND TRUE) +elseif("${ARCH}" MATCHES "wasm32") + set(BASEARCH "wasm32") + set(BASEARCH_WASM32_FOUND TRUE) +else() + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) + message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.") +endif() +message(STATUS "Basearch of '${ARCH}' has been detected as: '${BASEARCH}'") diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-coverage.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/detect-coverage.cmake new file mode 100644 index 000000000..8e67a085c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-coverage.cmake @@ -0,0 +1,46 @@ +# detect-coverage.cmake -- Detect supported compiler coverage flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_code_coverage) + # Check for -coverage flag support for Clang/GCC + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -coverage) + endif() + check_c_compiler_flag(-coverage HAVE_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_COVERAGE) + add_compile_options(-coverage) + add_link_options(-coverage) + message(STATUS "Code coverage enabled using: -coverage") + else() + # Some versions of GCC don't support -coverage shorthand + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -lgcov -fprofile-arcs) + endif() + check_c_compiler_flag("-ftest-coverage -fprofile-arcs -fprofile-values" HAVE_TEST_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_TEST_COVERAGE) + add_compile_options(-ftest-coverage -fprofile-arcs -fprofile-values) + add_link_options(-lgcov -fprofile-arcs) + message(STATUS "Code coverage enabled using: -ftest-coverage") + else() + message(WARNING "Compiler does not support code coverage") + set(WITH_CODE_COVERAGE OFF) + endif() + endif() + + # Set optimization level to zero for code coverage builds + if (WITH_CODE_COVERAGE) + # Use CMake compiler flag variables due to add_compile_options failure on Windows GCC + set(CMAKE_C_FLAGS "-O0 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-O0 ${CMAKE_CXX_FLAGS}") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-install-dirs.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/detect-install-dirs.cmake new file mode 100644 index 000000000..a7c774f47 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-install-dirs.cmake @@ -0,0 +1,43 @@ +# detect-install-dirs.cmake -- Detect install directory parameters +# Copyright (C) 2021 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details + +# Determine installation directory for executables +if (DEFINED BIN_INSTALL_DIR) + set(BIN_INSTALL_DIR "${BIN_INSTALL_DIR}" CACHE PATH "Installation directory for executables (Deprecated)" FORCE) + set(CMAKE_INSTALL_BINDIR "${BIN_INSTALL_DIR}") +elseif (DEFINED INSTALL_BIN_DIR) + set(CMAKE_INSTALL_BINDIR "${INSTALL_BIN_DIR}") +endif() + +# Determine installation directory for libraries +if (DEFINED LIB_INSTALL_DIR) + set(LIB_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Installation directory for libraries (Deprecated)" FORCE) + set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}") +elseif (DEFINED INSTALL_LIB_DIR) + set(CMAKE_INSTALL_LIBDIR "${INSTALL_LIB_DIR}") +endif() + +# Determine installation directory for include files +if (DEFINED INC_INSTALL_DIR) + set(INC_INSTALL_DIR "${INC_INSTALL_DIR}" CACHE PATH "Installation directory for headers (Deprecated)" FORCE) + set(CMAKE_INSTALL_INCLUDEDIR "${INC_INSTALL_DIR}") +elseif (DEFINED INSTALL_INC_DIR) + set(CMAKE_INSTALL_INCLUDEDIR "${INSTALL_INC_DIR}") +endif() + +# Define GNU standard installation directories +include(GNUInstallDirs) + +# Determine installation directory for pkgconfig files +if (DEFINED PKGCONFIG_INSTALL_DIR) + set(PKGCONFIG_INSTALL_DIR "${PKGCONFIG_INSTALL_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED INSTALL_PKGCONFIG_DIR) + set(PKGCONFIG_INSTALL_DIR "${INSTALL_PKGCONFIG_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_FULL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_FULL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +else() + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-intrinsics.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/detect-intrinsics.cmake new file mode 100644 index 000000000..e9e6d36da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-intrinsics.cmake @@ -0,0 +1,548 @@ +# detect-intrinsics.cmake -- Detect compiler intrinsics support +# Licensed under the Zlib license, see LICENSE.md for details + +macro(check_acle_compiler_flag) + if(MSVC) + # Both ARM and ARM64-targeting msvc support intrinsics, but + # ARM msvc is missing some intrinsics introduced with ARMv8, e.g. crc32 + if(MSVC_C_ARCHITECTURE_ID STREQUAL "ARM64") + set(HAVE_ACLE_FLAG TRUE) + endif() + else() + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc" CACHE INTERNAL "Compiler option to enable ACLE support") + endif() + endif() + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG FAIL_REGEX "not supported") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc+simd" CACHE INTERNAL "Compiler option to enable ACLE support" FORCE) + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG2 FAIL_REGEX "not supported") + set(HAVE_ACLE_FLAG ${HAVE_ACLE_FLAG2} CACHE INTERNAL "Have compiler option to enable ACLE intrinsics" FORCE) + unset(HAVE_ACLE_FLAG2 CACHE) # Don't cache this internal variable + endif() + set(CMAKE_REQUIRED_FLAGS) + endif() +endmacro() + +macro(check_avx512_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + else() + set(AVX512FLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + # For CPUs that can benefit from AVX512, it seems GCC generates suboptimal + # instruction scheduling unless you specify a reasonable -mtune= target + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE) + if(HAVE_CASCADE_LAKE) + set(AVX512FLAG "${AVX512FLAG} -mtune=cascadelake") + else() + set(AVX512FLAG "${AVX512FLAG} -mtune=skylake-avx512") + endif() + unset(HAVE_CASCADE_LAKE) + endif() + endif() + elseif(MSVC) + set(AVX512FLAG "/arch:AVX512") + endif() + # Check whether compiler supports AVX512 intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; + }" + HAVE_AVX512_INTRIN + ) + + # Evidently both GCC and clang were late to implementing these + check_c_source_compile_or_run( + "#include + int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; + }" + HAVE_MASK_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx512vnni_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512VNNIFLAG "-mavx512f -mavx512bw -mavx512dq -mavx512vl -mavx512vnni") + else() + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX512VNNIFLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mavx512vnni") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE) + if(HAVE_CASCADE_LAKE) + set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=cascadelake") + else() + set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=skylake-avx512") + endif() + unset(HAVE_CASCADE_LAKE) + endif() + endif() + elseif(MSVC) + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + + # Check whether compiler supports AVX512vnni intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512VNNIFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; + }" + HAVE_AVX512VNNI_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX2FLAG "-mavx2") + else() + set(AVX2FLAG "/arch:AVX2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX2FLAG "-mavx2") + endif() + elseif(MSVC) + set(AVX2FLAG "/arch:AVX2") + endif() + # Check whether compiler supports AVX2 intrinics + set(CMAKE_REQUIRED_FLAGS "${AVX2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; + }" + HAVE_AVX2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_compiler_flag) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports NEON flag + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main() { return 0; }" + MFPU_NEON_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_ld4_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports loading 4 neon vecs into a register range + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; + }" + NEON_HAS_LD4) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_pclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(PCLMULFLAG "-mpclmul") + endif() + endif() + # Check whether compiler supports PCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + # The pclmul code currently crashes on Mac in 32bit mode. Avoid for now. + set(CMAKE_REQUIRED_FLAGS "${PCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_PCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_PCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_vpclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(VPCLMULFLAG "-mvpclmulqdq -mavx512f") + endif() + endif() + # Check whether compiler supports VPCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + set(CMAKE_REQUIRED_FLAGS "${VPCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_VPCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_VPCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_ppc_intrinsics) + # Check if compiler supports AltiVec + set(CMAKE_REQUIRED_FLAGS "-maltivec") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_ALTIVEC + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_ALTIVEC) + set(PPCFLAGS "-maltivec") + endif() + + set(CMAKE_REQUIRED_FLAGS "-maltivec -mno-vsx") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_NOVSX + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_NOVSX) + set(PPCFLAGS "${PPCFLAGS} -mno-vsx") + endif() + + # Check if we have what we need for AltiVec optimizations + set(CMAKE_REQUIRED_FLAGS "${PPCFLAGS} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); + #else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); + #endif + }" + HAVE_VMX + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_power8_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER8FLAG "-mcpu=power8") + endif() + endif() + # Check if we have what we need for POWER8 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER8FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); + #else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); + #endif + }" + HAVE_POWER8_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_rvv_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(RISCVFLAG "-march=rv64gcv") + endif() + endif() + # Check whether compiler supports RVV + set(CMAKE_REQUIRED_FLAGS "${RISCVFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + int main() { + return 0; + }" + HAVE_RVV_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_s390_intrinsics) + check_c_source_compiles( + "#include + #ifndef HWCAP_S390_VXRS + #define HWCAP_S390_VXRS HWCAP_S390_VX + #endif + int main() { + return (getauxval(AT_HWCAP) & HWCAP_S390_VXRS); + }" + HAVE_S390_INTRIN + ) +endmacro() + +macro(check_power9_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER9FLAG "-mcpu=power9") + endif() + endif() + # Check if we have what we need for POWER9 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER9FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { + return 0; + }" + HAVE_POWER9_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_sse2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE2FLAG "-msse2") + else() + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(MSVC) + if(NOT "${ARCH}" MATCHES "x86_64") + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE2FLAG "-msse2") + endif() + endif() + # Check whether compiler supports SSE2 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; + }" + HAVE_SSE2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_ssse3_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSSE3FLAG "-mssse3") + else() + set(SSSE3FLAG "/arch:SSSE3") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSSE3FLAG "-mssse3") + endif() + endif() + # Check whether compiler supports SSSE3 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSSE3FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; + }" + HAVE_SSSE3_INTRIN + ) +endmacro() + +macro(check_sse42_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE42FLAG "-msse4.2") + else() + set(SSE42FLAG "/arch:SSE4.2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE42FLAG "-msse4.2") + endif() + endif() + # Check whether compiler supports SSE4.2 CRC inline asm + set(CMAKE_REQUIRED_FLAGS "${SSE42FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "int main(void) { + unsigned val = 0, h = 0; + #if defined(_MSC_VER) + { __asm mov edx, h __asm mov eax, val __asm crc32 eax, edx __asm mov h, eax } + #else + __asm__ __volatile__ ( \"crc32 %1,%0\" : \"+r\" (h) : \"r\" (val) ); + #endif + return (int)h; + }" + HAVE_SSE42CRC_INLINE_ASM + ) + # Check whether compiler supports SSE4.2 CRC intrinsics + check_c_source_compile_or_run( + "#include + int main(void) { + unsigned crc = 0; + char c = 'c'; + #if defined(_MSC_VER) + crc = _mm_crc32_u32(crc, c); + #else + crc = __builtin_ia32_crc32qi(crc, c); + #endif + (void)crc; + return 0; + }" + HAVE_SSE42CRC_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_vgfma_intrinsics) + if(NOT NATIVEFLAG) + set(VGFMAFLAG "-march=z13") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set(VGFMAFLAG "${VGFMAFLAG} -mzarch") + endif() + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(VGFMAFLAG "${VGFMAFLAG} -fzvector") + endif() + endif() + # Check whether compiler supports "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic + set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; + }" + HAVE_VGFMA_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_xsave_intrinsics) + if(NOT NATIVEFLAG AND NOT MSVC) + set(XSAVEFLAG "-mxsave") + endif() + set(CMAKE_REQUIRED_FLAGS "${XSAVEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _WIN32 + # include + #else + # include + #endif + int main(void) { + return _xgetbv(0); + }" + HAVE_XSAVE_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/detect-sanitizer.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/detect-sanitizer.cmake new file mode 100644 index 000000000..f9521ec2f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/detect-sanitizer.cmake @@ -0,0 +1,166 @@ +# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_common_sanitizer_flags) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options(-g3) + endif() + check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER) + if(HAVE_NO_OMIT_FRAME_POINTER) + add_compile_options(-fno-omit-frame-pointer) + add_link_options(-fno-omit-frame-pointer) + endif() + check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS) + if(HAVE_NO_OPTIMIZE_SIBLING_CALLS) + add_compile_options(-fno-optimize-sibling-calls) + add_link_options(-fno-optimize-sibling-calls) + endif() +endmacro() + +macro(check_sanitizer_support known_checks supported_checks) + set(available_checks "") + + # Build list of supported sanitizer flags by incrementally trying compilation with + # known sanitizer checks + + foreach(check ${known_checks}) + if(available_checks STREQUAL "") + set(compile_checks "${check}") + else() + set(compile_checks "${available_checks},${check}") + endif() + + set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks}) + + check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check} + FAIL_REGEX "not supported|unrecognized command|unknown option") + + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_SANITIZER_${check}) + set(available_checks ${compile_checks}) + endif() + endforeach() + + set(${supported_checks} ${available_checks}) +endmacro() + +macro(add_address_sanitizer) + set(known_checks + address + pointer-compare + pointer-subtract + ) + + check_sanitizer_support("${known_checks}" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Address sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Address sanitizer is not supported") + endif() + + if(CMAKE_CROSSCOMPILING_EMULATOR) + # Only check for leak sanitizer if not cross-compiling due to qemu crash + message(WARNING "Leak sanitizer is not supported when cross compiling") + else() + # Leak sanitizer requires address sanitizer + check_sanitizer_support("leak" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Leak sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Leak sanitizer is not supported") + endif() + endif() +endmacro() + +macro(add_memory_sanitizer) + check_sanitizer_support("memory" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Memory sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + + check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS) + if(HAVE_MEMORY_TRACK_ORIGINS) + add_compile_options(-fsanitize-memory-track-origins) + add_link_options(-fsanitize-memory-track-origins) + endif() + else() + message(STATUS "Memory sanitizer is not supported") + endif() +endmacro() + +macro(add_thread_sanitizer) + check_sanitizer_support("thread" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Thread sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Thread sanitizer is not supported") + endif() +endmacro() + +macro(add_undefined_sanitizer) + set(known_checks + array-bounds + bool + bounds + builtin + enum + float-cast-overflow + float-divide-by-zero + function + integer-divide-by-zero + local-bounds + null + nonnull-attribute + pointer-overflow + return + returns-nonnull-attribute + shift + shift-base + shift-exponent + signed-integer-overflow + undefined + unsigned-integer-overflow + unsigned-shift-base + vla-bound + vptr + ) + + # Only check for alignment sanitizer flag if unaligned access is not supported + if(NOT WITH_UNALIGNED) + list(APPEND known_checks alignment) + endif() + # Object size sanitizer has no effect at -O0 and produces compiler warning if enabled + if(NOT CMAKE_C_FLAGS MATCHES "-O0") + list(APPEND known_checks object-size) + endif() + + check_sanitizer_support("${known_checks}" supported_checks) + + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + + # Group sanitizer flag -fsanitize=undefined will automatically add alignment, even if + # it is not in our sanitize flag list, so we need to explicitly disable alignment sanitizing. + if(WITH_UNALIGNED) + add_compile_options(-fno-sanitize=alignment) + endif() + + add_common_sanitizer_flags() + else() + message(STATUS "Undefined behavior sanitizer is not supported") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/fallback-macros.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/fallback-macros.cmake new file mode 100644 index 000000000..8bc6cf25b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/fallback-macros.cmake @@ -0,0 +1,19 @@ +# fallback-macros.cmake -- CMake fallback macros +# Copyright (C) 2022 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# CMake less than version 3.5.2 +if(NOT COMMAND add_compile_options) + macro(add_compile_options options) + string(APPEND CMAKE_C_FLAGS ${options}) + string(APPEND CMAKE_CXX_FLAGS ${options}) + endmacro() +endif() + +# CMake less than version 3.14 +if(NOT COMMAND add_link_options) + macro(add_link_options options) + string(APPEND CMAKE_EXE_LINKER_FLAGS ${options}) + string(APPEND CMAKE_SHARED_LINKER_FLAGS ${options}) + endmacro() +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-aarch64.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-aarch64.cmake new file mode 100644 index 000000000..1e2473107 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-aarch64.cmake @@ -0,0 +1,24 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") +set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-arm.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-arm.cmake new file mode 100644 index 000000000..1bdd8d2cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-arm.cmake @@ -0,0 +1,29 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +if(NOT DEFINED CMAKE_C_COMPILER_TARGET) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) +endif() +if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) +endif() + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-armhf.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-armhf.cmake new file mode 100644 index 000000000..007859caf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-armhf.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf) +set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-i686.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-i686.cmake new file mode 100644 index 000000000..b95e63f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-i686.cmake @@ -0,0 +1,35 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET i686-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES + ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-x86_64.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-x86_64.cmake new file mode 100644 index 000000000..8c660b0b1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mingw-x86_64.cmake @@ -0,0 +1,34 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET x86_64-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips.cmake new file mode 100644 index 000000000..69a1025e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips.cmake @@ -0,0 +1,29 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR mips) +set(CMAKE_SYSTEM_VERSION 1) + +if(NOT DEFINED CMAKE_C_COMPILER_TARGET) + set(CMAKE_C_COMPILER_TARGET mips-linux-gnu) +endif() +if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET) + set(CMAKE_CXX_COMPILER_TARGET mips-linux-gnu) +endif() + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips64.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips64.cmake new file mode 100644 index 000000000..8ef3b6b00 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-mips64.cmake @@ -0,0 +1,29 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR mips64) +set(CMAKE_SYSTEM_VERSION 1) + +if(NOT DEFINED CMAKE_C_COMPILER_TARGET) + set(CMAKE_C_COMPILER_TARGET mips64-linux-gnuabi64) +endif() +if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET) + set(CMAKE_CXX_COMPILER_TARGET mips64-linux-gnuabi64) +endif() + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-mips64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc.cmake new file mode 100644 index 000000000..f09713370 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR powerpc) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc -cpu 7400 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64.cmake new file mode 100644 index 000000000..80d8b904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64le.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64le.cmake new file mode 100644 index 000000000..68381de12 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-powerpc64le.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64le) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-riscv.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-riscv.cmake new file mode 100644 index 000000000..9cf8fdb7f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-riscv.cmake @@ -0,0 +1,28 @@ +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_PROCESSOR "riscv64") + +# Avoid to use system path for cross-compile +set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE) + +set(TOOLCHAIN_PATH "" CACHE STRING "The toolchain path.") +if(NOT TOOLCHAIN_PATH) + set(TOOLCHAIN_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-clang) +endif() + +set(TOOLCHAIN_PREFIX "riscv64-unknown-linux-gnu-" CACHE STRING "The toolchain prefix.") +set(QEMU_PATH "" CACHE STRING "The qemu path.") +if(NOT QEMU_PATH) + set(QEMU_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64) +endif() + +# toolchain setting +set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang") +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang++") + +# disable auto-vectorizer +add_compile_options(-fno-vectorize -fno-slp-vectorize) + +# emulator setting +set(QEMU_CPU_OPTION "rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0") +set(CMAKE_CROSSCOMPILING_EMULATOR ${QEMU_PATH} -cpu ${QEMU_CPU_OPTION} -L ${TOOLCHAIN_PATH}/sysroot/) diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-s390x.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-s390x.cmake new file mode 100644 index 000000000..9455a2bed --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-s390x.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR s390x) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET s390x-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET s390x-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-s390x -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-sparc64.cmake b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-sparc64.cmake new file mode 100644 index 000000000..16161a78c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cmake/toolchain-sparc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR sparc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET sparc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET sparc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-sparc64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.2/compare256.c b/internal-complibs/zlib-ng-2.1.2/compare256.c new file mode 100644 index 000000000..82551cdd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/compare256.c @@ -0,0 +1,180 @@ +/* compare256.c -- 256 byte memory comparison with match length return + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "fallback_builtins.h" + +/* ALIGNED, byte comparison */ +static inline uint32_t compare256_c_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1) { + return compare256_c_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +/* 16-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_16_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_16_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#ifdef HAVE_BUILTIN_CTZ +/* 32-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_32_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint32_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint32_t match_byte = __builtin_ctz(diff) / 8; + return len + match_byte; + } + + src0 += 4, src1 += 4, len += 4; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_32_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#endif + +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +/* UNALIGNED64_OK, 64-bit integer comparison */ +static inline uint32_t compare256_unaligned_64_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint64_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint64_t match_byte = __builtin_ctzll(diff) / 8; + return len + (uint32_t)match_byte; + } + + src0 += 8, src1 += 8, len += 8; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_64_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/compare256_rle.h b/internal-complibs/zlib-ng-2.1.2/compare256_rle.h new file mode 100644 index 000000000..0f3998d4a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/compare256_rle.h @@ -0,0 +1,134 @@ +/* compare256_rle.h -- 256 byte run-length encoding comparison + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "fallback_builtins.h" + +typedef uint32_t (*compare256_rle_func)(const uint8_t* src0, const uint8_t* src1); + +/* ALIGNED, byte comparison */ +static inline uint32_t compare256_rle_c(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + } while (len < 256); + + return 256; +} + +#ifdef UNALIGNED_OK +/* 16-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_16(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + uint16_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + + do { + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + } while (len < 256); + + return 256; +} + +#ifdef HAVE_BUILTIN_CTZ +/* 32-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_32(const uint8_t *src0, const uint8_t *src1) { + uint32_t sv, len = 0; + uint16_t src0_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + sv = ((uint32_t)src0_cmp << 16) | src0_cmp; + + do { + uint32_t mv, diff; + + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint32_t match_byte = __builtin_ctz(diff) / 8; + return len + match_byte; + } + + src1 += 4, len += 4; + } while (len < 256); + + return 256; +} + +#endif + +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +/* 64-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_64(const uint8_t *src0, const uint8_t *src1) { + uint32_t src0_cmp32, len = 0; + uint16_t src0_cmp; + uint64_t sv; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + src0_cmp32 = ((uint32_t)src0_cmp << 16) | src0_cmp; + sv = ((uint64_t)src0_cmp32 << 32) | src0_cmp32; + + do { + uint64_t mv, diff; + + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint64_t match_byte = __builtin_ctzll(diff) / 8; + return len + (uint32_t)match_byte; + } + + src1 += 8, len += 8; + } while (len < 256); + + return 256; +} + +#endif + +#endif + diff --git a/internal-complibs/zlib-ng-2.1.2/compress.c b/internal-complibs/zlib-ng-2.1.2/compress.c new file mode 100644 index 000000000..66118e4f4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/compress.c @@ -0,0 +1,98 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_common.h" +#else +/* Returns the upper bound on compressed data length based on uncompressed data length, assuming default settings. + * Zero means that arch-specific deflation code behaves identically to the regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_COMPLEN(source_len) 0 +#endif + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int Z_EXPORT PREFIX(compress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, + z_uintmax_t sourceLen, int level) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_size_t left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(deflateInit)(&stream, level); + if (err != Z_OK) + return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (unsigned long)max ? max : (unsigned int)sourceLen; + sourceLen -= stream.avail_in; + } + err = PREFIX(deflate)(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + PREFIX(deflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int Z_EXPORT PREFIX(compress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(compress2)(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +z_uintmax_t Z_EXPORT PREFIX(compressBound)(z_uintmax_t sourceLen) { + z_uintmax_t complen = DEFLATE_BOUND_COMPLEN(sourceLen); + + if (complen > 0) + /* Architecture-specific code provided an upper bound. */ + return complen + ZLIB_WRAPLEN; + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + ZLIB_WRAPLEN; /* zlib wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + ZLIB_WRAPLEN; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/configure b/internal-complibs/zlib-ng-2.1.2/configure new file mode 100755 index 000000000..a7ecc370b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/configure @@ -0,0 +1,2326 @@ +#!/usr/bin/env bash +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +# start off configure.log +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +SRCDIR=$(cd $(dirname $0); pwd) +BUILDDIR=$(pwd) + +# set command prefix for cross-compilation +if [ -n "${CHOST}" ]; then + # normalize the chost before parsing it + NORM_CHOST=$(sh "$SRCDIR"/tools/config.sub $CHOST) + uname="$(echo "${NORM_CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')" + CROSS_PREFIX="${CHOST}-" + ARCH="$(echo "${NORM_CHOST}" | sed -e 's/-.*//')" +else + ARCH="$(uname -m)" +fi + +case "${ARCH}" in + x86_64) + case "${CFLAGS}" in + *-m32*) + ARCH=i686 + ;; + esac + ;; + i386 | i486 | i586 | i686) + case "${CFLAGS}" in + *-m64*) + ARCH=x86_64 + ;; + esac + ;; +esac + +# destination name for windows import library +IMPORTLIB= + +# establish commands for library building +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi + +# set defaults before processing command line options +LDCONFIG=${LDCONFIG-"ldconfig"} +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +bindir=${bindir-'${exec_prefix}/bin'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +gzfileops=1 +unalignedok=1 +compat=0 +cover=0 +build32=0 +build64=0 +buildvpclmulqdq=1 +buildacle=1 +buildaltivec=1 +buildpower8=1 +buildpower9=1 +buildneon=1 +builddfltccdeflate=0 +builddfltccinflate=0 +buildcrc32vx=1 +floatabi= +native=0 +forcesse2=0 +# For CPUs that can benefit from AVX512, it seems GCC generates suboptimal +# instruction scheduling unless you specify a reasonable -mtune= target +avx512flag="-mavx512f -mavx512dq -mavx512bw -mavx512vl" +avx512vnniflag="${avx512flag} -mavx512vnni" +avx2flag="-mavx2" +sse2flag="-msse2" +ssse3flag="-mssse3" +sse42flag="-msse4.2" +pclmulflag="-mpclmul" +vpclmulflag="-mvpclmulqdq -mavx512f" +xsaveflag="-mxsave" +acleflag= +neonflag= +noltoflag="-fno-lto" +vgfmaflag="-march=z13" +vmxflag="-maltivec" +symbol_prefix="" +without_optimizations=0 +without_new_strategies=0 +reducedmem=0 +gcc=0 +warn=0 +debug=0 +visibility=1 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +INSTALLTARGETS="install-shared install-static" +UNINSTALLTARGETS="uninstall-shared uninstall-static" + +TEST="teststatic" + +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + +# process command line options +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--32] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + echo ' [--sprefix=SYMBOL_PREFIX] Adds a prefix to all exported symbols' | tee -a configure.log + echo ' [--warn] Enables extra compiler warnings' | tee -a configure.log + echo ' [--debug] Enables extra debug prints during operation' | tee -a configure.log + echo ' [--zlib-compat] Compiles for zlib-compatible API instead of zlib-ng API' | tee -a configure.log + echo ' [--without-unaligned] Compiles without fast unaligned access' | tee -a configure.log + echo ' [--without-gzfileops] Compiles without the gzfile parts of the API enabled' | tee -a configure.log + echo ' [--without-optimizations] Compiles without support for optional instruction sets' | tee -a configure.log + echo ' [--without-new-strategies] Compiles without using new additional deflate strategies' | tee -a configure.log + echo ' [--without-acle] Compiles without ARM C Language Extensions' | tee -a configure.log + echo ' [--without-neon] Compiles without ARM Neon SIMD instruction set' | tee -a configure.log + echo ' [--without-altivec] Compiles without PPC AltiVec support' | tee -a configure.log + echo ' [--without-power8] Compiles without Power8 instruction set' | tee -a configure.log + echo ' [--with-dfltcc-deflate] Use DEFLATE CONVERSION CALL instruction for compression on IBM Z' | tee -a configure.log + echo ' [--with-dfltcc-inflate] Use DEFLATE CONVERSION CALL instruction for decompression on IBM Z' | tee -a configure.log + echo ' [--without-crc32-vx] Build without vectorized CRC32 on IBM Z' | tee -a configure.log + echo ' [--with-reduced-mem] Reduced memory usage for special cases (reduces performance)' | tee -a configure.log + echo ' [--force-sse2] Assume SSE2 instructions are always available (disabled by default on x86, enabled on x86_64)' | tee -a configure.log + echo ' [--native] Compiles with full instruction set supported on this host' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -e*=* | --eprefix=*) exec_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -m*=* | --sprefix=*) symbol_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -l*=* | --libdir=*) libdir=$(echo $1 | sed 's/.*=//'); shift ;; + --sharedlibdir=*) sharedlibdir=$(echo $1 | sed 's/.*=//'); shift ;; + -i*=* | --includedir=*) includedir=$(echo $1 | sed 's/.*=//');shift ;; + -u*=* | --uname=*) uname=$(echo $1 | sed 's/.*=//');shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -m* | --sprefix) symbol_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --zlib-compat) compat=1; shift ;; + --without-unaligned) unalignedok=0; shift ;; + --without-gzfileops) gzfileops=0; shift ;; + --cover) cover=1; shift ;; + -3* | --32) build32=1; shift ;; + -6* | --64) build64=1; shift ;; + --without-vpclmulqdq) buildvpclmulqdq=0; shift ;; + --without-acle) buildacle=0; shift ;; + --without-neon) buildneon=0; shift ;; + --without-altivec) buildaltivec=0 ; shift ;; + --without-power8) buildpower8=0 ; shift ;; + --without-power9) buildpower9=0 ; shift ;; + --with-dfltcc-deflate) builddfltccdeflate=1; shift ;; + --with-dfltcc-inflate) builddfltccinflate=1; shift ;; + --without-crc32-vx) buildcrc32vx=0; shift ;; + --with-reduced-mem) reducedmem=1; shift ;; + --force-sse2) forcesse2=1; shift ;; + -n | --native) native=1; shift ;; + -a*=* | --archs=*) ARCHS=$(echo $1 | sed 's/.*=//'); shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + -noopt | --without-optimizations) without_optimizations=1; shift;; + -oldstrat | --without-new-strategies) without_new_strategies=1; shift;; + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; + + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + leave 1;; + esac +done + +# temporary file name +test=ztest$$ + +# put arguments in log, also put test file in log if used in arguments +show() +{ + case "$*" in + *$test.c*) + echo "=== $test.c ===" >> configure.log + cat $test.c >> configure.log + echo "===" >> configure.log;; + esac + echo $* >> configure.log +} + +# check for gcc vs. cc and set compile and link flags based on the system identified by uname +cat > $test.c <&1) in + *gcc*) gcc=1 ;; + *clang*) gcc=1 ;; +esac + +if test $native -eq 1; then + avx512flag="" + avx512vnniflag="" + avx2flag="" + sse2flag="" + ssse3flag="" + sse42flag="" + pclmulflag="" + vpclmulflag="" + xsaveflag="" + noltoflag="" +fi + +if test $build32 -eq 1; then + CFLAGS="${CFLAGS} -m32" + SFLAGS="${SFLAGS} -m32" + LDFLAGS="${LDFLAGS} -m32" +fi +if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + LDFLAGS="${LDFLAGS} -m64" +fi + +# Set library name depending on zlib-compat option +if test $compat -eq 0; then + LIBNAME=libz-ng + LIBNAME2=zlib-ng + SUFFIX=-ng +else + LIBNAME=libz + LIBNAME2=zlib + SUFFIX="" +fi + +STATICLIB=${LIBNAME}.a +MAPNAME=${LIBNAME2}.map + +# extract zlib version numbers from zlib.h +if test $compat -eq 0; then + VER=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER3=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER2=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER1=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) +else + VER=$(sed -n -e '/ZLIB_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib.h.in) + VER3=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib.h.in) + VER2=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) + VER1=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) +fi + +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc $CFLAGS -c $test.c) >> configure.log 2>&1; then + echo "$cc" | tee -a configure.log + CC="$cc" + CFLAGS="${CFLAGS} -std=c11" + + # Re-check ARCH if the compiler is a cross-compiler. + if $CC -print-multiarch 1> /dev/null 2>&1 && test -n "$($CC -print-multiarch)" 1> /dev/null 2>&1; then + CC_ARCH=$($CC $CFLAGS -print-multiarch | sed 's/-.*//g') + else + CC_ARCH=$($CC $CFLAGS -dumpmachine | sed 's/-.*//g') + fi + case $CC_ARCH in + i386 | i486 | i586 | i686) + # Honor user choice if gcc is multilib and 64-bit is requested + if test $build64 -eq 1; then + ARCH=x86_64 + else + ARCH=$CC_ARCH + fi ;; + x86_64) + # Honor user choice if gcc is multilib and 32-bit is requested + if test $build32 -ne 1; then + ARCH=$CC_ARCH + fi ;; + arm | armeb) + if test $native -eq 0; then + ARCH=arm + else + ARCH=native + fi + if test "${uname}" = "eabi"; then + # No ACLE support + uname=arm + if test $buildacle -eq 1; then + echo ACLE support not available + buildacle=0 + fi + fi + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH=armv8-a+crc + fi + fi ;; + armv8l) + if test $native -eq 0; then + ARCH=armv8-a + else + ARCH=native + fi ;; + aarch64 | aarch64_be | arm64) + if test "${uname}" = "elf"; then + uname=aarch64 + fi + if test $native -eq 0; then + ARCH=aarch64 + else + ARCH=native + fi ;; + powerpc | ppc) + ARCH=powerpc ;; + powerpc64 | ppc64) + ARCH=powerpc64 ;; + powerpc64le | ppc64le) + ARCH=powerpc64le ;; + esac + CFLAGS="-O2 ${CFLAGS}" + if test -n "${ARCHS}"; then + CFLAGS="${CFLAGS} ${ARCHS}" + LDFLAGS="${LDFLAGS} ${ARCHS}" + fi + CFLAGS="${CFLAGS} -Wall" + SFLAGS="${CFLAGS} -fPIC" + if test $native -eq 1; then + case $ARCH in + powerpc*) + NATIVE_FLAG="-mcpu=native" ;; + *) + NATIVE_FLAG="-march=native" ;; + esac + CFLAGS="${CFLAGS} ${NATIVE_FLAG}" + SFLAGS="${SFLAGS} ${NATIVE_FLAG}" + fi + if test "$warn" -eq 1; then + CFLAGS="${CFLAGS} -Wextra" + fi + if test $debug -eq 1; then + CFLAGS="${CFLAGS} -DZLIB_DEBUG" + SFLAGS="${SFLAGS} -DZLIB_DEBUG" + else + CFLAGS="${CFLAGS} -DNDEBUG" + SFLAGS="${SFLAGS} -DNDEBUG" + fi + if test -z "$uname"; then + uname=$((uname -s || echo unknown) 2>/dev/null) + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=cygz-ng$shared_ext + else + SHAREDLIB=cygz$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB},--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MSYS* | msys*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=msys-z-ng$shared_ext + else + SHAREDLIB=msys-z$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MINGW* | mingw*) + visibility=0 + ARFLAGS="rcs" + CFLAGS="${CFLAGS} -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1 -Wno-pedantic-ms-format" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + SHAREDLIB=${LIBNAME}-$VER1$shared_ext + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib=${IMPORTLIB} -Wl,--version-script=${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + if [ "$CC" == "mingw32-gcc" ]; then + case $ARCH in + i386 | i486 | i586 | i686) RCFLAGS="${RCFLAGS} -F pe-i386";; + esac; + fi + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-h${LIBNAME}.so.${VER1}" ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=${LIBNAME}$shared_ext + SHAREDLIBV=${LIBNAME}.$VER$shared_ext + SHAREDLIBM=${LIBNAME}.$VER1$shared_ext + SHAREDTARGET=$SHAREDLIBV + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3" + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi + ARFLAGS="-o" ;; + aarch64) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1} -Wl,--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="-Wl,--start-group -lc -lrdimon -Wl,--end-group" ;; + *) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo "$CC" | tee -a configure.log + if test -z "$uname"; then + uname=$((uname -sr || echo unknown) 2>/dev/null) + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"ld"} + LDSHAREDFLAGS="-b" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc"} + LDSHAREDFLAGS="-G" ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc"} + LDSHAREDFLAGS="-shared" ;; + esac +fi + +# Simplify some later conditionals +case "$uname" in +Linux* | linux*) + LINUX=1 ;; +*) + LINUX=0 ;; +esac + +# destination names for shared library if not defined above +SHAREDLIB=${SHAREDLIB-"${LIBNAME}$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"${LIBNAME}$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"${LIBNAME}$shared_ext.$VER1"} +SHAREDTARGET=${SHAREDTARGET-"${LIBNAME}$shared_ext.$VER"} + +echo >> configure.log + +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "$(\( $* \) 2>&1 | tee -a configure.log)" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code $ret)" >> configure.log + fi + return $ret + } +fi + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + +# see if shared library build supported +cat > $test.c <> configure.log + +# check for large file support, and if none, check for fseeko() +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main() { + _off64_t dummy = 0; + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for _off64_t... Yes." | tee -a configure.log + else + echo "Checking for _off64_t... No." | tee -a configure.log + fi + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = 0; + int ret = posix_memalign(&ptr, 64, 10); + if (ptr) + free(ptr); + return ret; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for posix_memalign... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_POSIX_MEMALIGN" + SFLAGS="${SFLAGS} -DHAVE_POSIX_MEMALIGN" +else + echo "Checking for posix_memalign... No." | tee -a configure.log +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = aligned_alloc(64, 10); + if (ptr) + free(ptr); + return 0; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for aligned_alloc... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_ALIGNED_ALLOC" + SFLAGS="${SFLAGS} -DHAVE_ALIGNED_ALLOC" +else + echo "Checking for aligned_alloc... No." | tee -a configure.log +fi +echo >> configure.log + +# check for strerror() for use by gz* functions +cat > $test.c < +#include +int main() { return strlen(strerror(errno)); } +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for strerror... Yes." | tee -a configure.log +else + CFLAGS="${CFLAGS} -DNO_STRERROR" + SFLAGS="${SFLAGS} -DNO_STRERROR" + echo "Checking for strerror... No." | tee -a configure.log +fi + +# check for getauxval() or elf_aux_info() for architecture feature detection at run-time +cat > $test.c < +int main() { +#ifdef __FreeBSD__ + int test; + return elf_aux_info(AT_PAGESZ, &test, sizeof(test)); +#else + return getauxval(0); +#endif +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for getauxval() or elf_aux_info() in sys/auxv.h... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_SYS_AUXV_H" + SFLAGS="${SFLAGS} -DHAVE_SYS_AUXV_H" +else + echo "Checking for getauxval() in sys/auxv.h... No." | tee -a configure.log +fi + +# We need to remove consigured files (zconf.h etc) from source directory if building outside of it +if [ "$SRCDIR" != "$BUILDDIR" ]; then + rm -f $SRCDIR/zconf${SUFFIX}.h + rm -f $SRCDIR/zlib${SUFFIX}.h + rm -f $SRCDIR/zlib_name_mangling${SUFFIX}.h +fi + +# Rename @ZLIB_SYMBOL_PREFIX@ to $symbol_prefix in gzread.c, zlib.h and zlib_name_mangling.h +sed < $SRCDIR/gzread.c.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > gzread.c +sed < $SRCDIR/zlib${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib${SUFFIX}.h +if [[ ! -z $symbol_prefix ]]; then + sed < $SRCDIR/zlib_name_mangling${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib_name_mangling${SUFFIX}.h +else + # symbol_prefix is not set, copy the empty mangling header + cp -p $SRCDIR/zlib_name_mangling.h.empty zlib_name_mangling${SUFFIX}.h +fi + +# copy clean zconf.h for subsequent edits +cp -p $SRCDIR/zconf${SUFFIX}.h.in zconf${SUFFIX}.h + +echo >> configure.log + +# check for unistd.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be set to #if 1/ 0\1 was set to #if 0/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +# check for ptrdiff_t and save result in zconf.h +echo -n "Checking for ptrdiff_t... " | tee -a configure.log +cat > $test.c < +int fun(ptrdiff_t *a) { (void)a; return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Yes." | tee -a configure.log +else + echo "No." | tee -a configure.log + sed < zconf${SUFFIX}.h "/^#ifdef NEED_PTRDIFF_T.* may be/s/def NEED_PTRDIFF_T\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + + echo -n "Checking for sizeof(void *)... " | tee -a configure.log + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int32_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int32_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int32_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int64_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int64_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int64_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + echo "unknown." | tee -a configure.log + exit 1 + fi + fi +fi + +# if --zlib-compat was requested +if test $compat -eq 1; then + gzfileops=1 + CFLAGS="${CFLAGS} -DZLIB_COMPAT" + SFLAGS="${SFLAGS} -DZLIB_COMPAT" + case "$uname" in + CYGWIN* | Cygwin* | cygwin* | MSYS* | msys* | MINGW* | mingw*) + DEFFILE="win32/zlibcompat.def" ;; + esac +fi + +if [[ ! -z $DEFFILE ]]; then + mkdir -p win32 + sed < $SRCDIR/$DEFFILE.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > $DEFFILE +fi + +# if --gzfileops was requested +if test $gzfileops -eq 1; then + CFLAGS="${CFLAGS} -DWITH_GZFILEOP" + SFLAGS="${SFLAGS} -DWITH_GZFILEOP" + OBJC="${OBJC} \$(OBJG)" + PIC_OBJC="${PIC_OBJC} \$(PIC_OBJG)" +else + TESTOBJG="\$(OBJG)" + PIC_TESTOBJG="\$(OBJG)" +fi + +# set architecture alignment requirements +if test $unalignedok -eq 0; then + CFLAGS="${CFLAGS} -DNO_UNALIGNED" + SFLAGS="${SFLAGS} -DNO_UNALIGNED" + echo "Unaligned reads manually disabled." | tee -a configure.log +fi + +# enable reduced memory configuration +if test $reducedmem -eq 1; then + echo "Configuring for reduced memory environment." | tee -a configure.log + CFLAGS="${CFLAGS} -DHASH_SIZE=32768u -DGZBUFSIZE=8192" +fi + +# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" + LDFLAGS="${LDFLAGS} -fprofile-arcs -ftest-coverage" + if test -n "$GCC_CLASSIC"; then + CC=$GCC_CLASSIC + fi +fi + +echo >> configure.log + +# Check for ANSI C compliant compiler +cat > $test.c < +#include +#include +#include "zconf${SUFFIX}.h" +int main() { +#ifdef STDC + return 0; +#endif + return 1; +} +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking for ANSI C compliant compiler... Yes." | tee -a configure.log + : +else + echo "Checking for ANSI C compliant compiler... No." | tee -a configure.log + echo "Error: ANSI C compatible compiler needed, cannot continue." | tee -a configure.log + leave 1 +fi + +# Check for -fno-semantic-interposition compiler support +echo "" > test.c + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-semantic-interposition... Yes." | tee -a configure.log + SFLAGS="$SFLAGS -fno-semantic-interposition" +else + echo "Checking for -fno-semantic-interposition... No." | tee -a configure.log +fi + +# Check for -fno-lto compiler support +if test $gcc -eq 1 -a $without_optimizations -eq 0 -a $native -eq 0; then + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-lto... Yes." | tee -a configure.log + else + echo "Checking for -fno-lto... No." | tee -a configure.log + noltoflag="" + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using hidden +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(hidden)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(hidden)) support... No." | tee -a configure.log + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using internal +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(internal)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(internal)) support... No." | tee -a configure.log + fi +fi + +# Check for attribute(aligned) support in compiler +cat > $test.c << EOF +int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for attribute(aligned) ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_ATTRIBUTE_ALIGNED" + SFLAGS="$SFLAGS -DHAVE_ATTRIBUTE_ALIGNED" +else + echo "Checking for attribute(aligned) ... No." | tee -a configure.log +fi + +# Check for _Thread_local support in compiler +cat > $test.c << EOF +_Thread_local int test; +int main(void) { + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for _Thread_local ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_THREAD_LOCAL" + SFLAGS="$SFLAGS -DHAVE_THREAD_LOCAL" +else + echo "Checking for _Thread_local ... No." | tee -a configure.log +fi + +# Check for __builtin_ctz() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctz ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZ" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZ" +else + echo "Checking for __builtin_ctz ... No." | tee -a configure.log +fi + +# Check for __builtin_ctzll() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned long long zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctzll ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZLL" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZLL" +else + echo "Checking for __builtin_ctzll ... No." | tee -a configure.log +fi + +check_avx2_intrinsics() { + # Check whether compiler supports AVX2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx2flag} $test.c; then + echo "Checking for AVX2 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX2_INTRIN=1 + else + echo "Checking for AVX2 intrinsics ... No." | tee -a configure.log + HAVE_AVX2_INTRIN=0 + fi +} + +check_avx512_intrinsics() { + # Check whether compiler supports AVX512 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for AVX512 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512_INTRIN=1 + else + echo "Checking for AVX512 intrinsics ... No." | tee -a configure.log + HAVE_AVX512_INTRIN=0 + fi +} + +check_mtune_skylake_avx512_compiler_flag() { + # Check whether -mtune=skylake-avx512 works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=skylake-avx512 $test.c; then + MTUNE_SKYLAKE_AVX512_AVAILABLE=1 + echo "Check whether -mtune=skylake-avx512 works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=skylake-avx512 works ... No." | tee -a configure.log + MTUNE_SKYLAKE_AVX512_AVAILABLE=0 + fi +} + +check_mtune_cascadelake_compiler_flag() { + # Check whether -mtune=cascadelake works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=cascadelake $test.c; then + MTUNE_CASCADELAKE_AVAILABLE=1 + echo "Check whether -mtune=cascadelake works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=cascadelake works ... No." | tee -a configure.log + MTUNE_CASCADELAKE_AVAILABLE=0 + check_mtune_skylake_avx512_compiler_flag + fi +} + +check_avx512vnni_intrinsics() { + # Check whether compiler supports AVX512-VNNI intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512vnniflag} $test.c; then + echo "Checking for AVX512VNNI intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=1 + else + echo "Checking for AVX512VNNI intrinsics ... No." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=0 + fi +} + +check_mask_intrinsics() { + # Check whether compiler supports AVX512 k-mask intrinsics + cat > $test.c << EOF +#include +int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for AVX512 k-mask intrinsics ... Yes." | tee -a configure.log + HAVE_MASK_INTRIN=1 + else + echo "Checking for AVX512 k-mask intrinsics ... No." | tee -a configure.log + HAVE_MASK_INTRIN=0 + fi +} + +check_acle_compiler_flag() { + # Check whether -march=armv8-a+crc works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -march=armv8-a+crc $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc works ... Yes." | tee -a configure.log + else + echo "Check whether -march=armv8-a+crc works ... No." | tee -a configure.log + if try $CC -c $CFLAGS -march=armv8-a+crc+simd $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc+simd works ... Yes." | tee -a configure.log + if test "$ARCH" = "armv8-a+crc"; then + ARCH=armv8-a+crc+simd + fi + else + ACLE_AVAILABLE=0 + echo "Check whether -march=armv8-a+crc+simd works ... No." | tee -a configure.log + fi + fi +} + +check_neon_compiler_flag() { + # Check whether -mfpu=neon is available on ARM processors. + cat > $test.c << EOF +#ifdef _M_ARM64 + # include + #else + # include +#endif +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mfpu=neon $test.c; then + MFPU_NEON_AVAILABLE=1 + echo "Check whether -mfpu=neon is available ... Yes." | tee -a configure.log + else + MFPU_NEON_AVAILABLE=0 + echo "Check whether -mfpu=neon is available ... No." | tee -a configure.log + fi +} + +check_neon_ld4_intrinsics() { + if test $buildneon -eq 1 && test $native -eq 0; then + if test "$CC_ARCH" = "aarch64" || test "$CC_ARCH" = "aarch64_be" || test "$CC_ARCH" = "arm64"; then + neonflag="-march=armv8-a+simd" + elif test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + fi + cat > $test.c << EOF +#ifdef _M_ARM64 +# include +#else +# include +#endif +int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; +} +EOF + if try $CC -c $CFLAGS $neonflag $test.c; then + NEON_HAS_LD4=1 + echo "check whether compiler supports 4 wide register loads ... Yes." | tee -a configure.log + else + NEON_HAS_LD4=0 + echo "check whether compiler supports 4 wide register loads ... No." | tee -a configure.log + fi +} + +check_pclmulqdq_intrinsics() { + # Check whether compiler supports PCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${pclmulflag} $test.c; then + echo "Checking for PCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=1 + else + echo "Checking for PCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=0 + fi +} + +check_vpclmulqdq_intrinsics() { + # Check whether compiler supports VPCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${vpclmulflag} $test.c; then + echo "Checking for VPCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=1 + else + echo "Checking for VPCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=0 + fi +} + +check_xsave_intrinsics() { + # Check whether compiler supports XSAVE intrinsics + cat > $test.c << EOF +#ifdef _WIN32 +# include +#else +# include +#endif +int main(void) { + return _xgetbv(0); +} +EOF + if try ${CC} ${CFLAGS} ${xsaveflag} $test.c; then + echo "Checking for XSAVE intrinsics ... Yes." | tee -a configure.log + HAVE_XSAVE_INTRIN=1 + else + echo "Checking for XSAVE intrinsics ... No." | tee -a configure.log + HAVE_XSAVE_INTRIN=0 + fi +} + +check_ppc_intrinsics() { + cat > $test.c << EOF +#include +int main(void) +{ + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; +} +EOF + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec $test.c; then + echo "Checking for AltiVec intrinsics ... Yes." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=1 + else + echo "Checking for AltiVec intrinsics ... No." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=0 + fi + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec -mno-vsx $test.c; then + echo "Checking if -mno-vsx is supported ... Yes." | tee -a configure.log + vmxflag="$vmxflag -mno-vsx" + else + echo "Checking if -mno-vsx is supported ... No." | tee -a configure.log + fi + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); +#else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); +#endif +} +EOF + if try $CC -c $CFLAGS -maltivec $test.c; then + HAVE_VMX=1 + echo "Check whether VMX instructions are available ... Yes." | tee -a configure.log + else + HAVE_VMX=0 + echo "Check whether VMX instructions are available ... No." | tee -a configure.log + fi +} + +check_power8_intrinsics() { + # Check whether features needed by POWER8 optimisations are available + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); +#else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); +#endif +} +EOF + if test $buildpower8 -eq 1 && try $CC -c $CFLAGS -mcpu=power8 $test.c; then + HAVE_POWER8_INTRIN=1 + echo "Check whether POWER8 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER8_INTRIN=0 + echo "Check whether POWER8 instructions are available ... No." | tee -a configure.log + fi +} + +check_power9_intrinsics() { + # Check whether features needed by POWER9 optimisations are available + cat > $test.c << EOF +int main() { return 0; } +EOF + if test $buildpower9 -eq 1 && try $CC -c $CFLAGS -mcpu=power9 $test.c; then + HAVE_POWER9_INTRIN=1 + echo "Check whether POWER9 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER9_INTRIN=0 + echo "Check whether POWER9 instructions are available ... No." | tee -a configure.log + fi +} + +check_sse2_intrinsics() { + # Check whether compiler supports SSE2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse2flag} $test.c; then + echo "Checking for SSE2 intrinsics ... Yes." | tee -a configure.log + HAVE_SSE2_INTRIN=1 + else + echo "Checking for SSE2 intrinsics ... No." | tee -a configure.log + HAVE_SSE2_INTRIN=0 + fi +} + +check_sse42_intrinsics() { + # Check whether compiler supports SSE4.2 CRC inline asm + cat > $test.c << EOF +int main(void) { + unsigned val = 0, h = 0; + __asm__ __volatile__ ( "crc32 %1,%0" : "+r" (h) : "r" (val) ); + return (int) h; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC inline assembly ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=1 + else + echo "Checking for SSE4.2 CRC inline assembly ... No." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=0 + fi + + # Check whether compiler supports SSE4.2 CRC intrinsics + cat > $test.c << EOF +int main(void) { + unsigned crc = 0; + char c = 'c'; + crc = __builtin_ia32_crc32qi(crc, c); + (void)crc; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC intrinsics ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=1 + else + echo "Checking for SSE4.2 CRC intrinsics ... No." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=0 + fi +} + +check_ssse3_intrinsics() { + # Check whether compiler supports SSSE3 intrinsics + cat > $test.c << EOF +#include +int main(void) +{ + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${ssse3flag} $test.c; then + echo "Checking for SSSE3 intrinsics ... Yes." | tee -a configure.log + HAVE_SSSE3_INTRIN=1 + else + echo "Checking for SSSE3 intrinsics ... No." | tee -a configure.log + HAVE_SSSE3_INTRIN=0 + fi +} + +check_vgfma_intrinsics() { + # Check whether "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic is available + echo -n "Checking for -mzarch... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -mzarch; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -mzarch" + else + echo No. | tee -a configure.log + fi + echo -n "Checking for -fzvector... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -fzvector; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -fzvector" + else + echo No. | tee -a configure.log + fi + cat > $test.c << EOF +#include +int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; +} +EOF + echo -n "Checking for VGFMA support... " | tee -a configure.log + if try $CC -c $CFLAGS $vgfmaflag $test.c; then + HAVE_VGFMA_INTRIN=1 + echo "Yes." | tee -a configure.log + else + HAVE_VGFMA_INTRIN=0 + echo "No." | tee -a configure.log + fi +} + +case "${ARCH}" in + i386 | i486 | i586 | i686 | x86_64) + # Enable deflate_medium at level 1 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_QUICK_STRATEGY" + SFLAGS="${SFLAGS} -DNO_QUICK_STRATEGY" + fi + # Enable deflate_medium at level 4-6 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_MEDIUM_STRATEGY" + SFLAGS="${SFLAGS} -DNO_MEDIUM_STRATEGY" + fi + ;; +esac + +ARCHDIR='arch/generic' +ARCH_STATIC_OBJS='' +ARCH_SHARED_OBJS='' + +# Set ARCH specific FLAGS +case "${ARCH}" in + # x86/amd64 specific optimizations + i386 | i486 | i586 | i686 |x86_64) + ARCHDIR=arch/x86 + + # Enable arch-specific optimizations + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DX86_FEATURES" + SFLAGS="${SFLAGS} -DX86_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} x86_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} x86_features.lo" + + check_avx2_intrinsics + + if test ${HAVE_AVX2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX2" + SFLAGS="${SFLAGS} -DX86_AVX2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} slide_hash_avx2.o chunkset_avx2.o compare256_avx2.o adler32_avx2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} slide_hash_avx2.lo chunkset_avx2.lo compare256_avx2.lo adler32_avx2.lo" + fi + + check_avx512_intrinsics + + if test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512" + SFLAGS="${SFLAGS} -DX86_AVX512" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512.lo" + + check_mask_intrinsics + + if test ${HAVE_MASK_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_MASK_INTRIN" + SFLAGS="${SFLAGS} -DX86_MASK_INTRIN" + fi + fi + + check_mtune_cascadelake_compiler_flag + + if test ${MTUNE_CASCADELAKE_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=cascadelake" + avx512vnniflag="${avx512vnniflag} -mtune=cascadelake" + else + if test ${MTUNE_SKYLAKE_AVX512_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=skylake-avx512" + avx512vnniflag="${avx512vnniflag} -mtune=skylake-avx512" + fi + fi + + check_avx512vnni_intrinsics + + if test ${HAVE_AVX512VNNI_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512VNNI" + SFLAGS="${SFLAGS} -DX86_AVX512VNNI" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512_vnni.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512_vnni.lo" + fi + + check_sse42_intrinsics + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1 || test ${HAVE_SSE42CRC_INLINE_ASM} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42" + SFLAGS="${SFLAGS} -DX86_SSE42" + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42_CRC_INTRIN" + SFLAGS="${SFLAGS} -DX86_SSE42_CRC_INTRIN" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_sse42.o insert_string_sse42.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_sse42.lo insert_string_sse42.lo" + fi + + check_sse2_intrinsics + + if test ${HAVE_SSE2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE2" + SFLAGS="${SFLAGS} -DX86_SSE2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} chunkset_sse2.o compare256_sse2.o slide_hash_sse2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} chunkset_sse2.lo compare256_sse2.lo slide_hash_sse2.lo" + + if test $forcesse2 -eq 1; then + CFLAGS="${CFLAGS} -DX86_NOCHECK_SSE2" + SFLAGS="${SFLAGS} -DX86_NOCHECK_SSE2" + fi + fi + + check_ssse3_intrinsics + + if test ${HAVE_SSSE3_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSSE3" + SFLAGS="${SFLAGS} -DX86_SSSE3" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_ssse3.o chunkset_ssse3.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_ssse3.lo chunkset_ssse3.lo" + fi + + check_pclmulqdq_intrinsics + + if test ${HAVE_PCLMULQDQ_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_PCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_PCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_pclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_pclmulqdq.lo" + + if test $buildvpclmulqdq -eq 1; then + check_vpclmulqdq_intrinsics + + if test ${HAVE_VPCLMULQDQ_INTRIN} -eq 1 && test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_VPCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_VPCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_vpclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_vpclmulqdq.lo" + fi + fi + fi + + check_xsave_intrinsics + + if test ${HAVE_XSAVE_INTRIN} -eq 0; then + xsaveflag="" + fi + fi + ;; + + # ARM specific optimizations + arm*) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=arm + ARCHDIR=arch/arm + + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + cat > $test.c < +#include +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + else + echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + echo "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + fi + fi + + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=softfp && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=softfp" + else + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=hard && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=hard" + fi + fi + + if [ -z $floatabi ]; then + echo "ARM floating point arch not auto-detected" | tee -a configure.log + else + echo "ARM floating point arch: ${floatabi}" | tee -a configure.log + + CFLAGS="${CFLAGS} ${floatabi}" + SFLAGS="${SFLAGS} ${floatabi}" + fi + + if test $without_optimizations -eq 0; then + check_acle_compiler_flag + check_neon_compiler_flag + check_neon_ld4_intrinsics + fi + + case "${ARCH}" in + armv[345]*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + armv6l | armv6hl) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + arm | armv7*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a | armv8-a+simd) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a+crc | armv8-a+crc+simd | armv8.[1234]-a | armv8.[1234]-a+simd) + acleflag="-march=${ARCH}" + + if test $without_optimizations -eq 0; then + if test $ACLE_AVAILABLE -eq 1; then + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + esac + + ;; + # 64-bit ARM specific optimizations + aarch64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=aarch64 + ARCHDIR=arch/arm + + if test $native -eq 0; then + ARCH="armv8-a" + else + ARCH="native" + fi + + if test $without_optimizations -eq 0; then + check_neon_ld4_intrinsics + + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + echo "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+crc" + fi + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+simd" + fi + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + + neonflag="-march=${ARCH}" + acleflag="-march=${ARCH}" + ;; + powerpc*) + case "${ARCH}" in + powerpc) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc + ;; + powerpc64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64 + ;; + powerpc64le) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64le + ;; + esac + + ARCHDIR=arch/power + + if test $without_optimizations -eq 0; then + + check_ppc_intrinsics + check_power8_intrinsics + check_power9_intrinsics + + if test $HAVE_VMX -eq 1; then + CFLAGS="${CFLAGS} -DPPC_FEATURES" + SFLAGS="${SFLAGS} -DPPC_FEATURES" + fi + if test $HAVE_VMX -eq 1 -o $HAVE_POWER8_INTRIN -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} power_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} power_features.lo" + fi + if test $HAVE_VMX -eq 1 -a $HAVE_ALTIVEC_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPPC_VMX" + SFLAGS="${SFLAGS} -DPPC_VMX" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_vmx.o slide_hash_vmx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_vmx.lo slide_hash_vmx.lo" + fi + if test $HAVE_POWER8_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_power8.o chunkset_power8.o slide_hash_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_power8.lo chunkset_power8.lo slide_hash_power8.lo" + case "${ARCH}" in + powerpc64*) + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_power8.lo" + CFLAGS="${CFLAGS} -DPOWER8_VSX_CRC32" + SFLAGS="${SFLAGS} -DPOWER8_VSX_CRC32" + ;; + esac + fi + if test $HAVE_POWER9_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER9 -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER9 -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} compare256_power9.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} compare256_power9.lo" + fi + fi + ;; + s390x) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=s390x + ARCHDIR=arch/s390 + + if test $without_optimizations -eq 0; then + if test $buildcrc32vx -eq 1; then + CFLAGS="${CFLAGS} -DS390_FEATURES" + SFLAGS="${SFLAGS} -DS390_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} s390_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} s390_features.lo" + fi + + if test $builddfltccdeflate -eq 1 -o $builddfltccinflate -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_common.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_common.lo" + fi + + if test $builddfltccdeflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_DEFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_DEFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_deflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_deflate.lo" + ARCH="${ARCH}+dfltcc-deflate" + fi + + if test $builddfltccinflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_INFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_INFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_inflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_inflate.lo" + ARCH="${ARCH}+dfltcc-inflate" + fi + + if test $buildcrc32vx -eq 1; then + check_vgfma_intrinsics + if test $HAVE_VGFMA_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DS390_CRC32_VX" + SFLAGS="${SFLAGS} -DS390_CRC32_VX" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32-vx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32-vx.lo" + ARCH="${ARCH}+crc32-vx" + fi + fi + fi + ;; + *) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=$ARCH + ;; +esac + +echo "ARCH: ${ARCH}" +echo "Using arch directory: ${ARCHDIR}" +echo "Architecture-specific static object files:${ARCH_STATIC_OBJS}" +echo "Architecture-specific shared object files:${ARCH_SHARED_OBJS}" + +# show the results in the log +echo >> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDFLAGS = $LDSHAREDFLAGS >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo DEFFILE = $DEFFILE >> configure.log +echo RC = $RC >> configure.log +echo RCFLAGS = $RCFLAGS >> configure.log +echo RCOBJS = $RCOBJS >> configure.log +echo STRIP = $STRIP >> configure.log +echo OBJC = $OBJC >> configure.log +echo TESTOBJG = $TESTOBJG >> configure.log +echo PIC_TESTOBJG = $PIC_TESTOBJG >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo SHAREDTARGET = $SHAREDTARGET >> configure.log +echo IMPORTLIB = $IMPORTLIB >> configure.log +echo INSTALLTARGETS = $INSTALLTARGETS >> configure.log +echo UNINSTALLTARGETS = $UNINSTALLTARGETS >> configure.log +echo SRCDIR = $SRCDIR >> configure.log +echo BUILDDIR = $BUILDDIR >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo bindir = $bindir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo symbol_prefix = $symbol_prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log +echo sse2flag = $sse2flag >> configure.log +echo ssse3flag = $ssse3flag >> configure.log +echo sse42flag = $sse42flag >> configure.log +echo pclmulflag = $pclmulflag >> configure.log +echo vpclmulflag = $vpclmulflag >> configure.log +echo xsaveflag = $xsaveflag >> configure.log +echo acleflag = $acleflag >> configure.log +echo neonflag = $neonflag >> configure.log +echo ARCHDIR = ${ARCHDIR} >> configure.log +echo ARCH_STATIC_OBJS = ${ARCH_STATIC_OBJS} >> configure.log +echo ARCH_SHARED_OBJS = ${ARCH_SHARED_OBJS} >> configure.log + +# Handle sed incompatibilities when using -i +replace_in_file() { + if [ "$OS" = 'Darwin' ]; then + sed -i '.tmp' -e "$1" "$2" + else + sed -i'.tmp' -e "$1" "$2" + fi +} + +# update Makefile with the configure results + +INCLUDES="-I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then INCLUDES="-I$BUILDDIR ${INCLUDES}"; fi + +sed < $SRCDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^LIBNAME1 *=/s#=.*#=$LIBNAME# +/^LIBNAME2 *=/s#=.*#=$LIBNAME2# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^SHAREDTARGET *=/s#=.*#=$SHAREDTARGET# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^VER *=/s#=.*#=$VER# +/^VER1 *=/s#=.*#=$VER1# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^DEFFILE *=/s#=.*#=$DEFFILE# +/^RC *=/s#=.*#=$RC# +/^RCFLAGS *=/s#=.*#=$RCFLAGS# +/^RCOBJS *=/s#=.*#=$RCOBJS# +/^STRIP *=/s#=.*#=$STRIP# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#= $prefix# +/^exec_prefix *=/s#=.*#= $exec_prefix# +/^bindir *=/s#=.*#= $bindir# +/^symbol_prefix *=/s#=.*#= $symbol_prefix# +/^libdir *=/s#=.*#= $libdir# +/^sharedlibdir *=/s#=.*#= $sharedlibdir# +/^includedir *=/s#=.*#= $includedir# +/^mandir *=/s#=.*#= $mandir# +/^SRCDIR *=/s#=.*#=$SRCDIR# +/^INCLUDES *=/s#=.*#=$INCLUDES# +/^OBJC *=/s#=.*#= $OBJC# +/^TESTOBJG *=/s#=.*#= $TESTOBJG# +/^PIC_TESTOBJG *=/s#=.*#= $PIC_TESTOBJG# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^install-libs: */s#:.*#: $INSTALLTARGETS# +/^uninstall-libs: */s#:.*#: $UNINSTALLTARGETS# +/^ARCHDIR *=/s#=.*#=$ARCHDIR# +/^ARCH_STATIC_OBJS *=/s#=.*#=$ARCH_STATIC_OBJS# +/^ARCH_SHARED_OBJS *=/s#=.*#=$ARCH_SHARED_OBJS# +" > Makefile + +# Append header files dependencies. +for file in $SRCDIR/*.c $SRCDIR/test/*.c $SRCDIR/test/fuzz/*.c $SRCDIR/$ARCHDIR/*.c $SRCDIR/tools/*.c; do + if test ! -f $file; then + continue + fi + + short_name=$(echo $file | sed -e "s#$SRCDIR/##g") + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$ARCHDIR/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + + if grep -q "^$obj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + + # In case this is one of the ARCHDIR files, append a dependence line + # that will force the `$(MAKE) -C $(ARCHDIR)` generic rule. Without this + # we would only execute the copy rule from ARCHDIR to SRCDIR. + if test -e $SRCDIR/$ARCHDIR/$(basename $file); then + echo "$ARCHDIR/$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi + fi + + if grep -q "^$lobj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi +done + +# Generate Makefile in arch dir +mkdir -p $ARCHDIR + +ARCHINCLUDES="-I$SRCDIR/$ARCHDIR -I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then ARCHINCLUDES="-I$BUILDDIR ${ARCHINCLUDES}"; fi + +sed < $SRCDIR/$ARCHDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^INCLUDES *=/s#=.*#=$ARCHINCLUDES# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^SRCDIR *=/s#=.*#=$SRCDIR/$ARCHDIR# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^BUILDDIR *=/s#=.*#=$BUILDDIR# +/^AVX2FLAG *=/s#=.*#=$avx2flag# +/^AVX512FLAG *=/s#=.*#=$avx512flag# +/^AVX512VNNIFLAG *=/s#=.*#=$avx512vnniflag# +/^SSE2FLAG *=/s#=.*#=$sse2flag# +/^SSSE3FLAG *=/s#=.*#=$ssse3flag# +/^SSE42FLAG *=/s#=.*#=$sse42flag# +/^PCLMULFLAG *=/s#=.*#=$pclmulflag# +/^VPCLMULFLAG *=/s#=.*#=$vpclmulflag# +/^XSAVEFLAG *=/s#=.*#=$xsaveflag# +/^ACLEFLAG *=/s#=.*#=$acleflag# +/^NEONFLAG *=/s#=.*#=$neonflag# +/^NOLTOFLAG *=/s#=.*#=$noltoflag# +/^VGFMAFLAG *=/s#=.*#=$vgfmaflag# +/^PPCFLAGS *=/s#=.*#=$vmxflag# +" > $ARCHDIR/Makefile + +# Append header files dependencies. +for file in $SRCDIR/$ARCHDIR/*.c; do + if test ! -f $file; then + continue + fi + + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCTOP)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + short_name=$(basename $file) + if grep -q "^$obj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi + + if grep -q "^$lobj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi +done + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if test "$CHOST" != "wasm32"; then + TEST="${TEST} ghtests" +fi + +# Determine emulator to use when running tests +if test -z "$EMU_RUN" && test $QEMU_ARCH; then + EMU_RUN="qemu-$QEMU_ARCH -L /usr/${CHOST}/" +fi +if test -n "$EMU_RUN"; then + echo "Using cross-compile emulator: $EMU_RUN" +fi + +# Generate Makefile in test dir +mkdir -p test +sed < $SRCDIR/test/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^EXE *=/s#=.*#=$EXE# +/^alltests: */s#:.*#: $TEST# +/^SRCDIR *=/s#=.*#=$SRCDIR/test# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^EMU_RUN *=/s#=.*#=$EMU_RUN# +/^LIBNAME *=/s#=.*#=$LIBNAME# +" > test/Makefile + +# create zlib.pc with the configure results +sed < $SRCDIR/zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^bindir *=/s#=.*#=$bindir# +/^symbol_prefix *=/s#=.*#=$symbol_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +s/\@SUFFIX\@/$SUFFIX/g; +" > ${LIBNAME2}.pc + +# done +leave 0 diff --git a/internal-complibs/zlib-ng-2.1.2/cpu_features.c b/internal-complibs/zlib-ng-2.1.2/cpu_features.c new file mode 100644 index 000000000..3585172e5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cpu_features.c @@ -0,0 +1,23 @@ +/* cpu_features.c -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "cpu_features.h" +#include + +Z_INTERNAL void cpu_check_features(struct cpu_features *features) { + memset(features, 0, sizeof(struct cpu_features)); +#if defined(X86_FEATURES) + x86_check_features(&features->x86); +#elif defined(ARM_FEATURES) + arm_check_features(&features->arm); +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + power_check_features(&features->power); +#elif defined(S390_FEATURES) + s390_check_features(&features->s390); +#elif defined(RISCV_FEATURES) + riscv_check_features(&features->riscv); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.2/cpu_features.h b/internal-complibs/zlib-ng-2.1.2/cpu_features.h new file mode 100644 index 000000000..647d027f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/cpu_features.h @@ -0,0 +1,274 @@ +/* cpu_features.h -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CPU_FEATURES_H_ +#define CPU_FEATURES_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +#if defined(X86_FEATURES) +# include "arch/x86/x86_features.h" +# include "fallback_builtins.h" +#elif defined(ARM_FEATURES) +# include "arch/arm/arm_features.h" +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) +# include "arch/power/power_features.h" +#elif defined(S390_FEATURES) +# include "arch/s390/s390_features.h" +#elif defined(RISCV_FEATURES) +# include "arch/riscv/riscv_features.h" +#endif + +struct cpu_features { +#if defined(X86_FEATURES) + struct x86_cpu_features x86; +#elif defined(ARM_FEATURES) + struct arm_cpu_features arm; +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + struct power_cpu_features power; +#elif defined(S390_FEATURES) + struct s390_cpu_features s390; +#elif defined(RISCV_FEATURES) + struct riscv_cpu_features riscv; +#else + char empty; +#endif +}; + +extern void cpu_check_features(struct cpu_features *features); + +/* adler32 */ +typedef uint32_t (*adler32_func)(uint32_t adler, const uint8_t *buf, size_t len); + +extern uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len); +#ifdef ARM_NEON +extern uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef PPC_VMX +extern uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_SSSE3 +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_avx2(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_avx512(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef POWER8_VSX +extern uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len); +#endif + +/* adler32 folding */ +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +/* CRC32 folding */ +#ifdef X86_PCLMULQDQ_CRC +extern uint32_t crc32_fold_pclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_pclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_pclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_pclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_pclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) +extern uint32_t crc32_fold_vpclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_vpclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_vpclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_vpclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif + +/* memory chunking */ +extern uint32_t chunksize_c(void); +extern uint8_t* chunkmemset_safe_c(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#ifdef X86_SSE2 +extern uint32_t chunksize_sse2(void); +extern uint8_t* chunkmemset_safe_sse2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_SSSE3 +extern uint8_t* chunkmemset_safe_ssse3(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_AVX2 +extern uint32_t chunksize_avx2(void); +extern uint8_t* chunkmemset_safe_avx2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef ARM_NEON +extern uint32_t chunksize_neon(void); +extern uint8_t* chunkmemset_safe_neon(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef POWER8_VSX +extern uint32_t chunksize_power8(void); +extern uint8_t* chunkmemset_safe_power8(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +/* inflate fast loop */ +extern void inflate_fast_c(PREFIX3(stream) *strm, uint32_t start); +#ifdef X86_SSE2 +extern void inflate_fast_sse2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_SSSE3 +extern void inflate_fast_ssse3(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_AVX2 +extern void inflate_fast_avx2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef ARM_NEON +extern void inflate_fast_neon(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef POWER8_VSX +extern void inflate_fast_power8(PREFIX3(stream) *strm, uint32_t start); +#endif + +/* CRC32 */ +typedef uint32_t (*crc32_func)(uint32_t crc32, const uint8_t *buf, size_t len); + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); +#ifdef ARM_ACLE +extern uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(POWER8_VSX) +extern uint32_t crc32_power8(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(S390_CRC32_VX) +extern uint32_t crc32_s390_vx(uint32_t crc, const uint8_t *buf, size_t len); +#endif + +/* compare256 */ +typedef uint32_t (*compare256_func)(const uint8_t *src0, const uint8_t *src1); + +extern uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1); +#endif +#ifdef POWER9 +extern uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1); +#endif + +#ifdef DEFLATE_H_ +/* insert_string */ +extern void insert_string_c(deflate_state *const s, const uint32_t str, uint32_t count); +#ifdef X86_SSE42 +extern void insert_string_sse42(deflate_state *const s, const uint32_t str, uint32_t count); +#elif defined(ARM_ACLE) +extern void insert_string_acle(deflate_state *const s, const uint32_t str, uint32_t count); +#endif + +/* longest_match */ +extern uint32_t longest_match_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_unaligned_16(deflate_state *const s, Pos cur_match); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t longest_match_unaligned_32(deflate_state *const s, Pos cur_match); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_power9(deflate_state *const s, Pos cur_match); +#endif + +/* longest_match_slow */ +extern uint32_t longest_match_slow_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_slow_unaligned_16(deflate_state *const s, Pos cur_match); +extern uint32_t longest_match_slow_unaligned_32(deflate_state *const s, Pos cur_match); +#ifdef UNALIGNED64_OK +extern uint32_t longest_match_slow_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_slow_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_slow_power9(deflate_state *const s, Pos cur_match); +#endif + +/* quick_insert_string */ +extern Pos quick_insert_string_c(deflate_state *const s, const uint32_t str); +#ifdef X86_SSE42 +extern Pos quick_insert_string_sse42(deflate_state *const s, const uint32_t str); +#elif defined(ARM_ACLE) +extern Pos quick_insert_string_acle(deflate_state *const s, const uint32_t str); +#endif + +/* slide_hash */ +typedef void (*slide_hash_func)(deflate_state *s); + +#ifdef X86_SSE2 +extern void slide_hash_sse2(deflate_state *s); +#elif defined(ARM_NEON) +extern void slide_hash_neon(deflate_state *s); +#endif +#if defined(PPC_VMX) +extern void slide_hash_vmx(deflate_state *s); +#endif +#if defined(POWER8_VSX) +extern void slide_hash_power8(deflate_state *s); +#endif +#ifdef X86_AVX2 +extern void slide_hash_avx2(deflate_state *s); +#endif + +/* update_hash */ +extern uint32_t update_hash_c(deflate_state *const s, uint32_t h, uint32_t val); +#ifdef X86_SSE42 +extern uint32_t update_hash_sse42(deflate_state *const s, uint32_t h, uint32_t val); +#elif defined(ARM_ACLE) +extern uint32_t update_hash_acle(deflate_state *const s, uint32_t h, uint32_t val); +#endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_braid.c b/internal-complibs/zlib-ng-2.1.2/crc32_braid.c new file mode 100644 index 000000000..96754b53d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_braid.c @@ -0,0 +1,267 @@ +/* crc32_braid.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "functable.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" + +/* ========================================================================= */ + +const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) { + return (const uint32_t *)crc_table; +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return (unsigned long)functable.crc32((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return functable.crc32(crc, buf, len); +} +#endif + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32)(unsigned long crc, const unsigned char *buf, unsigned int len) { + return (unsigned long)PREFIX(crc32_z)((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t len) { + return PREFIX(crc32_z)(crc, buf, len); +} +#endif + +/* ========================================================================= */ + +/* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32 tables would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. +*/ + +/* ========================================================================= */ + +#if BYTE_ORDER == LITTLE_ENDIAN +# define ZSWAPWORD(word) (word) +# define BRAID_TABLE crc_braid_table +#elif BYTE_ORDER == BIG_ENDIAN +# if W == 8 +# define ZSWAPWORD(word) ZSWAP64(word) +# elif W == 4 +# define ZSWAPWORD(word) ZSWAP32(word) +# endif +# define BRAID_TABLE crc_braid_big_table +#else +# error "No endian defined" +#endif +#define DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +#ifdef W +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +#if BYTE_ORDER == LITTLE_ENDIAN +static uint32_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (uint32_t)data; +} +#elif BYTE_ORDER == BIG_ENDIAN +static z_word_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} +#endif /* BYTE_ORDER */ + +#endif /* W */ + +/* ========================================================================= */ +Z_INTERNAL uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + + /* Pre-condition the CRC */ + c = (~crc) & 0xffffffff; + +#ifdef W + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + size_t blks; + z_word_t const *words; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((uintptr_t)buf & (W - 1)) != 0) { + len--; + DO1; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + /* Initialize the CRC for each braid. */ + crc0 = ZSWAPWORD(c); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + /* Process the first blks-1 blocks, computing the CRCs on each braid independently. */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should get unrolled. */ + crc0 = BRAID_TABLE[0][word0 & 0xff]; +#if N > 1 + crc1 = BRAID_TABLE[0][word1 & 0xff]; +#if N > 2 + crc2 = BRAID_TABLE[0][word2 & 0xff]; +#if N > 3 + crc3 = BRAID_TABLE[0][word3 & 0xff]; +#if N > 4 + crc4 = BRAID_TABLE[0][word4 & 0xff]; +#if N > 5 + crc5 = BRAID_TABLE[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= BRAID_TABLE[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= BRAID_TABLE[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= BRAID_TABLE[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= BRAID_TABLE[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= BRAID_TABLE[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= BRAID_TABLE[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* Process the last block, combining the CRCs of the N braids at the same time. */ + comb = crc_word(crc0 ^ words[0]); +#if N > 1 + comb = crc_word(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + c = ZSWAPWORD(comb); + + /* Update the pointer to the remaining bytes to process. */ + buf = (const unsigned char *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + DO8; + } + while (len) { + len--; + DO1; + } + + /* Return the CRC, post-conditioned. */ + return c ^ 0xffffffff; +} diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb.c b/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb.c new file mode 100644 index 000000000..75fb47425 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb.c @@ -0,0 +1,57 @@ +/* crc32_braid_comb.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" +#include "crc32_braid_comb_p.h" + +/* ========================================================================= */ +static uint32_t crc32_combine_(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; +} +static uint32_t crc32_combine_gen_(z_off64_t len2) { + return x2nmodp(len2, 3); +} +static uint32_t crc32_combine_op_(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return multmodp(op, crc1) ^ crc2; +} + +/* ========================================================================= */ + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off64_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_gen)(z_off_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_op)(unsigned long crc1, unsigned long crc2, const unsigned long op) { + return (unsigned long)crc32_combine_op_((uint32_t)crc1, (uint32_t)crc2, (uint32_t)op); +} +#else +uint32_t Z_EXPORT PREFIX4(crc32_combine)(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return crc32_combine_(crc1, crc2, len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_op)(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return crc32_combine_op_(crc1, crc2, op); +} +#endif + +/* ========================================================================= */ diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb_p.h b/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb_p.h new file mode 100644 index 000000000..a269e7f5b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_braid_comb_p.h @@ -0,0 +1,42 @@ +#ifndef CRC32_BRAID_COMB_P_H_ +#define CRC32_BRAID_COMB_P_H_ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +static uint32_t multmodp(uint32_t a, uint32_t b) { + uint32_t m, p; + + m = (uint32_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +static uint32_t x2nmodp(z_off64_t n, unsigned k) { + uint32_t p; + + p = (uint32_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#endif /* CRC32_BRAID_COMB_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_braid_p.h b/internal-complibs/zlib-ng-2.1.2/crc32_braid_p.h new file mode 100644 index 000000000..1d8a07068 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_braid_p.h @@ -0,0 +1,50 @@ +#ifndef CRC32_BRAID_P_H_ +#define CRC32_BRAID_P_H_ + +#include "zbuild.h" +#include "zendian.h" + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifndef W +# if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 + typedef uint64_t z_word_t; +# else +# undef W +# define W 4 + typedef uint32_t z_word_t; +# endif +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); + +#endif /* CRC32_BRAID_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_braid_tbl.h b/internal-complibs/zlib-ng-2.1.2/crc32_braid_tbl.h new file mode 100644 index 000000000..84d79a69e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_braid_tbl.h @@ -0,0 +1,9446 @@ +#ifndef CRC32_BRAID_TBL_H_ +#define CRC32_BRAID_TBL_H_ + +/* crc32_braid_tbl.h -- tables for braided CRC calculation + * Generated automatically by makecrct.c + */ + +static const uint32_t crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +static const z_word_t crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +static const z_word_t crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#endif /* W */ + +#if N == 1 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif /* W */ + +#endif /* N == 1 */ +#if N == 2 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif /* W */ + +#endif /* N == 2 */ +#if N == 3 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif /* W */ + +#endif /* N == 3 */ +#if N == 4 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif /* W */ + +#endif /* N == 4 */ +#if N == 5 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif /* W */ + +#endif /* N == 5 */ +#if N == 6 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif /* W */ + +#endif /* N == 6 */ + +static const uint32_t x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; + +#endif /* CRC32_BRAID_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_fold.c b/internal-complibs/zlib-ng-2.1.2/crc32_fold.c new file mode 100644 index 000000000..5b3c7c459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_fold.c @@ -0,0 +1,33 @@ +/* crc32_fold.c -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" +#include "functable.h" + +#include "crc32_fold.h" + +#include + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc) { + crc->value = CRC32_INITIAL_VALUE; + return crc->value; +} + +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { + crc->value = functable.crc32(crc->value, src, len); + memcpy(dst, src, len); +} + +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { + /* Note: while this is basically the same thing as the vanilla CRC function, we still need + * a functable entry for it so that we can generically dispatch to this function with the + * same arguments for the versions that _do_ do a folding CRC but we don't want a copy. The + * init_crc is an unused argument in this context */ + Z_UNUSED(init_crc); + crc->value = functable.crc32(crc->value, src, len); +} + +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc) { + return crc->value; +} diff --git a/internal-complibs/zlib-ng-2.1.2/crc32_fold.h b/internal-complibs/zlib-ng-2.1.2/crc32_fold.h new file mode 100644 index 000000000..0d2ff6696 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/crc32_fold.h @@ -0,0 +1,21 @@ +/* crc32_fold.h -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef CRC32_FOLD_H_ +#define CRC32_FOLD_H_ + +#define CRC32_FOLD_BUFFER_SIZE (16 * 4) +/* sizeof(__m128i) * (4 folds) */ + +typedef struct crc32_fold_s { + uint8_t fold[CRC32_FOLD_BUFFER_SIZE]; + uint32_t value; +} crc32_fold; + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc); +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/deflate.c b/internal-complibs/zlib-ng-2.1.2/deflate.c new file mode 100644 index 000000000..3ea92a82d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate.c @@ -0,0 +1,1427 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in https://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef deflateInit +# undef deflateInit2 +#endif + +const char PREFIX(deflate_copyright)[] = " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_deflate.h" +#else +/* Memory management for the deflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_DEFLATE_STATE(strm) ((deflate_state *)ZALLOC(strm, 1, sizeof(deflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_DEFLATE_STATE(dst, src) memcpy(dst, src, sizeof(deflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define TRY_FREE_WINDOW(strm, addr) TRY_FREE(strm, addr) +/* Invoked at the beginning of deflateSetDictionary(). Useful for checking arch-specific window data. */ +# define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of deflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the end of deflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of deflateParams(). Useful for updating arch-specific compression parameters. */ +# define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) +/* Returns whether the last deflate(flush) operation did everything it's supposed to do. */ +# define DEFLATE_DONE(strm, flush) 1 +/* Adjusts the upper bound on compressed data length based on compression parameters and uncompressed data length. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) +/* Returns whether an optimistic upper bound on compressed data length should *not* be used. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 +/* Invoked for each deflate() call. Useful for plugging arch-specific deflation code. */ +# define DEFLATE_HOOK(strm, flush, bstate) 0 +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific deflation code already does that. */ +# define DEFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether reproducibility parameter can be set to a given value. */ +# define DEFLATE_CAN_SET_REPRODUCIBLE(strm, reproducible) 1 +#endif + +/* =========================================================================== + * Function prototypes. + */ +static int deflateStateCheck (PREFIX3(stream) *strm); +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush); +Z_INTERNAL block_state deflate_fast (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_quick (deflate_state *s, int flush); +#ifndef NO_MEDIUM_STRATEGY +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush); +#endif +Z_INTERNAL block_state deflate_slow (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_rle (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_huff (deflate_state *s, int flush); +static void lm_set_level (deflate_state *s, int level); +static void lm_init (deflate_state *s); +Z_INTERNAL unsigned read_buf (PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +extern uint32_t update_hash_roll (deflate_state *const s, uint32_t h, uint32_t val); +extern void insert_string_roll (deflate_state *const s, uint32_t str, uint32_t count); +extern Pos quick_insert_string_roll(deflate_state *const s, uint32_t str); + +/* =========================================================================== + * Local data + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + uint16_t good_length; /* reduce lazy search above this match length */ + uint16_t max_lazy; /* do not perform lazy search above this match length */ + uint16_t nice_length; /* quit search above this match length */ + uint16_t max_chain; + compress_func func; +} config; + +static const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ + +#ifdef NO_QUICK_STRATEGY +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +#else +/* 1 */ {0, 0, 0, 0, deflate_quick}, +/* 2 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +#endif + +#ifdef NO_MEDIUM_STRATEGY +/* 3 */ {4, 6, 32, 32, deflate_fast}, +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +#else +/* 3 */ {4, 6, 16, 6, deflate_medium}, +/* 4 */ {4, 12, 32, 24, deflate_medium}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_medium}, +/* 6 */ {8, 16, 128, 128, deflate_medium}, +#endif + +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ + +/* Note: the deflate() code requires max_lazy >= STD_MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + + +/* =========================================================================== + * Initialize the hash table. prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) do { \ + memset((unsigned char *)s->head, 0, HASH_SIZE * sizeof(*s->head)); \ + } while (0) + +/* ========================================================================= */ +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy) { + /* Todo: ignore strm->next_in if we use it as window */ + uint32_t window_padding = 0; + deflate_state *s; + int wrap = 1; + + if (strm == NULL) + return Z_STREAM_ERROR; + + strm->msg = NULL; + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; +#ifdef GZIP + } else if (windowBits > MAX_WBITS) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; +#endif + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < MIN_WBITS || + windowBits > MAX_WBITS || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED || + (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) + windowBits = 9; /* until 256-byte window bug fixed */ + + s = ZALLOC_DEFLATE_STATE(strm); + if (s == NULL) + return Z_MEM_ERROR; + strm->state = (struct internal_state *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = NULL; + s->w_bits = (unsigned int)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + s->window = (unsigned char *) ZALLOC_WINDOW(strm, s->w_size + window_padding, 2*sizeof(unsigned char)); + s->prev = (Pos *) ZALLOC(strm, s->w_size, sizeof(Pos)); + memset(s->prev, 0, s->w_size * sizeof(Pos)); + s->head = (Pos *) ZALLOC(strm, HASH_SIZE, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n-2) bits have been written, just + * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * symbols are written.) The closest the writing gets to what is unread is + * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (unsigned char *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf_size = s->lit_bufsize * 4; + + if (s->window == NULL || s->prev == NULL || s->head == NULL || s->pending_buf == NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + PREFIX(deflateEnd)(strm); + return Z_MEM_ERROR; + } + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->block_open = 0; + s->reproducible = 0; + + return PREFIX(deflateReset)(strm); +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(deflateInit)(PREFIX3(stream) *strm, int32_t level) { + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit_)(PREFIX3(stream) *strm, int32_t level, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, method, windowBits, memLevel, strategy); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +static int deflateStateCheck (PREFIX3(stream) *strm) { + deflate_state *s; + if (strm == NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && +#endif + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + deflate_state *s; + unsigned int str, n; + int wrap; + uint32_t avail; + const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = functable.adler32(strm->adler, dictionary, dictLength); + DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const unsigned char *)dictionary; + PREFIX(fill_window)(s); + while (s->lookahead >= STD_MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (STD_MIN_MATCH - 1); + s->insert_string(s, str, n); + s->strstart = str + n; + s->lookahead = STD_MIN_MATCH - 1; + PREFIX(fill_window)(s); + } + s->strstart += s->lookahead; + s->block_start = (int)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->prev_length = 0; + s->match_available = 0; + strm->next_in = (z_const unsigned char *)next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + deflate_state *s; + unsigned int len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != NULL && len) + memcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateResetKeep)(PREFIX3(stream) *strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_reset(&s->crc_fold); + } else +#endif + strm->adler = ADLER32_INITIAL_VALUE; + s->last_flush = -2; + + zng_tr_init(s); + + DEFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateReset)(PREFIX3(stream) *strm) { + int ret; + + ret = PREFIX(deflateResetKeep)(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePending)(PREFIX3(stream) *strm, uint32_t *pending, int32_t *bits) { + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (pending != NULL) + *pending = strm->state->pending; + if (bits != NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + deflate_state *s; + uint64_t value64 = (uint64_t)value; + int32_t put; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + if (bits < 0 || bits > BIT_BUF_SIZE || bits > (int32_t)(sizeof(value) << 3) || + s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = BIT_BUF_SIZE - s->bi_valid; + put = MIN(put, bits); + + if (s->bi_valid == 0) + s->bi_buf = value64; + else + s->bi_buf |= (value64 & ((UINT64_C(1) << put) - 1)) << s->bi_valid; + s->bi_valid += put; + zng_tr_flush_bits(s); + value64 >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int32_t strategy) { + deflate_state *s; + compress_func func; + int hook_flush = Z_NO_FLUSH; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) + return Z_STREAM_ERROR; + DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); /* hook for IBM Z DFLTCC */ + func = configuration_table[s->level].func; + + if (((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2) + || hook_flush != Z_NO_FLUSH) { + /* Flush the last buffer. Use Z_BLOCK mode, unless the hook requests a "stronger" one. */ + int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK; + int err = PREFIX(deflate)(strm, flush); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || ((int)s->strstart - s->block_start) + s->lookahead || !DEFLATE_DONE(strm, flush)) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) { + functable.slide_hash(s); + } else { + CLEAR_HASH(s); + } + s->matches = 0; + } + + lm_set_level(s, level); + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateTune)(PREFIX3(stream) *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (unsigned int)good_length; + s->max_lazy_match = (unsigned int)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (unsigned int)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long sourceLen) { + deflate_state *s; + unsigned long complen, wraplen; + + /* conservative upper bound for compressed data */ + complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen); /* hook for IBM Z DFLTCC */ + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (deflateStateCheck(strm)) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = GZIP_WRAPLEN; + if (s->gzhead != NULL) { /* user-supplied gzip header */ + unsigned char *str; + if (s->gzhead->extra != NULL) { + wraplen += 2 + s->gzhead->extra_len; + } + str = s->gzhead->name; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + str = s->gzhead->comment; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = ZLIB_WRAPLEN; + } + + /* if not default parameters, return conservative bound */ + if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */ + s->w_bits != MAX_WBITS || HASH_BITS < 15) { + if (s->level == 0) { + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + complen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7; + } + + return complen + wraplen; + } + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + wraplen; /* none, zlib or gzip wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + wraplen; +#endif +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) { + uint32_t len; + deflate_state *s = strm->state; + + zng_tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) + len = strm->avail_out; + if (len == 0) + return; + + Tracev((stderr, "[FLUSH]")); + memcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) + s->pending_out = s->pending_buf; +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) { + int32_t old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) + return Z_STREAM_ERROR; + s = strm->state; + + if (strm->next_out == NULL || (strm->avail_in != 0 && strm->next_in == NULL) + || (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + unsigned int level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) + header |= PRESET_DICT; + header += 31 - (header % 31); + + put_short_msb(s, (uint16_t)header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) + put_uint32_msb(s, strm->adler); + strm->adler = ADLER32_INITIAL_VALUE; + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + functable.crc32_fold_reset(&s->crc_fold); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_uint32(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == NULL ? 0 : 4) + + (s->gzhead->name == NULL ? 0 : 8) + + (s->gzhead->comment == NULL ? 0 : 16) + ); + put_uint32(s, s->gzhead->time); + put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) + put_short(s, (uint16_t)s->gzhead->extra_len); + if (s->gzhead->hcrc) + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + uint32_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + + while (s->pending + left > s->pending_buf_size) { + uint32_t copy = s->pending_buf_size - s->pending; + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_short(s, (uint16_t)strm->adler); + functable.crc32_fold_reset(&s->crc_fold); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : /* hook for IBM Z DFLTCC */ + s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + zng_tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + zng_tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + } + } + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) + return Z_OK; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_final(&s->crc_fold); + + put_uint32(s, strm->adler); + put_uint32(s, (uint32_t)strm->total_in); + } else +#endif + { + if (s->wrap == 1) + put_uint32_msb(s, strm->adler); + } + PREFIX(flush_pending)(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) + s->wrap = -s->wrap; /* write the trailer only once! */ + if (s->pending == 0) { + Assert(s->bi_valid == 0, "bi_buf not flushed"); + return Z_STREAM_END; + } + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateEnd)(PREFIX3(stream) *strm) { + int32_t status; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE_WINDOW(strm, strm->state->window); + + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + */ +int32_t Z_EXPORT PREFIX(deflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + deflate_state *ds; + deflate_state *ss; + uint32_t window_padding = 0; + + if (deflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + + ss = source->state; + + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + + ds = ZALLOC_DEFLATE_STATE(dest); + if (ds == NULL) + return Z_MEM_ERROR; + dest->state = (struct internal_state *) ds; + ZCOPY_DEFLATE_STATE(ds, ss); + ds->strm = dest; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + ds->window = (unsigned char *) ZALLOC_WINDOW(dest, ds->w_size + window_padding, 2*sizeof(unsigned char)); + ds->prev = (Pos *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Pos *) ZALLOC(dest, HASH_SIZE, sizeof(Pos)); + ds->pending_buf = (unsigned char *) ZALLOC(dest, ds->lit_bufsize, 4); + + if (ds->window == NULL || ds->prev == NULL || ds->head == NULL || ds->pending_buf == NULL) { + PREFIX(deflateEnd)(dest); + return Z_MEM_ERROR; + } + + memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(unsigned char)); + memcpy((void *)ds->prev, (void *)ss->prev, ds->w_size * sizeof(Pos)); + memcpy((void *)ds->head, (void *)ss->head, HASH_SIZE * sizeof(Pos)); + memcpy(ds->pending_buf, ss->pending_buf, ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { + uint32_t len = strm->avail_in; + + len = MIN(len, size); + if (len == 0) + return 0; + + strm->avail_in -= len; + + if (!DEFLATE_NEED_CHECKSUM(strm)) { + memcpy(buf, strm->next_in, len); +#ifdef GZIP + } else if (strm->state->wrap == 2) { + functable.crc32_fold_copy(&strm->state->crc_fold, buf, strm->next_in, len); +#endif + } else { + if (strm->state->wrap == 1) + strm->adler = functable.adler32_fold_copy(strm->adler, buf, strm->next_in, len); + else + memcpy(buf, strm->next_in, len); + } + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Set longest match variables based on level configuration + */ +static void lm_set_level(deflate_state *s, int level) { + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + + /* Use rolling hash for deflate_slow algorithm with level 9. It allows us to + * properly lookup different hash chains to speed up longest_match search. Since hashing + * method changes depending on the level we cannot put this into functable. */ + if (s->max_chain_length > 1024) { + s->update_hash = &update_hash_roll; + s->insert_string = &insert_string_roll; + s->quick_insert_string = &quick_insert_string_roll; + } else { + s->update_hash = functable.update_hash; + s->insert_string = functable.insert_string; + s->quick_insert_string = functable.quick_insert_string; + } + + s->level = level; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +static void lm_init(deflate_state *s) { + s->window_size = 2 * s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + lm_set_level(s, s->level); + + s->strstart = 0; + s->block_start = 0; + s->lookahead = 0; + s->insert = 0; + s->prev_length = 0; + s->match_available = 0; + s->match_start = 0; + s->ins_h = 0; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s) { + unsigned n; + unsigned int more; /* Amount of free space at the end of the window. */ + unsigned int wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s->window_size - s->lookahead - s->strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + memcpy(s->window, s->window+wsize, (unsigned)wsize); + if (s->match_start >= wsize) { + s->match_start -= wsize; + } else { + s->match_start = 0; + s->prev_length = 0; + } + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (int)wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + functable.slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) + break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = PREFIX(read_buf)(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= STD_MIN_MATCH) { + unsigned int str = s->strstart - s->insert; + if (UNLIKELY(s->max_chain_length > 1024)) { + s->ins_h = s->update_hash(s, s->window[str], s->window[str+1]); + } else if (str >= 1) { + s->quick_insert_string(s, str + 2 - STD_MIN_MATCH); + } + unsigned int count; + if (UNLIKELY(s->lookahead == 1)) { + count = s->insert - 1; + } else { + count = s->insert; + } + if (count > 0) { + s->insert_string(s, str, count); + s->insert -= count; + } + } + /* If the whole input has less than STD_MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to STD_MAX_MATCH since the longest match + * routines allow scanning to strstart + STD_MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + unsigned int curr = s->strstart + s->lookahead; + unsigned int init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + memset(s->window + curr, 0, init); + s->high_water = curr + init; + } else if (s->high_water < curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + memset(s->window + s->high_water, 0, init); + s->high_water += init; + } + } + + Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +#ifndef ZLIB_COMPAT +/* ========================================================================= + * Checks whether buffer size is sufficient and whether this parameter is a duplicate. + */ +static int32_t deflateSetParamPre(zng_deflate_param_value **out, size_t min_size, zng_deflate_param_value *param) { + int32_t buf_error = param->size < min_size; + + if (*out != NULL) { + (*out)->status = Z_BUF_ERROR; + buf_error = 1; + } + *out = param; + return buf_error; +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + size_t i; + deflate_state *s; + zng_deflate_param_value *new_level = NULL; + zng_deflate_param_value *new_strategy = NULL; + zng_deflate_param_value *new_reproducible = NULL; + int param_buf_error; + int version_error = 0; + int buf_error = 0; + int stream_error = 0; + int ret; + int val; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + /* Check buffer sizes and detect duplicates. */ + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + param_buf_error = deflateSetParamPre(&new_level, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_STRATEGY: + param_buf_error = deflateSetParamPre(&new_strategy, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_REPRODUCIBLE: + param_buf_error = deflateSetParamPre(&new_reproducible, sizeof(int), ¶ms[i]); + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + param_buf_error = 0; + break; + } + if (param_buf_error) { + params[i].status = Z_BUF_ERROR; + buf_error = 1; + } + } + /* Exit early if small buffers or duplicates are detected. */ + if (buf_error) + return Z_BUF_ERROR; + + /* Apply changes, remember if there were errors. */ + if (new_level != NULL || new_strategy != NULL) { + ret = PREFIX(deflateParams)(strm, new_level == NULL ? s->level : *(int *)new_level->buf, + new_strategy == NULL ? s->strategy : *(int *)new_strategy->buf); + if (ret != Z_OK) { + if (new_level != NULL) + new_level->status = Z_STREAM_ERROR; + if (new_strategy != NULL) + new_strategy->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + if (new_reproducible != NULL) { + val = *(int *)new_reproducible->buf; + if (DEFLATE_CAN_SET_REPRODUCIBLE(strm, val)) { + s->reproducible = val; + } else { + new_reproducible->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + + /* Report version errors only if there are no real errors. */ + return stream_error ? Z_STREAM_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + deflate_state *s; + size_t i; + int32_t buf_error = 0; + int32_t version_error = 0; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->level; + break; + case Z_DEFLATE_STRATEGY: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->strategy; + break; + case Z_DEFLATE_REPRODUCIBLE: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->reproducible; + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + break; + } + if (params[i].status == Z_BUF_ERROR) + buf_error = 1; + } + return buf_error ? Z_BUF_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/deflate.h b/internal-complibs/zlib-ng-2.1.2/deflate.h new file mode 100644 index 000000000..e4b971f88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate.h @@ -0,0 +1,403 @@ +#ifndef DEFLATE_H_ +#define DEFLATE_H_ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zutil.h" +#include "zendian.h" +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define BIT_BUF_SIZE 64 +/* size of bit buffer in bi_buf */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +# define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +# define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +# define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +# define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#endif +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + +#define HASH_BITS 16u /* log2(HASH_SIZE) */ +#ifndef HASH_SIZE +# define HASH_SIZE 65536u /* number of elements in hash table */ +#endif +#define HASH_MASK (HASH_SIZE - 1u) /* HASH_SIZE-1 */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + uint16_t freq; /* frequency count */ + uint16_t code; /* bit string */ + } fc; + union { + uint16_t dad; /* father node in Huffman tree */ + uint16_t len; /* length of bit string */ + } dl; +} ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} tree_desc; + +typedef uint16_t Pos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. + */ +/* Type definitions for hash callbacks */ +typedef struct internal_state deflate_state; + +typedef uint32_t (* update_hash_cb) (deflate_state *const s, uint32_t h, uint32_t val); +typedef void (* insert_string_cb) (deflate_state *const s, uint32_t str, uint32_t count); +typedef Pos (* quick_insert_string_cb)(deflate_state *const s, uint32_t str); + +struct internal_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + unsigned char *pending_buf; /* output still pending */ + unsigned char *pending_out; /* next pending byte to output to the stream */ + uint32_t pending_buf_size; /* size of pending_buf */ + uint32_t pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + uint32_t gzindex; /* where in extra, name, or comment */ + PREFIX(gz_headerp) gzhead; /* gzip header information to write */ + int status; /* as the name implies */ + int last_flush; /* value of flush param for previous deflate call */ + int reproducible; /* Whether reproducible compression results are required. */ + + int block_open; + /* Whether or not a block is currently open for the QUICK deflation scheme. + * This is set to 1 if there is an active block, or 0 if the block was just closed. + */ + + /* used by deflate.c: */ + + unsigned int w_size; /* LZ77 window size (32K by default) */ + unsigned int w_bits; /* log2(w_size) (8..16) */ + unsigned int w_mask; /* w_size - 1 */ + unsigned int lookahead; /* number of valid bytes ahead in window */ + + unsigned int high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + + unsigned int window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + unsigned char *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-STD_MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + Pos *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Pos *head; /* Heads of the hash chains or 0. */ + + uint32_t ins_h; /* hash index of string to be inserted */ + + int block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + unsigned int match_length; /* length of best match */ + Pos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + unsigned int strstart; /* start of string to insert */ + unsigned int match_start; /* start of matching string */ + + unsigned int prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + unsigned int max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this length. + * A higher limit improves compression ratio but degrades the speed. + */ + + unsigned int max_lazy_match; + /* Attempt to find a better match only when the current match is strictly smaller + * than this value. This mechanism is used only for compression levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + update_hash_cb update_hash; + insert_string_cb insert_string; + quick_insert_string_cb quick_insert_string; + /* Hash function callbacks that can be configured depending on the deflate + * algorithm being used */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + unsigned int good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + unsigned char depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + unsigned int lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + unsigned char *sym_buf; /* buffer for distances and literals/lengths */ + unsigned int sym_next; /* running index in sym_buf */ + unsigned int sym_end; /* symbol table full when sym_next reaches this */ + + unsigned long opt_len; /* bit length of current block with optimal trees */ + unsigned long static_len; /* bit length of current block with static trees */ + unsigned int matches; /* number of string matches in current block */ + unsigned int insert; /* bytes at end of window left to insert */ + + /* compressed_len and bits_sent are only used if ZLIB_DEBUG is defined */ + unsigned long compressed_len; /* total bit length of compressed file mod 2^32 */ + unsigned long bits_sent; /* bit length of compressed data sent mod 2^32 */ + + /* Reserved for future use and alignment purposes */ + char *reserved_p; + + uint64_t bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least significant bits). */ + + int32_t bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit are always zero. */ + + /* Reserved for future use and alignment purposes */ + int32_t reserved[11]; +} ALIGNED_(8); + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) { \ + s->pending_buf[s->pending++] = (unsigned char)(c); \ +} + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == BIG_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a short MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short_msb(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == LITTLE_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a 32-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == BIG_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 32-bit unsigned int MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32_msb(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == LITTLE_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 64-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint64(deflate_state *s, uint64_t lld) { +#if BYTE_ORDER == BIG_ENDIAN + lld = ZSWAP64(lld); +#endif + memcpy(&s->pending_buf[s->pending], &lld, sizeof(lld)); + s->pending += 8; +} + +#define MIN_LOOKAHEAD (STD_MAX_MATCH + STD_MIN_MATCH + 1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the STD_MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size - MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT STD_MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s); +void Z_INTERNAL slide_hash_c(deflate_state *s); + + /* in trees.c */ +void Z_INTERNAL zng_tr_init(deflate_state *s); +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s); +void Z_INTERNAL zng_tr_align(deflate_state *s); +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +uint16_t Z_INTERNAL PREFIX(bi_reverse)(unsigned code, int len); +void Z_INTERNAL PREFIX(flush_pending)(PREFIX3(streamp) strm); +#define d_code(dist) ((dist) < 256 ? zng_dist_code[dist] : zng_dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. zng_dist_code[256] and zng_dist_code[257] are never + * used. + */ + +/* Bit buffer and compress bits calculation debugging */ +#ifdef ZLIB_DEBUG +# define cmpr_bits_add(s, len) s->compressed_len += (len) +# define cmpr_bits_align(s) s->compressed_len = (s->compressed_len + 7) & ~7L +# define sent_bits_add(s, bits) s->bits_sent += (bits) +# define sent_bits_align(s) s->bits_sent = (s->bits_sent + 7) & ~7L +#else +# define cmpr_bits_add(s, len) Z_UNUSED(len) +# define cmpr_bits_align(s) +# define sent_bits_add(s, bits) Z_UNUSED(bits) +# define sent_bits_align(s) +#endif + +#endif /* DEFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_fast.c b/internal-complibs/zlib-ng-2.1.2/deflate_fast.c new file mode 100644 index 000000000..3184aa718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_fast.c @@ -0,0 +1,102 @@ +/* deflate_fast.c -- compress data using the fast strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +Z_INTERNAL block_state deflate_fast(deflate_state *s, int flush) { + Pos hash_head; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match length < WANT_MIN_MATCH + */ + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = functable.longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + } + + if (match_len >= WANT_MIN_MATCH) { + check_match(s, s->strstart, s->match_start, match_len); + + bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_len <= s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match_len--; /* string at strstart already in table */ + s->strstart++; + + functable.insert_string(s, s->strstart, match_len); + s->strstart += match_len; + } else { + s->strstart += match_len; + functable.quick_insert_string(s, s->strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_huff.c b/internal-complibs/zlib-ng-2.1.2/deflate_huff.c new file mode 100644 index 000000000..b197e24d7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_huff.c @@ -0,0 +1,45 @@ +/* deflate_huff.c -- compress data using huffman encoding only strategy + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +Z_INTERNAL block_state deflate_huff(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + PREFIX(fill_window)(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_medium.c b/internal-complibs/zlib-ng-2.1.2/deflate_medium.c new file mode 100644 index 000000000..47796e322 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_medium.c @@ -0,0 +1,293 @@ +/* deflate_medium.c -- The deflate_medium deflate strategy + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Arjan van de Ven + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef NO_MEDIUM_STRATEGY +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +struct match { + uint16_t match_start; + uint16_t match_length; + uint16_t strstart; + uint16_t orgstart; +}; + +static int emit_match(deflate_state *s, struct match match) { + int bflush = 0; + + /* matches that are not long enough we need to emit as literals */ + if (match.match_length < WANT_MIN_MATCH) { + while (match.match_length) { + bflush += zng_tr_tally_lit(s, s->window[match.strstart]); + s->lookahead--; + match.strstart++; + match.match_length--; + } + return bflush; + } + + check_match(s, match.strstart, match.match_start, match.match_length); + + bflush += zng_tr_tally_dist(s, match.strstart - match.match_start, match.match_length - STD_MIN_MATCH); + + s->lookahead -= match.match_length; + return bflush; +} + +static void insert_match(deflate_state *s, struct match match) { + if (UNLIKELY(s->lookahead <= (unsigned int)(match.match_length + WANT_MIN_MATCH))) + return; + + /* matches that are not long enough we need to emit as literals */ + if (LIKELY(match.match_length < WANT_MIN_MATCH)) { + match.strstart++; + match.match_length--; + if (UNLIKELY(match.match_length > 0)) { + if (match.strstart >= match.orgstart) { + if (match.strstart + match.match_length - 1 >= match.orgstart) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + match.strstart += match.match_length; + match.match_length = 0; + } + } + return; + } + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match.match_length <= 16 * s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match.match_length--; /* string at strstart already in table */ + match.strstart++; + + if (LIKELY(match.strstart >= match.orgstart)) { + if (LIKELY(match.strstart + match.match_length - 1 >= match.orgstart)) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + } else if (match.orgstart < match.strstart + match.match_length) { + functable.insert_string(s, match.orgstart, match.strstart + match.match_length - match.orgstart); + } + match.strstart += match.match_length; + match.match_length = 0; + } else { + match.strstart += match.match_length; + match.match_length = 0; + + if (match.strstart >= (STD_MIN_MATCH - 2)) + functable.quick_insert_string(s, match.strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < WANT_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } +} + +static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { + Pos limit; + unsigned char *match, *orig; + int changed = 0; + struct match c, n; + /* step zero: sanity checks */ + + if (current->match_length <= 1) + return; + + if (UNLIKELY(current->match_length > 1 + next->match_start)) + return; + + if (UNLIKELY(current->match_length > 1 + next->strstart)) + return; + + match = s->window - current->match_length + 1 + next->match_start; + orig = s->window - current->match_length + 1 + next->strstart; + + /* quick exit check.. if this fails then don't bother with anything else */ + if (LIKELY(*match != *orig)) + return; + + c = *current; + n = *next; + + /* step one: try to move the "next" match to the left as much as possible */ + limit = next->strstart > MAX_DIST(s) ? next->strstart - (Pos)MAX_DIST(s) : 0; + + match = s->window + n.match_start - 1; + orig = s->window + n.strstart - 1; + + while (*match == *orig) { + if (UNLIKELY(c.match_length < 1)) + break; + if (UNLIKELY(n.strstart <= limit)) + break; + if (UNLIKELY(n.match_length >= 256)) + break; + if (UNLIKELY(n.match_start <= 1)) + break; + + n.strstart--; + n.match_start--; + n.match_length++; + c.match_length--; + match--; + orig--; + changed++; + } + + if (!changed) + return; + + if (c.match_length <= 1 && n.match_length != 2) { + n.orgstart++; + *current = c; + *next = n; + } else { + return; + } +} + +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { + /* Align the first struct to start on a new cacheline, this allows us to fit both structs in one cacheline */ + ALIGNED_(16) struct match current_match; + struct match next_match; + + /* For levels below 5, don't check the next position for a better match */ + int early_exit = s->level < 5; + + memset(¤t_match, 0, sizeof(struct match)); + memset(&next_match, 0, sizeof(struct match)); + + for (;;) { + Pos hash_head = 0; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next current_match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + next_match.match_length = 0; + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + + /* If we already have a future match from a previous round, just use that */ + if (!early_exit && next_match.match_length > 0) { + current_match = next_match; + next_match.match_length = 0; + } else { + hash_head = 0; + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + } + + current_match.strstart = (uint16_t)s->strstart; + current_match.orgstart = current_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + current_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + current_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(current_match.match_length < WANT_MIN_MATCH)) + current_match.match_length = 1; + if (UNLIKELY(current_match.match_start >= current_match.strstart)) { + /* this can happen due to some restarts */ + current_match.match_length = 1; + } + } else { + /* Set up the match to be a 1 byte literal */ + current_match.match_start = 0; + current_match.match_length = 1; + } + } + + insert_match(s, current_match); + + /* now, look ahead one */ + if (LIKELY(!early_exit && s->lookahead > MIN_LOOKAHEAD && (uint32_t)(current_match.strstart + current_match.match_length) < (s->window_size - MIN_LOOKAHEAD))) { + s->strstart = current_match.strstart + current_match.match_length; + hash_head = functable.quick_insert_string(s, s->strstart); + + next_match.strstart = (uint16_t)s->strstart; + next_match.orgstart = next_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + next_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + next_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(next_match.match_start >= next_match.strstart)) { + /* this can happen due to some restarts */ + next_match.match_length = 1; + } + if (next_match.match_length < WANT_MIN_MATCH) + next_match.match_length = 1; + else + fizzle_matches(s, ¤t_match, &next_match); + } else { + /* Set up the match to be a 1 byte literal */ + next_match.match_start = 0; + next_match.match_length = 1; + } + + s->strstart = current_match.strstart; + } else { + next_match.match_length = 0; + } + + /* now emit the current match */ + bflush = emit_match(s, current_match); + + /* move the "cursor" forward */ + s->strstart += current_match.match_length; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + + return block_done; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_p.h b/internal-complibs/zlib-ng-2.1.2/deflate_p.h new file mode 100644 index 000000000..dd2021a0f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_p.h @@ -0,0 +1,116 @@ +/* deflate_p.h -- Private inline functions and macros shared with more than + * one deflate method + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef DEFLATE_P_H +#define DEFLATE_P_H + +/* Forward declare common non-inlined functions declared in deflate.c */ + +#ifdef ZLIB_DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +static inline void check_match(deflate_state *s, Pos start, Pos match, int length) { + /* check that the match length is valid*/ + if (length < STD_MIN_MATCH || length > STD_MAX_MATCH) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match length"); + } + /* check that the match isn't at the same position as the start string */ + if (match == start) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match position"); + } + /* check that the match is indeed a match */ + if (memcmp(s->window + match, s->window + start, length) != 0) { + int32_t i = 0; + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + do { + fprintf(stderr, " %03d: match [%02x] start [%02x]\n", i++, + s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr, "\\[%u,%d]", start-match, length); + do { + putc(s->window[start++], stderr); + } while (--length != 0); + } +} +#else +#define check_match(s, start, match, length) +#endif + +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm); +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + +extern const unsigned char Z_INTERNAL zng_length_code[]; +extern const unsigned char Z_INTERNAL zng_dist_code[]; + +static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { + /* c is the unmatched char */ + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = c; + s->dyn_ltree[c].Freq++; + Tracevv((stderr, "%c", c)); + Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); + return (s->sym_next == s->sym_end); +} + +static inline int zng_tr_tally_dist(deflate_state *s, uint32_t dist, uint32_t len) { + /* dist: distance of matched string */ + /* len: match length-STD_MIN_MATCH */ + s->sym_buf[s->sym_next++] = (uint8_t)(dist); + s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); + s->sym_buf[s->sym_next++] = (uint8_t)len; + s->matches++; + dist--; + Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, + "zng_tr_tally: bad match"); + + s->dyn_ltree[zng_length_code[len]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + return (s->sym_next == s->sym_end); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + zng_tr_flush_block(s, (s->block_start >= 0 ? \ + (char *)&s->window[(unsigned)s->block_start] : \ + NULL), \ + (uint32_t)((int)s->strstart - s->block_start), \ + (last)); \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Compression function. Returns the block state after the call. */ +typedef block_state (*compress_func) (deflate_state *s, int flush); +/* Match function. Returns the longest match. */ +typedef uint32_t (*match_func) (deflate_state *const s, Pos cur_match); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_quick.c b/internal-complibs/zlib-ng-2.1.2/deflate_quick.c new file mode 100644 index 000000000..df5a17b9e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_quick.c @@ -0,0 +1,129 @@ +/* + * The deflate_quick deflate strategy, designed to be used when cycles are + * at a premium. + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "trees_emit.h" + +extern const ct_data static_ltree[L_CODES+2]; +extern const ct_data static_dtree[D_CODES]; + +#define QUICK_START_BLOCK(s, last) { \ + zng_tr_emit_tree(s, STATIC_TREES, last); \ + s->block_open = 1 + (int)last; \ + s->block_start = (int)s->strstart; \ +} + +#define QUICK_END_BLOCK(s, last) { \ + if (s->block_open) { \ + zng_tr_emit_end_block(s, static_ltree, last); \ + s->block_open = 0; \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ + if (s->strm->avail_out == 0) \ + return (last) ? finish_started : need_more; \ + } \ +} + +Z_INTERNAL block_state deflate_quick(deflate_state *s, int flush) { + Pos hash_head; + int64_t dist; + unsigned match_len, last; + + + last = (flush == Z_FINISH) ? 1 : 0; + if (UNLIKELY(last && s->block_open != 2)) { + /* Emit end of previous block */ + QUICK_END_BLOCK(s, 0); + /* Emit start of last block */ + QUICK_START_BLOCK(s, last); + } else if (UNLIKELY(s->block_open == 0 && s->lookahead > 0)) { + /* Start new block only when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + + for (;;) { + if (UNLIKELY(s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size)) { + PREFIX(flush_pending)(s->strm); + if (s->strm->avail_out == 0) { + return (last && s->strm->avail_in == 0 && s->bi_valid == 0 && s->block_open == 0) ? finish_started : need_more; + } + } + + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD)) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; + + if (UNLIKELY(s->block_open == 0)) { + /* Start new block when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + } + + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0) { + const uint8_t *str_start = s->window + s->strstart; + const uint8_t *match_start = s->window + hash_head; + + if (zng_memcmp_2(str_start, match_start) == 0) { + match_len = functable.compare256(str_start+2, match_start+2) + 2; + + if (match_len >= WANT_MIN_MATCH) { + if (UNLIKELY(match_len > s->lookahead)) + match_len = s->lookahead; + if (UNLIKELY(match_len > STD_MAX_MATCH)) + match_len = STD_MAX_MATCH; + + check_match(s, s->strstart, hash_head, match_len); + + zng_tr_emit_dist(s, static_ltree, static_dtree, match_len - STD_MIN_MATCH, (uint32_t)dist); + s->lookahead -= match_len; + s->strstart += match_len; + continue; + } + } + } + } + + zng_tr_emit_lit(s, static_ltree, s->window[s->strstart]); + s->strstart++; + s->lookahead--; + } + + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(last)) { + QUICK_END_BLOCK(s, 1); + return finish_done; + } + + QUICK_END_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_rle.c b/internal-complibs/zlib-ng-2.1.2/deflate_rle.c new file mode 100644 index 000000000..cd0850994 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_rle.c @@ -0,0 +1,85 @@ +/* deflate_rle.c -- compress data using RLE strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "compare256_rle.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +#ifdef UNALIGNED_OK +# if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +# define compare256_rle compare256_rle_unaligned_64 +# elif defined(HAVE_BUILTIN_CTZ) +# define compare256_rle compare256_rle_unaligned_32 +# else +# define compare256_rle compare256_rle_unaligned_16 +# endif +#else +# define compare256_rle compare256_rle_c +#endif + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +Z_INTERNAL block_state deflate_rle(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + unsigned char *scan; /* scan goes up to strend for length of run */ + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= STD_MAX_MATCH) { + PREFIX(fill_window)(s); + if (s->lookahead <= STD_MAX_MATCH && flush == Z_NO_FLUSH) + return need_more; + if (s->lookahead == 0) + break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + if (s->lookahead >= STD_MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + if (scan[0] == scan[1] && scan[1] == scan[2]) { + match_len = compare256_rle(scan, scan+3)+2; + match_len = MIN(match_len, s->lookahead); + match_len = MIN(match_len, STD_MAX_MATCH); + } + Assert(scan+match_len <= s->window + s->window_size - 1, "wild scan"); + } + + /* Emit match if have run of STD_MIN_MATCH or longer, else emit literal */ + if (match_len >= STD_MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, match_len); + + bflush = zng_tr_tally_dist(s, 1, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + s->strstart += match_len; + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_slow.c b/internal-complibs/zlib-ng-2.1.2/deflate_slow.c new file mode 100644 index 000000000..9f1c91346 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_slow.c @@ -0,0 +1,143 @@ +/* deflate_slow.c -- compress data using the slow strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Same as deflate_medium, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { + Pos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len; + match_func *longest_match; + + if (s->max_chain_length <= 1024) + longest_match = &functable.longest_match; + else + longest_match = &functable.longest_match_slow; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0; + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = s->quick_insert_string(s, s->strstart); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_match = (Pos)s->match_start; + match_len = STD_MIN_MATCH - 1; + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0 && s->prev_length < s->max_lazy_match && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = (*longest_match)(s, hash_head); + /* longest_match() sets match_start */ + + if (match_len <= 5 && (s->strategy == Z_FILTERED)) { + /* If prev_match is also WANT_MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_len = STD_MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= STD_MIN_MATCH && match_len <= s->prev_length) { + unsigned int max_insert = s->strstart + s->lookahead - STD_MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - STD_MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->prev_length -= 1; + s->lookahead -= s->prev_length; + + unsigned int mov_fwd = s->prev_length - 1; + if (max_insert > s->strstart) { + unsigned int insert_cnt = mov_fwd; + if (UNLIKELY(insert_cnt > max_insert - s->strstart)) + insert_cnt = max_insert - s->strstart; + s->insert_string(s, s->strstart + 1, insert_cnt); + } + s->prev_length = 0; + s->match_available = 0; + s->strstart += mov_fwd + 1; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]); + if (UNLIKELY(bflush)) + FLUSH_BLOCK_ONLY(s, 0); + s->prev_length = match_len; + s->strstart++; + s->lookahead--; + if (UNLIKELY(s->strm->avail_out == 0)) + return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->prev_length = match_len; + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert(flush != Z_NO_FLUSH, "no flush?"); + if (UNLIKELY(s->match_available)) { + (void) zng_tr_tally_lit(s, s->window[s->strstart-1]); + s->match_available = 0; + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.2/deflate_stored.c b/internal-complibs/zlib-ng-2.1.2/deflate_stored.c new file mode 100644 index 000000000..6160896b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/deflate_stored.c @@ -0,0 +1,186 @@ +/* deflate_stored.c -- store data without compression using deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = (int)s->strstart - s->block_start; /* bytes left in window */ + if (len > (unsigned long)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + len = MIN(len, have); /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + zng_tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending -= 4; + put_short(s, (uint16_t)len); + put_short(s, (uint16_t)~len); + + /* Write the stored block header bytes. */ + PREFIX(flush_pending)(s->strm); + + /* Update debugging counts for the data about to be copied. */ + cmpr_bits_add(s, len << 3); + sent_bits_add(s, len << 3); + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + left = MIN(left, len); + memcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += (int)left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + PREFIX(read_buf)(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + memcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + s->insert = MIN(s->insert, s->strstart); + } + memcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = (int)s->strstart; + } + s->high_water = MAX(s->high_water, s->strstart); + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && s->strm->avail_in == 0 && (int)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (int)s->w_size) { + /* Slide the window down. */ + s->block_start -= (int)s->w_size; + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + s->insert = MIN(s->insert, s->strstart); + } + + have = MIN(have, s->strm->avail_in); + if (have) { + PREFIX(read_buf)(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + s->high_water = MAX(s->high_water, s->strstart); + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = (int)s->strstart - s->block_start; + if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0; + zng_tr_stored_block(s, (char *)s->window + s->block_start, len, last); + s->block_start += (int)len; + PREFIX(flush_pending)(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} diff --git a/internal-complibs/zlib-ng-2.1.2/doc/algorithm.txt b/internal-complibs/zlib-ng-2.1.2/doc/algorithm.txt new file mode 100644 index 000000000..acd099c9a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.2/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +https://tools.ietf.org/html/rfc1951 diff --git a/internal-complibs/zlib-ng-2.1.2/doc/crc-doc.1.0.pdf b/internal-complibs/zlib-ng-2.1.2/doc/crc-doc.1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d6942ecc09a3f8b2d7e4b6fbecc5955121e8e7cf GIT binary patch literal 776142 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

  • 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℞AMkzQ=&V-bWaym-?9j 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%0ARD|WAUa-^)bZn# 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%0Dmda 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 literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/Makefile.in b/internal-complibs/zlib-ng-2.1.0-beta1/test/Makefile.in new file mode 100644 index 000000000..d2658e7ce --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/Makefile.in @@ -0,0 +1,82 @@ +# Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler +# Copyright 2015, Daniel Axtens, IBM Corporation +# zlib license, see zlib.h + +CC= +CFLAGS= +EXE= +SRCDIR= +SRCTOP= +LIBNAME= +TEST_LDFLAGS=-L.. ../$(LIBNAME).a + +EMU_RUN= + +all: alltests + +alltests: #set by ../configure +check_cross_dep: +ifneq (,$(findstring qemu,$(EMU_RUN))) +QEMU_VER:=$(shell command -v $(EMU_RUN) --version 2> /dev/null) +ifeq (,$(QEMU_VER)) + $(error You need QEMU to run tests on non-native platform) +endif +endif + +ALL_SRC_FILES := $(wildcard ../*) + +teststatic: check_cross_dep + @TMPST=tmpst_$$$$; \ + HELLOST=tmphellost_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzip$(EXE) > $$HELLOST && ${EMU_RUN} ../minigzip$(EXE) -d < $$HELLOST && ${EMU_RUN} ../example$(EXE) $$TMPST; then \ + echo ' *** zlib test OK ***'; \ + else \ + echo ' *** zlib test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPST $$HELLOST + +testshared: check_cross_dep + @LD_LIBRARY_PATH=`pwd`/..:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \ + LD_LIBRARYN32_PATH=`pwd`/..:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \ + DYLD_LIBRARY_PATH=`pwd`/..:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \ + SHLIB_PATH=`pwd`/..:$(SHLIB_PATH) ; export SHLIB_PATH; \ + TMPSH=tmpsh_$$$$; \ + HELLOSH=tmphellosh_$$$$; \ + if echo hello world | ${EMU_RUN} ../minigzipsh$(EXE) > $$HELLOSH && ${EMU_RUN} ../minigzipsh$(EXE) -d < $$HELLOSH && ${EMU_RUN} ../examplesh$(EXE) $$TMPSH; then \ + echo ' *** zlib shared test OK ***'; \ + else \ + echo ' *** zlib shared test FAILED ***'; exit 1; \ + fi; \ + rm -f $$TMPSH $$HELLOSH + +.PHONY: ghtests +ghtests: testGH-361 testGH-364 testGH-751 testGH-1235 + +.PHONY: testGH-361 +testGH-361: + $(EMU_RUN) ../minigzip$(EXE) -4 <$(SRCDIR)/GH-361/test.txt >/dev/null + +switchlevels$(EXE): $(SRCDIR)/switchlevels.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-364 +testGH-364: switchlevels$(EXE) + $(EMU_RUN) ./switchlevels$(EXE) 1 5 9 3 <$(SRCDIR)/GH-364/test.bin >/dev/null + +.PHONY: testGH-751 +testGH-751: + $(EMU_RUN) ../minigzip$(EXE) <$(SRCDIR)/GH-751/test.txt | $(EMU_RUN) ../minigzip$(EXE) -d >/dev/null + +gh1235$(EXE): $(SRCDIR)/gh1235.c + $(CC) $(CFLAGS) -I.. -I$(SRCTOP) -o $@ $< $(TEST_LDFLAGS) + +.PHONY: testGH-1235 +testGH-1235: gh1235$(EXE) + $(EMU_RUN) ./gh1235$(EXE) + +clean: + rm -f *.o *.gcda *.gcno *.gcov + rm -f switchlevels$(EXE) gh1235$(EXE) + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/README.md b/internal-complibs/zlib-ng-2.1.0-beta1/test/README.md new file mode 100644 index 000000000..d844ba530 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/README.md @@ -0,0 +1,37 @@ +Contents +-------- + +|Name|Description| +|-|-| +|[CVE-2003-0107](https://nvd.nist.gov/vuln/detail/CVE-2003-0107)|Buffer overflow in the gzprintf function, requires ZLIB_COMPAT| +|[CVE-2002-0059](https://nvd.nist.gov/vuln/detail/CVE-2002-0059)|inflateEnd to release memory more than once| +|[CVE-2004-0797](https://nvd.nist.gov/vuln/detail/CVE-2004-0797)|Error handling in inflate and inflateBack causes crash| +|[CVE-2005-1849](https://nvd.nist.gov/vuln/detail/CVE-2005-1849)|inftrees.h bug causes crash| +|[CVE-2005-2096](https://nvd.nist.gov/vuln/detail/CVE-2005-2096)|Buffer overflow when incomplete code description| +|[CVE-2018-25032](https://nvd.nist.gov/vuln/detail/CVE-2018-25032)|Memory corruption when compressing if the input has many distant matches.| +|[GH-361](https://github.com/zlib-ng/zlib-ng/issues/361)|Test case for overlapping matches| +|[GH-364](https://github.com/zlib-ng/zlib-ng/issues/364)|Test case for switching compression levels| +|[GH-382](https://github.com/zlib-ng/zlib-ng/issues/382)|Test case for deflateEnd returning -3 in deflate quick| + +Copying +------- + +Some of the files in _test_ are licensed differently: + + - test/data/fireworks.jpeg is Copyright 2013 Steinar H. Gunderson, and + is licensed under the Creative Commons Attribution 3.0 license + (CC-BY-3.0). See https://creativecommons.org/licenses/by/3.0/ + for more information. + + - test/data/paper-100k.pdf is an excerpt (bytes 92160 to 194560) from the paper + “Combinatorial Modeling of Chromatin Features Quantitatively Predicts DNA + Replication Timing in _Drosophila_†by Federico Comoglio and Renato Paro, + which is licensed under the CC-BY license. See + https://www.ploscompbiol.org/static/license for more information. + + - test/data/lcet10.txt is from Project Gutenberg. It does not have expired + copyright, but is still in the public domain according to the license information. + (https://www.gutenberg.org/ebooks/53). + + - test/GH-382/defneg3.dat was the smallest file generated by Nathan Moinvaziri + that reproduced GH-382. It is licensed under the terms of the zlib license. diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/ignore b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/ignore new file mode 100644 index 000000000..dba3639cb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/ignore @@ -0,0 +1,12 @@ +# See https://sourceware.org/libabigail/manual/libabigail-concepts.html#suppression-specifications + +[suppress_type] + name = internal_state + +[suppress_type] + name_regexp = z_stream.* + +# Size varies with version number +[suppress_variable] + name = zlibng_string + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..c9088b86f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..48f8fb6bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..cee35ca46 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3d7ca82c1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..ad037fd6a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..5ef350b4d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1268 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..569d084b9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,1263 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..b2a63a4bd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-04f42ceca40f73e2978b50e93806c2a18c1281fc-x86_64-pc-linux-gnu.abi @@ -0,0 +1,1281 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi new file mode 100644 index 000000000..cfc0eddc6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-aarch64-unknown-linux-gnu.abi @@ -0,0 +1,1904 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi new file mode 100644 index 000000000..414f8a96e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabi.abi @@ -0,0 +1,1889 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi new file mode 100644 index 000000000..f5b3aa773 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-arm-unknown-linux-gnueabihf.abi @@ -0,0 +1,1881 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi new file mode 100644 index 000000000..3164f07e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc-unknown-linux-gnu.abi @@ -0,0 +1,1895 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi new file mode 100644 index 000000000..1d97902bc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64-unknown-linux-gnu.abi @@ -0,0 +1,1894 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi new file mode 100644 index 000000000..613f5f2f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-powerpc64le-unknown-linux-gnu.abi @@ -0,0 +1,1886 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi new file mode 100644 index 000000000..82d8943b8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu-m32.abi @@ -0,0 +1,2032 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi new file mode 100644 index 000000000..a03df554a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abi/zlib-ng-e4614ebcb9b3e5b108dc983c155e4baf80882311-x86_64-pc-linux-gnu.abi @@ -0,0 +1,2064 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.md b/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.md new file mode 100644 index 000000000..57337f588 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.md @@ -0,0 +1,59 @@ +ABI Compatibility test +---------------------- + +abicheck.sh uses libabigail to check ABI stability. +It will abort if the current source +tree has a change that breaks binary compatibility. + +This protects against the common scenario where: +- an app is compiled against the current zlib-ng +- the system package manager updates the zlib-ng shared library +- the app now crashes because some symbol is + missing or some public structure or parameter + has changed type or size + +If run with --zlib-compat, it verifies that the +current source tree generates a library that +is ABI-compatible with the reference release +of classic zlib. This ensures that building +zlib-ng with --zlib-compat does what it says on the tin. + +abicheck.sh is not perfect, but it can catch +many common compatibility issues. + +Cached files test/abi/*.abi +--------------------------- + +Comparing to the old version of zlib (or zlib-ng) +means someone has to check out and build +the previous source tree and extract its .abi +using abidw. This can be slow. + +If you don't mind the slowness, run abicheck.sh --refresh-if, +and it will download and build the reference version +and extract the .abi on the spot if needed. +(FIXME: should this be the default?) + +On the next run, the reference .abi file will already be +present, and that step will be skipped. +It's stored in the tests/abi directory, +in a file with the architecture and git hash in the name. + +If you're running continuous integration +which clear out the source tree on each run, +and you don't want your build machines +constantly downloading and building the old +version, you can check the .abi file into git. + +To make this easier, a helper script could be written to automatically build +all the configurations tested by .github/workflows/abicheck.yml +Then they could be checked into git en masse by a maintainer +when a new platform is added or a new major version (which +intentionally breaks backwards compatibility) is being prepared. + +Further reading +--------------- + +- https://sourceware.org/libabigail/manual/ +- https://developers.redhat.com/blog/2014/10/23/comparing-abis-for-compatibility-with-libabigail-part-1/ +- https://developers.redhat.com/blog/2020/04/02/how-to-write-an-abi-compliance-checker-using-libabigail/ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.sh b/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.sh new file mode 100755 index 000000000..1656711f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/abicheck.sh @@ -0,0 +1,163 @@ +#!/bin/sh +set -ex +TESTDIR="$(cd $(dirname "$0"); pwd)" + +usage() { + cat <<_EOF_ +Usage: $0 [--zlib-compat][--refresh][--refresh-if] + +Build shared library with -ggdb, then compare its ABI to the stable +ABI, and abort if differences found. + +Options: +--zlib-compat - check the ABI of the zlib-compatible flavor of zlib-ng. +--refresh - build the reference library and extract its ABI rather than using a stored ABI file. +--refresh-if - refresh only if ABI file not present. + +Obeys CHOST, CONFIGURE_ARGS, CFLAGS, and LDFLAGS. + +Requires libabigail (on Ubuntu, install package abigail-tools). +_EOF_ +} + +# Print the multiarch tuple for the current (non-cross) machine, +# or the empty string if unavailable. +detect_chost() { + dpkg-architecture -qDEB_HOST_MULTIARCH || + $CC -print-multiarch || + $CC -print-search-dirs | sed 's/:/\n/g' | grep -E '^/lib/[^/]+$' | sed 's%.*/%%' || + true +} + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +suffix="-ng" +CONFIGURE_ARGS_NG="$CONFIGURE_ARGS" +refresh=false +refresh_if=false +for arg +do + case "$arg" in + --zlib-compat) + suffix="" + CONFIGURE_ARGS_NG="$CONFIGURE_ARGS_NG --zlib-compat" + ;; + --refresh) + refresh=true + ;; + --refresh-if) + refresh_if=true + ;; + --help) + usage + exit 0 + ;; + *) + echo "Unknown arg '$arg'" + usage + exit 1 + ;; + esac +done + +# Choose reference repo and commit +if test "$suffix" = "" +then + # Reference is zlib 1.2.13. + ABI_GIT_REPO=https://github.com/madler/zlib.git + ABI_GIT_COMMIT=04f42ceca40f73e2978b50e93806c2a18c1281fc +else + # Reference is most recent zlib-ng develop with zlib 1.2.12 compatible api. + ABI_GIT_REPO=https://github.com/zlib-ng/zlib-ng.git + ABI_GIT_COMMIT=e4614ebcb9b3e5b108dc983c155e4baf80882311 +fi + +# Test compat build for ABI compatibility with zlib +if test "$CHOST" = "" +then + # Note: don't export CHOST here, as we don't want configure seeing it + # when it's just the name for the build machine. + # Leave it as a plain shell variable, not an environment variable. + CHOST=$(detect_chost) + # Support -m32 for non-cross builds. + case "$CFLAGS" in + *-m32*) M32="-m32";; + *) M32="";; + esac +fi + +# Canonicalize CHOST to work around bug in original zlib's configure +# (Don't export it if it wasn't already exported, else may cause +# default compiler detection failure and shared library link error +# when building both zlib and zlib-ng. +# See https://github.com/zlib-ng/zlib-ng/issues/1219) +CHOST=$(sh $TESTDIR/../tools/config.sub $CHOST) + +if test "$CHOST" = "" +then + echo "abicheck: SKIP, as we don't know CHOST" + exit 0 +fi + +ABIFILE="test/abi/zlib$suffix-$ABI_GIT_COMMIT-$CHOST$M32.abi" +if ! $refresh && $refresh_if && ! test -f "$ABIFILE" +then + refresh=true +fi +abidw --version + +if $refresh +then + # Check out reference source + rm -rf btmp1 + mkdir -p btmp1/src.d + cd btmp1/src.d + git init + git remote add origin $ABI_GIT_REPO + git fetch origin $ABI_GIT_COMMIT + git reset --hard FETCH_HEAD + cd .. + # Build unstripped, uninstalled, very debug shared library + CFLAGS="$CFLAGS -ggdb" src.d/configure $CONFIGURE_ARGS + make -j2 + cd .. + # Find shared library, extract its abi + dylib1=$(find btmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + abidw $dylib1 > "$ABIFILE" + # Maintainers may wish to check $ABIFILE into git when a new + # target is added, or when a major release happens that is + # intended to change the ABI. Alternately, this script could + # just always rebuild the reference source, and dispense with + # caching abi files in git (but that would slow builds down). +fi + +if ! test -f "$ABIFILE" +then + echo "abicheck: SKIP: $ABIFILE not found; rerun with --refresh or --refresh-if" + exit 1 +fi + +# Build unstripped, uninstalled, very debug shared library +rm -rf btmp2 +mkdir btmp2 +cd btmp2 +CFLAGS="$CFLAGS -ggdb" ../configure $CONFIGURE_ARGS_NG +make -j2 +cd .. +# Find shared library, extract its abi +dylib2=$(find btmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) +abidw $dylib2 > btmp2/zlib${suffix}-built.abi + +# Compare it to the reference +# FIXME: use --no-added-syms for now, but we probably want to be more strict. +if abidiff --no-added-syms --suppressions test/abi/ignore "$ABIFILE" btmp2/zlib${suffix}-built.abi +then + echo "abicheck: PASS" +else + echo "abicheck: FAIL" + exit 1 +fi diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/CMakeLists.txt new file mode 100644 index 000000000..1b87005f7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.5.1) + +project(zlib-ng-add-subdirecory-test C) + +include(CTest) + +set(BUILD_SHARED_LIBS OFF) +set(ZLIB_ENABLE_TESTS ON CACHE BOOL "Build test binaries" FORCE) + +add_subdirectory(../.. zlib-ng) + +add_executable(app main.c) +target_link_libraries(app zlibstatic) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/main.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/main.c new file mode 100644 index 000000000..638a35b1d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/add-subdirectory-project/main.c @@ -0,0 +1,7 @@ +#include +#include "zlib-ng.h" + +int main(void) { + printf("zlib-ng: %s\n", ZLIBNG_VERSION); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/CMakeLists.txt new file mode 100644 index 000000000..ebc6acb78 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/CMakeLists.txt @@ -0,0 +1,107 @@ +cmake_minimum_required(VERSION 3.12) + +include(FetchContent) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) +enable_language(CXX) + +# Search for Google benchmark package +find_package(benchmark QUIET) +if(NOT benchmark_FOUND) + # Fetch google benchmark source code from official repository + set(BENCHMARK_ENABLE_TESTING OFF) + + # Allow specifying alternative Google benchmark repository + if(NOT DEFINED GBENCHMARK_REPOSITORY) + set(GBENCHMARK_REPOSITORY https://github.com/google/benchmark.git) + endif() + if(NOT DEFINED GBENCHMARK_TAG) + set(GBENCHMARK_TAG v1.7.1) + endif() + + FetchContent_Declare(benchmark + GIT_REPOSITORY ${GBENCHMARK_REPOSITORY} + GIT_TAG ${GBENCHMARK_TAG}) + + FetchContent_GetProperties(benchmark) + if(NOT benchmark_POPULATED) + FetchContent_Populate(benchmark) + add_subdirectory(${benchmark_SOURCE_DIR} ${benchmark_BINARY_DIR} EXCLUDE_FROM_ALL) + endif() +endif() + +add_executable(benchmark_zlib + benchmark_adler32.cc + benchmark_adler32_copy.cc + benchmark_compare256.cc + benchmark_crc32.cc + benchmark_main.cc + benchmark_slidehash.cc + ) + +target_compile_definitions(benchmark_zlib PRIVATE -DBENCHMARK_STATIC_DEFINE) +target_include_directories(benchmark_zlib PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + +target_link_libraries(benchmark_zlib zlibstatic benchmark::benchmark) +if(WIN32) + target_link_libraries(benchmark_zlib shlwapi) +endif() + +if(ZLIB_ENABLE_TESTS) + add_test(NAME benchmark_zlib + COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) +endif() + +if(WITH_BENCHMARK_APPS) + option(BUILD_ALT_BENCH "Link against alternative zlib implementation" OFF) + + # Search for libpng package + find_package(PNG QUIET) + + if(NOT PNG_FOUND) + FetchContent_Declare(PNG + GIT_REPOSITORY https://github.com/glennrp/libpng.git) + + FetchContent_GetProperties(PNG) + if(NOT PNG_POPULATED) + FetchContent_Populate(PNG) + add_subdirectory(${PNG_SOURCE_DIR} ${PNG_BINARY_DIR}) + endif() + endif() + + set(BENCH_APP_SRCS + benchmark_png_encode.cc + benchmark_png_decode.cc + benchmark_main.cc + ) + + add_executable(benchmark_zlib_apps ${BENCH_APP_SRCS}) + + if(DEFINED BUILD_ALT_BENCH) + set(ZLIB_ALT_LIB "libz.a" CACHE FILEPATH "Optional alternative zlib implementation (defaults to stock zlib)") + add_executable(benchmark_zlib_apps_alt ${BENCH_APP_SRCS}) + target_link_libraries(benchmark_zlib_apps_alt libpng.a ${ZLIB_ALT_LIB} benchmark::benchmark) + target_compile_definitions(benchmark_zlib_apps_alt PRIVATE BUILD_ALT=1) + target_include_directories(benchmark_zlib_apps_alt PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + endif() + + target_include_directories(benchmark_zlib_apps PRIVATE + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${PNG_INCLUDE_DIR} + ${benchmark_SOURCE_DIR}/benchmark/include) + + # We need the static png library if we're statically linking to zlib, + # otherwise it will resolve these things in the system provided dynamic + # libraries (likely linked to stock zlib) + target_link_libraries(benchmark_zlib_apps libpng.a zlibstatic benchmark::benchmark) +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/README.md b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/README.md new file mode 100644 index 000000000..5dce7f51b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/README.md @@ -0,0 +1,47 @@ +## Benchmarks +These benchmarks are written using [Google Benchmark](https://github.com/google/benchmark). + +*Repetitions* + +To increase the number of times each benchmark iteration is run use: + +``` +--benchmark_repetitions=20 +``` + +*Filters* + +To filter out which benchmarks are performed use: + +``` +--benchmark_filter="adler32*" +``` + +There are two different benchmarks, micro and macro. + +### Benchmark benchmark_zlib +These are microbenchmarks intended to test lower level subfunctions of the library. + +Benchmarks include impelementations of: + - Adler32 + - CRC + - 256 byte comparisons + - SIMD accelerated "slide hash" routine + +By default these benchmarks report things on the nanosecond scale and are small enough +to measure very minute diferences. + +### Benchmark benchmark_zlib_apps +These benchmarks measure applications of zlib as a whole. Currently the only examples +are PNG encoding and decoding. The PNG encode and decode tests leveraging procedurally +generated and highly compressible image data. + +Additionally, a test called `png_decode_realistic` that will decode any RGB 8 BPP encoded +set of PNGs in the working directory under a directory named "test_pngs" with files named +{0..1}.png. If these images do not exist, they will error out and the benchmark will move +on to the next set of benchmarks. + +*benchmark_zlib_apps_alt* + +The user can compile a comparison benchmark application linking to any zlib-compatible +implementation of his or her choosing. diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32.cc new file mode 100644 index 000000000..5b0b65d67 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32.cc @@ -0,0 +1,89 @@ +/* benchmark_adler32.cc -- benchmark adler32 variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class adler32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_func adler32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_ADLER32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32, name)->Range(2048, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32(c, adler32_c, 1); + +#ifdef ARM_NEON +BENCHMARK_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +BENCHMARK_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +BENCHMARK_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSSE3 +BENCHMARK_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32_copy.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32_copy.cc new file mode 100644 index 000000000..cbee780b7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_adler32_copy.cc @@ -0,0 +1,118 @@ +/* benchmark_adler32_copy.cc -- benchmark adler32 (elided copy) variants + * Copyright (C) 2022 Nathan Moinvaziri, Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +typedef uint32_t (*adler32_cpy_func)(uint32_t adler, unsigned char *dst, const uint8_t *buf, size_t len); + +class adler32_copy: public benchmark::Fixture { +private: + uint32_t *random_ints_src; + uint32_t *random_ints_dst; + +public: + void SetUp(const ::benchmark::State& state) { + /* Control the alignment so that we have the best case scenario for loads. With + * AVX512, unaligned loads can mean we're crossing a cacheline boundary at every load. + * And while this is a realistic scenario, it makes it difficult to compare benchmark + * to benchmark because one allocation could have been aligned perfectly for the loads + * while the subsequent one happened to not be. This is not to be advantageous to AVX512 + * (indeed, all lesser SIMD implementations benefit from this aligned allocation), but to + * control the _consistency_ of the results */ + random_ints_src = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + random_ints_dst = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints_src != NULL); + assert(random_ints_dst != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints_src[i] = rand(); + } + } + + void Bench(benchmark::State& state, adler32_cpy_func adler32_func) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = adler32_func(hash, (unsigned char *)random_ints_dst, + (const unsigned char*)random_ints_src, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints_src); + zng_free(random_ints_dst); + } +}; + +#define BENCHMARK_ADLER32_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +#define BENCHMARK_ADLER32_BASELINE_COPY(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(adler32_copy, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, [](uint32_t init_sum, unsigned char *dst, \ + const uint8_t *buf, size_t len) -> uint32_t { \ + memcpy(dst, buf, (size_t)len); \ + return fptr(init_sum, buf, len); \ + }); \ + } \ + BENCHMARK_REGISTER_F(adler32_copy, name)->Range(8192, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_ADLER32_BASELINE_COPY(c, adler32_c, 1); + +#ifdef ARM_NEON +/* If we inline this copy for neon, the function would go here */ +//BENCHMARK_ADLER32_COPY(neon, adler32_neon, test_cpu_features.arm.has_neon); +BENCHMARK_ADLER32_BASELINE_COPY(neon_copy_baseline, adler32_neon, test_cpu_features.arm.has_neon); +#endif + +#ifdef PPC_VMX +//BENCHMARK_ADLER32_COPY(vmx_inline_copy, adler32_fold_copy_vmx, test_cpu_features.power.has_altivec); +BENCHMARK_ADLER32_BASELINE_COPY(vmx_copy_baseline, adler32_vmx, test_cpu_features.power.has_altivec); +#endif +#ifdef POWER8_VSX +//BENCHMARK_ADLER32_COPY(power8_inline_copy, adler32_fold_copy_power8, test_cpu_features.power.has_arch_2_07); +BENCHMARK_ADLER32_BASELINE_COPY(power8, adler32_power8, test_cpu_features.power.has_arch_2_07); +#endif + +#ifdef X86_SSE42 +BENCHMARK_ADLER32_BASELINE_COPY(sse42_baseline, adler32_ssse3, test_cpu_features.x86.has_ssse3); +BENCHMARK_ADLER32_COPY(sse42, adler32_fold_copy_sse42, test_cpu_features.x86.has_sse42); +#endif +#ifdef X86_AVX2 +BENCHMARK_ADLER32_BASELINE_COPY(avx2_baseline, adler32_avx2, test_cpu_features.x86.has_avx2); +BENCHMARK_ADLER32_COPY(avx2, adler32_fold_copy_avx2, test_cpu_features.x86.has_avx2); +#endif +#ifdef X86_AVX512 +BENCHMARK_ADLER32_BASELINE_COPY(avx512_baseline, adler32_avx512, test_cpu_features.x86.has_avx512); +BENCHMARK_ADLER32_COPY(avx512, adler32_fold_copy_avx512, test_cpu_features.x86.has_avx512); +#endif +#ifdef X86_AVX512VNNI +BENCHMARK_ADLER32_BASELINE_COPY(avx512_vnni_baseline, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +BENCHMARK_ADLER32_COPY(avx512_vnni, adler32_fold_copy_avx512_vnni, test_cpu_features.x86.has_avx512vnni); +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_compare256.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_compare256.cc new file mode 100644 index 000000000..3ab04d202 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_compare256.cc @@ -0,0 +1,84 @@ +/* benchmark_compare256.cc -- benchmark compare256 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_COMPARE_SIZE (256) + +class compare256: public benchmark::Fixture { +private: + uint8_t *str1; + uint8_t *str2; + +public: + void SetUp(const ::benchmark::State& state) { + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + assert(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + } + + void Bench(benchmark::State& state, compare256_func compare256) { + int32_t match_len = (int32_t)state.range(0) - 1; + uint32_t len = 0; + + str2[match_len] = 0; + for (auto _ : state) { + len = compare256((const uint8_t *)str1, (const uint8_t *)str2); + } + str2[match_len] = 'a'; + + benchmark::DoNotOptimize(len); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(str1); + zng_free(str2); + } +}; + +#define BENCHMARK_COMPARE256(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(compare256, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(compare256, name)->Range(1, MAX_COMPARE_SIZE); + +BENCHMARK_COMPARE256(c, compare256_c, 1); + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +BENCHMARK_COMPARE256(unaligned_16, compare256_unaligned_16, 1); +#ifdef HAVE_BUILTIN_CTZ +BENCHMARK_COMPARE256(unaligned_32, compare256_unaligned_32, 1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(unaligned_64, compare256_unaligned_64, 1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +BENCHMARK_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +BENCHMARK_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER9 +BENCHMARK_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00); +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_crc32.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_crc32.cc new file mode 100644 index 000000000..b2b9673d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_crc32.cc @@ -0,0 +1,69 @@ +/* benchmark_crc32.cc -- benchmark crc32 variants + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS (1024 * 1024) +#define MAX_RANDOM_INTS_SIZE (MAX_RANDOM_INTS * sizeof(uint32_t)) + +class crc32: public benchmark::Fixture { +private: + uint32_t *random_ints; + +public: + void SetUp(const ::benchmark::State& state) { + random_ints = (uint32_t *)zng_alloc(MAX_RANDOM_INTS_SIZE); + assert(random_ints != NULL); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + random_ints[i] = rand(); + } + } + + void Bench(benchmark::State& state, crc32_func crc32) { + uint32_t hash = 0; + + for (auto _ : state) { + hash = crc32(hash, (const unsigned char *)random_ints, (size_t)state.range(0)); + } + + benchmark::DoNotOptimize(hash); + } + + void TearDown(const ::benchmark::State& state) { + zng_free(random_ints); + } +}; + +#define BENCHMARK_CRC32(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(crc32, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(crc32, name)->Range(1, MAX_RANDOM_INTS_SIZE); + +BENCHMARK_CRC32(braid, PREFIX(crc32_braid), 1); + +#ifdef ARM_ACLE +BENCHMARK_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32); +#elif defined(POWER8_VSX) +BENCHMARK_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07); +#elif defined(S390_CRC32_VX) +BENCHMARK_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx); +#elif defined(X86_PCLMULQDQ_CRC) +/* CRC32 fold does a memory copy while hashing */ +BENCHMARK_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq); +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_main.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_main.cc new file mode 100644 index 000000000..3ef2c5e87 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_main.cc @@ -0,0 +1,28 @@ +/* benchmark_main.cc -- benchmark suite main entry point + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +#ifndef BUILD_ALT +extern "C" { +# include "zbuild.h" +# include "../test_cpu_features.h" + + struct cpu_features test_cpu_features; +} +#endif + +int main(int argc, char** argv) { +#ifndef BUILD_ALT + cpu_check_features(&test_cpu_features); +#endif + + ::benchmark::Initialize(&argc, argv); + ::benchmark::RunSpecifiedBenchmarks(); + + return EXIT_SUCCESS; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_decode.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_decode.cc new file mode 100644 index 000000000..c037976c8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_decode.cc @@ -0,0 +1,126 @@ +#include +#include +#include "benchmark_png_shared.h" +#include + +class png_decode: public benchmark::Fixture { +protected: + png_dat inpng[10]; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *output_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width*height); + } + + void SetUp(const ::benchmark::State& state) { + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + assert(output_img_buf != NULL); + init_img(output_img_buf, IMWIDTH, IMHEIGHT); + + /* First we need to author the png bytes to be decoded */ + for (int i = 0; i < 10; ++i) { + inpng[i] = {NULL, 0, 0}; + encode_png(output_img_buf, &inpng[i], i, IMWIDTH, IMHEIGHT); + } + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + int compress_lvl = state.range(0); + png_parse_dat in = { inpng[compress_lvl].buf }; + uint32_t width, height; + decode_png(&in, (png_bytepp)&output_img_buf, IMWIDTH * IMHEIGHT * 3, width, height); + } + } + + void TearDown(const ::benchmark::State &state) { + free(output_img_buf); + for (int i = 0; i < 10; ++i) { + free(inpng[i].buf); + } + } +}; + +class png_decode_realistic: public png_decode { +private: + bool test_files_found = false; + +public: + void SetUp(const ::benchmark::State &state) { + output_img_buf = NULL; + output_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Let's take all the images at different compression levels and jam their bytes into buffers */ + char test_fname[25]; + FILE *files[10]; + + /* Set all to NULL */ + memset(files, 0, sizeof(FILE*)); + + for (size_t i = 0; i < 10; ++i) { + sprintf(test_fname, "test_pngs/%1lu.png", i); + FILE *in_img = fopen(test_fname, "r"); + if (in_img == NULL) { + for (size_t j = 0; j < i; ++j) { + if (files[j]) + fclose(files[j]); + } + + /* For proper cleanup */ + for (size_t j = i; j < 10; ++j) { + inpng[i] = { NULL, 0, 0 }; + } + + return; + } + files[i] = in_img; + } + + test_files_found = true; + /* Now that we've established we have all the png files, let's read all of their bytes into buffers */ + for (size_t i = 0; i < 10; ++i) { + FILE *in_file = files[i]; + fseek(in_file, 0, SEEK_END); + size_t num_bytes = ftell(in_file); + rewind(in_file); + + uint8_t *raw_file = (uint8_t*)malloc(num_bytes); + if (raw_file == NULL) + abort(); + + inpng[i].buf = raw_file; + inpng[i].len = num_bytes; + inpng[i].buf_rem = 0; + + size_t bytes_read = fread(raw_file, 1, num_bytes, in_file); + if (bytes_read != num_bytes) { + fprintf(stderr, "couldn't read all of the bytes for file test_pngs/%lu.png", i); + abort(); + } + + fclose(in_file); + } + } + + void Bench(benchmark::State &state) { + if (!test_files_found) { + state.SkipWithError("Test imagery in test_pngs not found"); + } + + png_decode::Bench(state); + } +}; + +BENCHMARK_DEFINE_F(png_decode, png_decode)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode, png_decode)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); + +BENCHMARK_DEFINE_F(png_decode_realistic, png_decode_realistic)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_decode_realistic, png_decode_realistic)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_encode.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_encode.cc new file mode 100644 index 000000000..f1c597d36 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_encode.cc @@ -0,0 +1,54 @@ +#include +#include +#include +#include "benchmark_png_shared.h" + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +class png_encode: public benchmark::Fixture { +private: + png_dat outpng; + + /* Backing this on the heap is a more realistic benchmark */ + uint8_t *input_img_buf = NULL; + +public: + /* Let's make the vanilla version have something extremely compressible */ + virtual void init_img(png_bytep img_bytes, size_t width, size_t height) { + init_compressible(img_bytes, width * height); + } + + void SetUp(const ::benchmark::State& state) { + input_img_buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + outpng.buf = (uint8_t*)malloc(IMWIDTH * IMHEIGHT * 3); + /* Using malloc rather than zng_alloc so that we can call realloc. + * IMWIDTH * IMHEIGHT is likely to be more than enough bytes, though, + * given that a simple run length encoding already pretty much can + * reduce to this */ + outpng.len = 0; + outpng.buf_rem = IMWIDTH * IMHEIGHT * 3; + assert(input_img_buf != NULL); + assert(outpng.buf != NULL); + init_img(input_img_buf, IMWIDTH, IMHEIGHT); + } + + /* State in this circumstance will convey the compression level */ + void Bench(benchmark::State &state) { + for (auto _ : state) { + encode_png((png_bytep)input_img_buf, &outpng, state.range(0), IMWIDTH, IMHEIGHT); + outpng.buf_rem = outpng.len; + outpng.len = 0; + } + } + + void TearDown(const ::benchmark::State &state) { + free(input_img_buf); + free(outpng.buf); + } +}; + +BENCHMARK_DEFINE_F(png_encode, encode_compressible)(benchmark::State &state) { + Bench(state); +} +BENCHMARK_REGISTER_F(png_encode, encode_compressible)->DenseRange(0, 9, 1)->Unit(benchmark::kMicrosecond); diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_shared.h b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_shared.h new file mode 100644 index 000000000..926b4d964 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_png_shared.h @@ -0,0 +1,146 @@ +#pragma once + +#include +#include +#include + +#define IMWIDTH 1024 +#define IMHEIGHT 1024 + +extern "C" { +# include +} + +typedef struct _png_dat { + uint8_t *buf; + int64_t len; + size_t buf_rem; +} png_dat; + +typedef struct _png_parse_dat { + uint8_t *cur_pos; +} png_parse_dat; + +/* Write a customized write callback so that we write back to an in-memory buffer. + * This allows the testing to not involve disk IO */ +static void png_write_cb(png_structp pngp, png_bytep data, png_size_t len) { + png_dat *dat = (png_dat*)png_get_io_ptr(pngp); + size_t curSize = dat->len + len; + + /* realloc double the requested buffer size to prevent excessive reallocs */ + if (dat->buf_rem < len) { + dat->buf = (uint8_t*)realloc(dat->buf, dat->len + dat->buf_rem + 2 * len); + + if (!dat->buf) { + /* Pretty unlikely but we'll put it here just in case */ + fprintf(stderr, "realloc failed, exiting\n"); + exit(1); + } + + dat->buf_rem += 2 * len; + } + + memcpy(dat->buf + dat->len, data, len); + dat->len = curSize; + dat->buf_rem -= len; +} + +static void init_compressible(png_bytep buf, size_t num_pix) { + /* It doesn't actually matter what we make this, but for + * the sake of a reasonable test image, let's make this + * be a stripe of R, G, & B, with no alpha channel */ + int32_t i = 0; + int32_t red_stop = num_pix / 3; + int32_t blue_stop = 2 * num_pix / 3; + int32_t green_stop = num_pix; + + for (int32_t x = 0; i < red_stop; x += 3, ++i) { + buf[x] = 255; + buf[x + 1] = 0; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < blue_stop; x+= 3, ++i) { + buf[x] = 0; + buf[x + 1] = 255; + buf[x + 2] = 0; + } + + for (int32_t x = 3 * i; i < green_stop; x += 3, ++i) { + buf[x] = 0; + buf[x + 1] = 0; + buf[x + 2] = 255; + } +} + +static inline void encode_png(png_bytep buf, png_dat *outpng, int32_t comp_level, uint32_t width, uint32_t height) { + png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + /* Most of this error handling is _likely_ not necessary. Likewise it's likely + * a lot of this stuff can be done in the setup function to avoid measuring this + * fixed setup time, but for now we'll do it here */ + if (!png) abort(); + + png_infop info = png_create_info_struct(png); + if (!info) abort(); + + png_set_write_fn(png, outpng, png_write_cb, NULL); + png_bytep *png_row_ptrs = new png_bytep[height]; + for (int i = 0; i < IMHEIGHT; ++i) { + png_row_ptrs[i] = (png_bytep)&buf[3*i*width]; + } + + png_set_IHDR(png, info, IMWIDTH, IMHEIGHT, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + + png_write_info(png, info); + png_set_compression_level(png, comp_level); + png_set_filter(png, 0, PNG_FILTER_NONE); + png_write_image(png, (png_bytepp)png_row_ptrs); + png_write_end(png, NULL); + png_destroy_write_struct(&png, &info); + delete[] png_row_ptrs; +} + +static void read_from_pngdat(png_structp png, png_bytep out, png_size_t bytes_to_read) { + png_parse_dat *io = (png_parse_dat*)png_get_io_ptr(png); + memcpy(out, io->cur_pos, bytes_to_read); + io->cur_pos += bytes_to_read; +} + +static inline int decode_png(png_parse_dat *dat, png_bytepp out_bytes, size_t in_size, uint32_t &width, uint32_t &height) { + png_structp png = NULL; + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + + if (!png) abort(); + png_infop info = NULL; + info = png_create_info_struct(png); + if (!info) abort(); + + png_set_read_fn(png, dat, read_from_pngdat); + png_read_info(png, info); + + int bit_depth = 0, color_type = -1; + png_get_IHDR(png, info, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL); + + size_t im_size = width * height * bit_depth/8 * 3; + if (color_type != PNG_COLOR_TYPE_RGB) { + fprintf(stderr, "expected an 8 bpp RGB image\n"); + abort(); + } + + if (im_size > in_size) { + *out_bytes = (png_bytep)realloc(*out_bytes, im_size); + } + + png_bytep *out_rows = new png_bytep[height]; + for (size_t i = 0; i < height; ++i) + out_rows[i] = *out_bytes + (width*i*3); + + png_read_rows(png, out_rows, NULL, height); + png_destroy_read_struct(&png, &info, NULL); + delete[] out_rows; + + return im_size; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_slidehash.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_slidehash.cc new file mode 100644 index 000000000..238cc1f65 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/benchmarks/benchmark_slidehash.cc @@ -0,0 +1,86 @@ +/* benchmark_slidehash.cc -- benchmark slide_hash variants + * Copyright (C) 2022 Adam Stylinski, Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "deflate.h" +# include "../test_cpu_features.h" +} + +#define MAX_RANDOM_INTS 32768 + +class slide_hash: public benchmark::Fixture { +private: + uint16_t *l0; + uint16_t *l1; + deflate_state *s_g; + +public: + void SetUp(const ::benchmark::State& state) { + l0 = (uint16_t *)zng_alloc(HASH_SIZE * sizeof(uint16_t)); + + for (uint32_t i = 0; i < HASH_SIZE; i++) { + l0[i] = rand(); + } + + l1 = (uint16_t *)zng_alloc(MAX_RANDOM_INTS * sizeof(uint16_t)); + + for (int32_t i = 0; i < MAX_RANDOM_INTS; i++) { + l1[i] = rand(); + } + + deflate_state *s = (deflate_state*)malloc(sizeof(deflate_state)); + s->head = l0; + s->prev = l1; + s_g = s; + } + + void Bench(benchmark::State& state, slide_hash_func slide_hash) { + s_g->w_size = (uint32_t)state.range(0); + + for (auto _ : state) { + slide_hash(s_g); + benchmark::DoNotOptimize(s_g); + } + } + + void TearDown(const ::benchmark::State& state) { + zng_free(l0); + zng_free(l1); + } +}; + +#define BENCHMARK_SLIDEHASH(name, fptr, support_flag) \ + BENCHMARK_DEFINE_F(slide_hash, name)(benchmark::State& state) { \ + if (!support_flag) { \ + state.SkipWithError("CPU does not support " #name); \ + } \ + Bench(state, fptr); \ + } \ + BENCHMARK_REGISTER_F(slide_hash, name)->RangeMultiplier(2)->Range(1024, MAX_RANDOM_INTS); + +BENCHMARK_SLIDEHASH(c, slide_hash_c, 1); + +#ifdef ARM_NEON +BENCHMARK_SLIDEHASH(neon, slide_hash_neon, test_cpu_features.arm.has_neon); +#endif +#ifdef POWER8_VSX +BENCHMARK_SLIDEHASH(power8, slide_hash_power8, test_cpu_features.power.has_arch_2_07); +#endif +#ifdef PPC_VMX +BENCHMARK_SLIDEHASH(vmx, slide_hash_vmx, test_cpu_features.power.has_altivec); +#endif + +#ifdef X86_SSE2 +BENCHMARK_SLIDEHASH(sse2, slide_hash_sse2, test_cpu_features.x86.has_sse2); +#endif +#ifdef X86_AVX2 +BENCHMARK_SLIDEHASH(avx2, slide_hash_avx2, test_cpu_features.x86.has_avx2); +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/compress-and-verify.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/compress-and-verify.cmake new file mode 100644 index 000000000..e79c50c4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/compress-and-verify.cmake @@ -0,0 +1,264 @@ +# compress-and-verify.cmake -- Runs a test against an input file to make sure that the specified +# targets are able to to compress and then decompress successfully. Optionally verify +# the results with gzip. Output files are generated with unique names to prevent parallel +# tests from corrupting one another. Default target arguments are compatible with minigzip. + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# that test a specific input file for compression or decompression. + +# Required Variables +# INPUT - Input file to test +# TARGET or - Command to run for both compress and decompress +# COMPRESS_TARGET and - Command to run to compress input file +# DECOMPRESS_TARGET - Command to run to decompress output file + +# Optional Variables +# TEST_NAME - Name of test to use when constructing output file paths +# COMPRESS_ARGS - Arguments to pass for compress command (default: -c -k) +# DECOMPRESS_ARGS - Arguments to pass to decompress command (default: -d -c) + +# GZIP_VERIFY - Verify that gzip can decompress the COMPRESS_TARGET output and +# verify that DECOMPRESS_TARGET can decompress gzip output of INPUT +# COMPARE - Verify decompressed output is the same as input +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +if(TARGET) + set(COMPRESS_TARGET ${TARGET}) + set(DECOMPRESS_TARGET ${TARGET}) +endif() + +if(NOT DEFINED INPUT OR NOT DEFINED COMPRESS_TARGET OR NOT DEFINED DECOMPRESS_TARGET) + message(FATAL_ERROR "Compress test arguments missing") +endif() + +# Set default values +if(NOT DEFINED COMPARE) + set(COMPARE ON) +endif() +if(NOT DEFINED COMPRESS_ARGS) + set(COMPRESS_ARGS -c -k) +endif() +if(NOT DEFINED DECOMPRESS_ARGS) + set(DECOMPRESS_ARGS -d -c) +endif() +if(NOT DEFINED GZIP_VERIFY) + set(GZIP_VERIFY ON) +endif() +if(NOT DEFINED SUCCESS_EXIT) + set(SUCCESS_EXIT 0) +endif() + +# Use test name from input file name +if(NOT DEFINED TEST_NAME) + get_filename_component(TEST_NAME "${INPUT}" NAME) +endif() + +# Generate unique output path so multiple tests can be executed at the same time +string(RANDOM LENGTH 6 UNIQUE_ID) +string(REPLACE "." "-" TEST_NAME "${TEST_NAME}") +set(OUTPUT_BASE "${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${TEST_NAME}-${UNIQUE_ID}") + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT_BASE}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +# Cleanup temporary files +macro(cleanup_always) + file(GLOB TEMP_FILES ${OUTPUT_BASE}*) + file(REMOVE ${TEMP_FILES}) +endmacro() +# Clean up temporary files if not on CI +macro(cleanup) + if(NOT DEFINED ENV{CI}) + cleanup_always() + endif() +endmacro() + +# Show differences between two files +macro(diff src1 src2) + find_program(XXD xxd) + if(XXD) + find_program(DIFF diff) + if(DIFF) + set(XXD_COMMAND ${XXD} ${src1} ${src1}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + set(XXD_COMMAND ${XXD} ${src2} ${src2}.hex) + execute_process(COMMAND ${XXD_COMMAND}) + + set(DIFF_COMMAND ${DIFF} -u ${src1}.hex ${src2}.hex) + execute_process(COMMAND ${DIFF_COMMAND} + OUTPUT_FILE ${src2}.diff) + + file(READ ${src2}.diff DIFF_OUTPUT) + message(STATUS "Diff:\n${DIFF_OUTPUT}") + + if(NOT DEFINED ENV{CI}) + file(REMOVE ${src1}.hex ${src2}.hex ${src2}.diff) + endif() + endif() + endif() +endmacro() + +# Compress input file +if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find compress input: ${INPUT}") +endif() + +set(COMPRESS_COMMAND ${COMPRESS_TARGET} ${COMPRESS_ARGS}) + +message(STATUS "Compress ${COMPRESS_COMMAND}") +message(STATUS " Input: ${INPUT}") +message(STATUS " Output: ${OUTPUT_BASE}.gz") + +execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMPRESS_COMMAND}" + -DINPUT=${INPUT} + -DOUTPUT=${OUTPUT_BASE}.gz + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Compress failed: ${CMD_RESULT}") +endif() + +# Decompress output +if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress input: ${OUTPUT_BASE}.gz") +endif() + +set(DECOMPRESS_COMMAND ${DECOMPRESS_TARGET} ${DECOMPRESS_ARGS}) + +message(STATUS "Decompress ${DECOMPRESS_COMMAND}") +message(STATUS " Input: ${OUTPUT_BASE}.gz") +message(STATUS " Output: ${OUTPUT_BASE}") + +execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${DECOMPRESS_COMMAND}" + -DINPUT=${OUTPUT_BASE}.gz + -DOUTPUT=${OUTPUT_BASE} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) + +if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress failed: ${CMD_RESULT}") +endif() + +if(COMPARE) + # Compare decompressed output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE} + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}) + cleanup() + message(FATAL_ERROR "Compare decompress failed: ${CMD_RESULT}") + endif() +endif() + +if(GZIP_VERIFY AND NOT "${COMPRESS_ARGS}" MATCHES "-T") + # Transparent writing does not use gzip format + find_program(GZIP gzip) + if(GZIP) + if(NOT EXISTS ${OUTPUT_BASE}.gz) + cleanup() + message(FATAL_ERROR "Cannot find gzip decompress input: ${OUTPUT_BASE}.gz") + endif() + + # Check gzip can decompress our compressed output + set(GZ_DECOMPRESS_COMMAND ${GZIP} -d) + + message(STATUS "Gzip decompress ${GZ_DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}.gz") + message(STATUS " Output: ${OUTPUT_BASE}-ungzip") + + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${GZ_DECOMPRESS_COMMAND}" + -DINPUT=${OUTPUT_BASE}.gz + -DOUTPUT=${OUTPUT_BASE}-ungzip + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compare gzip output with original input file + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-ungzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-ungzip) + cleanup() + message(FATAL_ERROR "Compare gzip decompress failed: ${CMD_RESULT}") + endif() + + # Compress input file with gzip + set(GZ_COMPRESS_COMMAND ${GZIP} --stdout) + + message(STATUS "Gzip compress ${GZ_COMPRESS_COMMAND}") + message(STATUS " Input: ${INPUT}") + message(STATUS " Output: ${OUTPUT_BASE}-gzip.gz") + + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${GZ_COMPRESS_COMMAND}" + -DINPUT=${INPUT} + -DOUTPUT=${OUTPUT_BASE}-gzip.gz + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Gzip compress failed: ${CMD_RESULT}") + endif() + + if(NOT EXISTS ${OUTPUT_BASE}-gzip.gz) + cleanup() + message(FATAL_ERROR "Cannot find decompress gzip input: ${OUTPUT_BASE}-gzip.gz") + endif() + + message(STATUS "Decompress gzip ${DECOMPRESS_COMMAND}") + message(STATUS " Input: ${OUTPUT_BASE}-gzip.gz") + message(STATUS " Output: ${OUTPUT_BASE}-gzip") + + # Check decompress target can handle gzip compressed output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${DECOMPRESS_COMMAND}" + -DINPUT=${OUTPUT_BASE}-gzip.gz + -DOUTPUT=${OUTPUT_BASE}-gzip + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + cleanup() + message(FATAL_ERROR "Decompress gzip failed: ${CMD_RESULT}") + endif() + + if(COMPARE) + # Compare original input file with gzip decompressed output + execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${INPUT} ${OUTPUT_BASE}-gzip + RESULT_VARIABLE CMD_RESULT) + + if(CMD_RESULT) + diff(${INPUT} ${OUTPUT_BASE}-gzip) + cleanup() + message(FATAL_ERROR "Compare decompress gzip failed: ${CMD_RESULT}") + endif() + endif() + endif() +endif() + +cleanup_always() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-compare.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-compare.cmake new file mode 100644 index 000000000..eb2218dcb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-compare.cmake @@ -0,0 +1,72 @@ +# run-and-compare.cmake -- Runs a command and compares its output to an expected value + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Required Variables +# COMMAND - Command to run +# OUTPUT - Standard output +# COMPARE - String to compare output against + +# Optional Variables +# INPUT - Standard input +# IGNORE_LINE_ENDINGS - Ignore line endings when comparing output + +if(NOT DEFINED OUTPUT OR NOT DEFINED COMPARE OR NOT DEFINED COMMAND) + message(FATAL_ERROR "Run and compare arguments missing") +endif() + +# Ensure directory exists for output files +get_filename_component(OUTPUT_DIR "${OUTPUT}" DIRECTORY) +file(MAKE_DIRECTORY "${OUTPUT_DIR}") + +if(INPUT) + # Run command with stdin input and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DINPUT=${INPUT} + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +else() + # Run command and redirect stdout to output + execute_process(COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${COMMAND}" + -DOUTPUT=${OUTPUT} + "-DSUCCESS_EXIT=${SUCCESS_EXIT}" + -P ${CMAKE_CURRENT_LIST_DIR}/run-and-redirect.cmake + RESULT_VARIABLE CMD_RESULT) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run before compare failed: ${CMD_RESULT}") +endif() + +# Use configure_file to normalize line-endings +if(IGNORE_LINE_ENDINGS) + # Rewrite files with normalized line endings to temporary directory + get_filename_component(COMPARE_NAME ${COMPARE} NAME) + set(COMPARE_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${COMPARE_NAME}.cmp) + configure_file(${COMPARE} ${COMPARE_TEMP} NEWLINE_STYLE LF) + set(COMPARE ${COMPARE_TEMP}) + + get_filename_component(OUTPUT_NAME ${OUTPUT} NAME) + set(OUTPUT_TEMP ${CMAKE_CURRENT_BINARY_DIR}/Testing/Temporary/${OUTPUT_NAME}.cmp) + configure_file(${OUTPUT} ${OUTPUT_TEMP} NEWLINE_STYLE LF) + set(OUTPUT ${OUTPUT_TEMP}) +endif() + +# Compare that output is equal to specified file +execute_process(COMMAND ${CMAKE_COMMAND} + -E compare_files ${COMPARE} ${OUTPUT} + RESULT_VARIABLE CMD_RESULT) + +# Delete temporary files used to normalize line-endings +if(IGNORE_LINE_ENDINGS) + file(REMOVE ${COMPARE} ${OUTPUT}) +endif() + +if(CMD_RESULT) + message(FATAL_ERROR "Run compare failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-redirect.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-redirect.cmake new file mode 100644 index 000000000..6651d1a30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/run-and-redirect.cmake @@ -0,0 +1,54 @@ +# run-and-redirect.cmake -- Runs a command and validates exit code + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# Normally ctest will always fail with non-zero exit code, but we have tests +# that need to check specific exit codes. + +# Required Variables +# COMMAND - Command to run + +# Optional Variables +# INPUT - Standard input +# OUTPUT - Standard output (default: /dev/null) +# SUCCESS_EXIT - List of successful exit codes (default: 0, ie: 0;1) + +# If no output is specified, discard output +if(NOT DEFINED OUTPUT) + if(WIN32) + set(OUTPUT NUL) + else() + set(OUTPUT /dev/null) + endif() +endif() + +if(INPUT) + # Check to see that input file exists + if(NOT EXISTS ${INPUT}) + message(FATAL_ERROR "Cannot find input: ${INPUT}") + endif() + # Execute with both stdin and stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + INPUT_FILE ${INPUT} + OUTPUT_FILE ${OUTPUT}) +else() + # Execute with only stdout file + execute_process(COMMAND ${COMMAND} + RESULT_VARIABLE CMD_RESULT + OUTPUT_FILE ${OUTPUT}) +endif() + +# Check if exit code is in list of successful exit codes +if(SUCCESS_EXIT) + list(FIND SUCCESS_EXIT ${CMD_RESULT} _INDEX) + if (${_INDEX} GREATER -1) + set(CMD_RESULT 0) + endif() +endif() + +# Check to see if successful +if(CMD_RESULT) + message(FATAL_ERROR "${COMMAND} failed: ${CMD_RESULT}") +endif() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-cves.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-cves.cmake new file mode 100644 index 000000000..4a0860403 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-cves.cmake @@ -0,0 +1,33 @@ +# test-cves.cmake -- Tests targeting common vulnerabilities and exposures + +set(CVES CVE-2002-0059 CVE-2004-0797 CVE-2005-1849 CVE-2005-2096) +foreach(cve ${CVES}) + set(CVE_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ -d) + add_test(NAME ${cve} + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${CVE_COMMAND}" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${cve}/test.gz + "-DSUCCESS_EXIT=0;1" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) +endforeach() + +set(CVE_COMPRESS_LEVELS 6 1 2) +foreach(cve_compress_level ${CVE_COMPRESS_LEVELS}) + add_test(NAME CVE-2018-25032-fixed-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-F;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/fixed.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + + add_test(NAME CVE-2018-25032-default-level-${cve_compress_level} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-m;1;-w;-15;-s;4;-${cve_compress_level}" + "-DDECOMPRESS_ARGS=-c;-k;-d;-m;1;-w;-15;-${cve_compress_level}" + -DGZIP_VERIFY=OFF + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/CVE-2018-25032/default.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-data.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-data.cmake new file mode 100644 index 000000000..07013355a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-data.cmake @@ -0,0 +1,67 @@ +# test-data.cmake - Tests targeting data files in the data directory + +# Test compress and verify test against data file using extra args +macro(test_minigzip name path) + # Construct compression arguments for minigzip + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id minigzip-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + endif() +endmacro() + +# List of arg combinations to use during compression +set(TEST_CONFIGS + -R # Z_RLE + -h # Z_HUFFMAN_ONLY + -T # Direct store + -0 # No compression + -1 # Deflate quick + -4 # Deflate medium (lazy matches) + "-5;-F" # Deflate medium (Z_FIXED) + -6 # Deflate medium + -9 # Deflate slow + "-9;-f" # Deflate slow (Z_FILTERED) +) + +# Enumerate all files in data directory to run tests against +file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/data/*) + +# For all files in the data directory, run tests against them +foreach(test_file_path ${TEST_FILE_PATHS}) + if("${test_file_path}" MATCHES ".gz$" OR "${test_file_path}" MATCHES ".out$" OR + "${test_file_path}" MATCHES "/.git/" OR "${test_file_path}" MATCHES ".md$") + continue() + endif() + foreach(test_config ${TEST_CONFIGS}) + get_filename_component(test_name ${test_file_path} NAME) + if (test_name STREQUAL "") + continue() + endif() + test_minigzip(${test_name} ${test_file_path} ${test_config}) + endforeach() +endforeach() + +# Additional tests to verify with automatic data type detection arg +test_minigzip("detect-text" "data/lcet10.txt" -A) +test_minigzip("detect-binary" "data/paper-100k.pdf" -A) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-issues.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-issues.cmake new file mode 100644 index 000000000..1ffb3abda --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-issues.cmake @@ -0,0 +1,68 @@ +# test-issues.cmake -- Tests targeting specific GitHub issues + +add_test(NAME GH-361 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + "-DCOMPRESS_ARGS=-c;-k;-4" + -DTEST_NAME=GH-361-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-361/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-364 + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=1;5;9;3" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-364-test-bin + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-364/test.bin + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-382 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIDEFLATE_COMMAND}" + "-DCOMPRESS_ARGS=-c;-m;1;-w;-15;-1;-s;4" + "-DDECOMPRESS_ARGS=-c;-d;-m;1;-w;-15" + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-382-defneg3-dat + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-382/defneg3.dat + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-segfault + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;9744;1;91207" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-segfault-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-incomplete-read + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;88933;1;195840;2;45761" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-incomplete-read-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-536-zero-stored-block + COMMAND ${CMAKE_COMMAND} + "-DCOMPRESS_TARGET=${SWITCHLEVELS_COMMAND}" + "-DCOMPRESS_ARGS=6;15248;1;1050;2;25217" + "-DDECOMPRESS_TARGET=${MINIGZIP_COMMAND}" + -DCOMPARE=OFF + -DGZIP_VERIFY=OFF + -DTEST_NAME=GH-536-zero-stored-block-lcet10-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/data/lcet10.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) + +add_test(NAME GH-751 + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${MINIGZIP_COMMAND}" + -DTEST_NAME=GH-751-test-txt + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/GH-751/test.txt + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/compress-and-verify.cmake) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-tools.cmake b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-tools.cmake new file mode 100644 index 000000000..afe4835d8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/cmake/test-tools.cmake @@ -0,0 +1,61 @@ +# test-tools.cmake -- Tests targeting tool coverage + +# Test --help and invalid parameters for our tools +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--help") +add_test(NAME minigzip-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIGZIP_COMMAND} "--invalid") +add_test(NAME minigzip-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--help") +add_test(NAME minideflate-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${MINIDEFLATE_COMMAND} "--invalid") +add_test(NAME minideflate-invalid + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -DSUCCESS_EXIT=64 + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +set(TEST_COMMAND ${SWITCHLEVELS_COMMAND} "--help") +add_test(NAME switchlevels-help + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${TEST_COMMAND}" + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-redirect.cmake) + +# Test generated crc32 tables match tables in source directory +add_test(NAME makecrct + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKECRCT_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/crc32_braid_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/crc32_braid_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated inflate tables match tables in source directory +add_test(NAME makefixed + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKEFIXED_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/inffixed_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/inffixed_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) + +# Test generated tree tables match tables in source directory +add_test(NAME maketrees + COMMAND ${CMAKE_COMMAND} + "-DCOMMAND=${MAKETREES_COMMAND}" + -DOUTPUT=${PROJECT_BINARY_DIR}/Testing/Temporary/trees_tbl._h + -DCOMPARE=${PROJECT_SOURCE_DIR}/trees_tbl.h + -DIGNORE_LINE_ENDINGS=ON + -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/run-and-compare.cmake) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/data/fireworks.jpg b/internal-complibs/zlib-ng-2.1.0-beta1/test/data/fireworks.jpg new file mode 100644 index 0000000000000000000000000000000000000000..078cf1755dc0853e97ad30fc7af4d6af0b67047e GIT binary patch literal 123093 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
    ma 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

    ha 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�rRb`0y|*v1_Y0K2x& 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

    3ZRBxkF?%H#_f~x|{{V*%h1A?S z%$!c+o-HK_qTxPOs>Eq#O#Hu$nu3V{bS|Ptw0Pbnte3Wxa>ks#JfgmBKY{J&Fh)2y zUp$RR;m%(~*Tng+;ukv3;s+G5%wl}QHhv>nHhR=ly{BK$ql(X^KfI6FL$JvG)3P_HCYfsyve|aFY_x6q6=k=}sf$q^@ddNu4rE zKyszZPw!HJ&3Xz4H3;eD)~rhMD*gB6^*QnBUPbP1ay!D$g{gihQ&p95N_t!m8ks;Q zNJP0hMAXQXl&2G;D0I|l2tSLGhf<~MnuMux&Yzvu>!+v7$A$5x{M%Q%jF&p=7t@p2 z`W-$Td2stY(czaaT;E2!K98gIK9>9tz90Cv1uL^2F`Dqn-?nLR49%3W3VG>7`4p>_ zMv0P)wSrQ#&X+lAN|WhYG^r&)QRB~1mo~d3IBG5ue;yfqRWH=<;lm7CY*{$2N^t)G zw~2p;^`quL68r(?yvfD9X9uFg<>8YsnP0YX>{}A5O(qkUs3x+cnwg3KA!-T=33V-6 z(1f6=#CrZ0;|=2CyGvxNcGq7{pPwVm@jnV)*N2p)zmi|6=*}!k$+;$|;Q28i&nq?&ni*U#|sP17%sQvF8dgMdDZOtl%RdHvPWEAwZGsGgq!;M4ohte@nMUCb&` zB}6$cNsmP&wmjD-Cv3@BYup&+US}HuZTc~dQ6>dixsR-3iomFW^M!epfSIU=v}%ls zN#=gBBt-UoqDXG`Ahsm8(jWroltKzO?b5@^5opzgiIUH}Q+Wsi@K0n0#do|*7 zYVk_>n2lWXsdK7jqH^XQrAh?HsfWUJxMRVJ94pDS_%o@O#&vmJ zO)5}8JraPQu#Vg@sIC-rGGuez{)b2?l6muvLxPAb*b%fgAQXCcg#$Cq+B5*{E;opT zDDuC~0x}eC8r-2wfkCWo2s1qSzyEf<-2h&oJ20GI0nWSIn#*7m$= zjV2`W>kxobz?d>t(O+UMPx6A;FfRT5;xaBmU!OQpq{tmtCE_F<;zMSbhT0H(z^S)j zec&QzF!~UOAMXa^>Ip7(XhE`eRiCUKOxZiy@QspeH;6T))aDB+lH# z0LxH^)U1hfv;>#}=?CWvVj{--z=Ukj`2e`pv9uxtx}!E_?Z|an{GqZ;wO@M}nW9PU zXb6GQA|pY4M%>^d3NP$WNQgmXg4c}^5>2BG5S1~${NW?Ya$aNq08C`e)VW7Y{9cY$ z6b~^ibJ03s9^ybr?6nB$XNMkGE{WgM`<=`(;l(+3Rr7z?@qnf`7LMabOwm&jVSZ)~ z8yhz!p;D%$X(cL2bdk6*nZ-3j7f#P;c%Q9Kc*SroA=9WW8Rmpd#2WraDIuiR%U5-% zBA|chtC!8=$neDR@#$amJ-_LDug!c9XT(~`7;5AFYk&Hd&+>m0@p1jl^G^{NIra5&Q6y@!)J{kA@d!vg>ui%HVoK&OR z^z8i3{{TGD$*aR8)UKj#J%Y_1T_!3J)s%#PSr@a{w&PV9E^GB(Un9kH?nIlBaru;gi=o7% zFqtBYp{``}k~mn(Y*{^We24)uy>M z`~K(Qi*mV+=b_RTepdE})DG@m9j^>r`IF?!LKYI4Wlu6;>J!ioWrxlZAs&fkOgfouoGW+j}bW?WK(1E{OQr{Q@t)yxC&_`@N3P?Etx zGD4D8RFun^I!RHyc>4Y-QRmJHBQsj~kaT%6LG~(g- z3c|Um9NzE?;?9eQoJYZxoVc%-G1@w6xm7ae)L_`3?HW~~*>b9dFjk@IAj~TOq%aqM zneiNg&?sB02eHf3r9bKW75x$iCmiZm2Jtco=&UibbMLrqMC5(IiyWtetf;C)eQ-J*StMULI~kE_!7jwyZlaQf}|pD~+9K2VLb$gpnFqb5a^{USs`KpQ(kLVZHtc!>izzsd!<2rsk5$r88zuvc<2ZSsVOc8QWS zrD+`CHDnax`!r;TI#}+|lQxvw2rB(=ar-sPi;M=FbFSu)Zkl0w$qEqLQ^ zeU4=vw?B7>+4Xrh5vi3i3OHUZOEV9|WT3g5A#8R#lr1Qjk^ca6wCv9vEnbJ)Ly9ln zi%oj3)mnZ`?&!7422L3-c1oY4{W+ua^TtiYat2|WhGKF&ij*Q;F-e4oV@UB^~2ie=2iCgJlClPwjA zNm8YTU>4UXiis*|o=o6>B8Qm7+?Y4X_X!Vz(M?sm%b*rxsCk<&QXS6X=K=~B1FhjS!Gryvq7tHitX#;AhVeGUiDA4TRzA?O1`X6k z45D$gBDWCQz2ZYcs97^R9mV4ytUw=UB!n?e@S-Q?PX7RC1YB(r0Z!yRNURG# zOTZ*9c|wSfOSDu%3x?VPJGz8Uq{1o6(xl0&Ql_Av;|V1WI|39wMmXarypFk}no3c| zuao??J5X5OIjG?xS-HkYR9Nj6#Ce8IuNjkvnATca{{Vd{Lm9(@zlv<65k6SxRVCHj z$Vj;&Jl#xvo_J?mzU%aSpTYhor>2*+!#zFk_m`?$uZsK+5SKBPZM(;y*2kWi`#F0w z)MeSrnIULWCZx-sB4E`jp$BxVb02V6f(QmWS+vm0w7w6MUWaoQrdanwiKd>STBpzj zCR(pDoo7;|`yb*@eaAkf#@c)``Ic1{xS`9j`134v0jIO=9jd-(Nw$VjOv$O%Nmcp8Ea+r@QV+AEckxs@G@1RLjqaxg{Vk;Dar|Nk|MKks!P%1(s(yGF7*8mcI^s^Omw#7i%$`-m1B|TOr_+RW?N(U*YO1swYiMv`Lh< z{PQL)wk(9LU&9^-w&bnt#rPi1g?r7%`gxyMJ}N#PY5a8XtA#v3%2;j^a}u)79bI3B zlO}d4_*uY|%~3wJY0}D39Ki*gM~$qUakVI|oK?PV)vITxq{rWC$D$*jg636c3)l`jZQqIY8MaynumqQri)W#400ON|kSzM*@ z-4>iik;(;t$WTt;-HtWEONQ>_QmraO+`%09OXa*B1#`K*hAPB+N> z?K;k)?b{LcfIvB{a_wdb`j#kX&h-^lIwYl`-#{FHO%|Ud7qic^Tc)|SNlK~_OILd>~CAGdUsHV$NT=-#k}w1 z7K4e(@~7i`M!_U0KAL<}5S5#7`DdV$R+K3z@2O-CN{?P146*MRMo-G%{%fhzpNxA= zoTVR>m&x)yJ)3DxB|TGQRApRTEB^pH4w3j3eB^1AK^>6Y36EC`P}*Ee*LCyX@jSf0 z%y%9a>9hQg!o=s%8hKKYhSX8i%SiJSsrr*J_0m!s>SMWyP5azQuTSoErr}9&wEcf0 z^DIwD=cBH{TXcn@+-y3ZXiyokS4W7500A8$qBK$(A_80I5fM(25U>Hx(E)1Pv_x8* zU9S-xS}6jip%Tp5azQLsvO-hb{{U#iq-s0tcePTm`cFb8&aPOtq$kRi^3*jE?h<=P z6XSdGIhO+2?soqGjnv6P6Dd6qE`Db4#cjJX+USnH8Bh4i#7bl9PzLeEno23Nmke%5 z`=Q_~{vQq>aTCKnU&k{o6-FnBAUBMqaN8SCK@tJEd z{{T1dE@#O2&xS`&m-%kd#%y02sm28`sh=`=q>>~`D^rxqPvuBG1CTlkN7CWN3~jh7 zz5XYUn>6Q2PU~-h*%Iu+I~>u$WVJ4Z z2@LRAAZPyoc+pUiV(}WFYY-wbTd?}Vh{}it21Y^LZ_*PaKx;xoo?h@!leYW9jL|qJ zbJ8Lv>C0$RHOPwq&{2aVf$#K!%~+&FinkZ^w=)R`Xeexmg@uE#zv~C6Sp)Tn3SwdE zAkI3(Oo@q>!=;2(u>&~%a8WV*yL0CV7Ru!jmP$|B7AOj}T*hpyw~Zr6)3Ff~M%*y5 zVcseZW_iGh!N7%&m;x?&z!%tnF9m@gQo2OMk_R|ZSg5p5nGtQwRn&~Vo&BM*vtH1e zAz*FvjFEGJA}04dp}wJH-tbtKpHK9J#fVLtlvHQ{g0~UUdc@NP06Ka_&@6~zF7a+$ zL`O(`#>58pipe_*g7609#9Y865>Lt$NPXgD!)^J%We|7X!|xHRAQ<(C1a|i62$Dyr zKRA*rG^Bd1aSKJv6j=L4NKYdX7$Z@BkddamX^8^^BdI#2brPhZYf(gmXh7tVsHlPS zB>dwFDK^(rPEDkrL#C5*?nG+Lh_D6i0T#Fa03ISb_-%aLD-e-YC0Zv_EKEV}3y980 zDW@0I+$Q5CBy}-QEj8*~hVmx*<$=j3_$H*u(sndKZgXB?2Ww_g*rj})=K71zp-yM6^QkNiaOY2iw3A~9i&R`9zCGpi-l z=%$rRDs@!3;L8ElvWaRARKRj2ihgfAqdf4_!<$iDyUE|nsqJav;iZ;YZ(L94tMWV# z8Lsj5*(Vo3>L99)R=HQLEysAE?r%eTjw=;*YO$ev7(-Ceov>3vUL(&TA57mC%` zRYZ^56&Q74r>B*1B6`s=il#9NDPVmdhkK9%9+dTS&!&vAz82T+zf-jhJTU5Ijr-g$ zZ|;4r@k!$QANY2BJG?q&YWm+VH|L7kS+@|TLQ_pI3&W)+O(i^;NC6V%-%v_G8jwxO zi9R#a)}A_K-@WfTZ>G!VyMHs-Q;W|$(&W9>>&{;-k-#n5rn0MF zzsIq}4m4(3A&%A5Wt>uP>^xkF--PoNgDj8~WlfYxO0=oKRlq?2GYPd>Ul0!$)#Zsf^=Ixyoo8M@wsf5n0HDttA%Xhza~tAcM^e0evxB?il*$cPl?@Eq0lec zglxkCZQc+9=I8Z-h*B6a=e#63Uuzz31(BeFSdaIFj1=luPO%k{9Jxe5o5Dl%zsdq6 z+&;nr=2F8qc)_%Fk{wL@MtKb%p@Yows*t{EQ@nL`DY!a2T6e=GNA;cX1LHj}9)2A8 zDrCZmwU`{EhE6-H(X;%FerKb>1*yr3Npt!iOX7KE;|#HU(ZTQdxx6{~`CBIE+G=n= z2{m|iLc(@RgQfms?;e+hWLkZD#*#{Zk-?Ha+egRE#P|zTJh_BCet`)eF*Brha9%l= zBQ?2|B$K>XWXo&q^Nph+`PAReDhmbyP0M(QiPl3ib$CdaJVF2%fQWarOl%Wz(hh)3 z<|IHsDt=z^q5{O)0y3dt8V*83hrB?+ouVd52K^!s*zN>dkl$6}=1CDrDZlF%Fldw3 zB!vR313mdf*)~SwalY^-X35w_hmr=2ktft`{?Q=x7qn@y4L}$yn1JAajSvmU{_vrR zk#hoNV)ll~5cLQx7ctyBlF*`EfQJ@utN@5#a$rnsm@((`jUllX9a4AEMuIhb<17+8zu9w4ps_7_K->#Q7q)_YH@V5|^8he$eX8>EWFE8fp~9WMqg3v@qr!UGDJE@C`hc`;u0xw)+#Cu z&Ef(g0!5|bDj*zkh>@XSAAe}lUBwQsRp4w(RqWS*h+K4th=(x+0N-!4Btf-BLN+EU zBC&{wonPnP7DNGY+A>5-kA2~`LKH=>*g!{8Svo`PU}SX|gUa0F3u8}m3Do0Ah_+_5 zYftNFQx=Yt#AsJ&Z@HF9I)iC=Zi>1dS0@agQ!5V3)Uv|rs%Iu-{zuJKl7f0AKXPNB z^2N87Ph@r@ALv}p^l=Lj$XUvceptn8@Tu4j?&&LNsuv<|uw7FEl0gox`vDlsrNy5c zSyGaH&c;1XOgR(7E*844sq8*6_^{6&EGsh9%=L<^FxTbUWzo}BO{I}4a^U*5!QD zz}y!l@V^{f`PFjg)@F=VXqZ<@YbzJ%lPyi9LR~r~5^DVJFUIyVTuKw~#e|~SC z$7{yi<%5bpc2aNUx8r9Gvdr2(E78#9ywb1P_=L?eaC~upnIM)-na}y962L5gU73E)(g`{4kgR!g#mEeA=|P`d5eetx#Y6sxpE>`V;k!2VXbsxVos#{{Z6G z=6jwU7wpt}N>E?!dq-as zcy##jDpyOHtkM4f)k`W*tE0)jK0YqL{3yIMT;)&yR)4vj;ui;TDN=1TP+z97}G`Spe$tTR| z8A4h;N*a#H1^)5MrO_NtFPl06PG6^J-I-{ge!bxUHa)~e)QALg{*e(2L`AejEz0o` z*QKUaLcjp1orGn&B#uJ(Z}?~NSH(XMGfrg5`D&uO2Fe(8>`xM`n6%21B21(etm;t! zsexpNQP=`w$j##LhEHWpzb=cbeut%t!*Wg>e3RLEzQ-T&Y&lqUM9B*ZPnJqgQbz9{ zraX#D(b36`#k9`Mu?3@);{aTqZxILO06YkhD7B(wXcuNXcZ{?s>V-H4?-^*?I`q>5 zRvd>Hyl~H!$21xD&;Alm6_j*28#`nSLa_*)OEDOoB(<*UN%XCU&ExZL7Mjv{gUcnf zm&0S~@ZoyB8pj{JpU~xh{6)*bIE(P%&IYDrfjbNGs;QJneR|k8ymhea;h$TL$C`d; zCLJ8`Y2@e0?0+k`gL&)d?H{P)-5(#8DLszdkJqeoql%1>Rk8U(O*1Y?jV5t{b#w>b z5+W{lF%dKGc8I7LwZ8C>4TJy8&JYk>Zej8ZL~c&) z6^RuzR#aBg*XI{PpgZ$|$h!xCgK^Ffq1Dn9$r8G}Oc`8_?GU2W6d>kih}-mwp`?K~ zg&;I;Ifz)aW%i5(02k*96o*TV_k_6t-UdVbJlsNo6~h<@kvoUDganr4dqHH0-0oT% zv3-EqjsF0oL&#IUj%Rvpgs8aU68xhF;4Gn3*ZXt7XX6zsMaxUOXSP zTKVZTGs};fN44M@2x|3_#Xd*h+>`LG;Fe3sbodosN5ZiwqL;|1shW~kHBIVJ=wE35 zcz!vpoR(i~?eEO}-W~;_Se`Bf_UA{&Z;NMvx-SHNAwOl{)qjh?v8f-AqXhct&`BOz zhiWIYmdBWAP?p>MBLa!T2y9EAQ43(mS;2{uCj|6@&>(hzgd032g+u2S!~n26+wB4Y z0f+f$LtJZxciTlFe}dF(e-19f+bNC4?jlHo3G30!60p144)%%?Oo)9pcy- z6LGXp%#fsiog*YnklCl>Hh#|84(7EjfQ_VqcDuu6M$DaP7P-5;V~cZ68*F#E zW{y=ZBx@>ACR0%-%`(saV!wqyH8;o@U@x>N;PY_-3o zNd;DOta?a&DoH$3jmjt^Ja&}Ns=o&g8Q|P1@SEbNGG%;fRy&5TCCs9wsq&39#2M-! zA!t&GNoKo|-+1veP4HxM=?1^0E1@={6%r5s$`i} z`EM=%0HrVm38^YpD~qjC0Z9k*B9dKV`uapVmBizPE|v4!@VD?WjxI8mX?py({{ZE} zz9#^&{APYNh$>{oE^O7Uh1}e`eN26Bj|4Ge*=&!N)Mb`QT%EDRaA}kjY5ky0GQyoQ zP3I}VxlizqNc_#%803aUDSNy5^fNq8D&?{G^Jo763K9~Buy-fkJ1RX{*K+8NlDFza zYLHkkD|Uv0!{xjnEaisLQ5hQ-iinaJ-<(7|?GYMELXFxMi1#0YFAVs{i(e6WYa(DW zQ98dIsuI+-t3;}4N%c&fF-FLigas)|I|P{VJZDny;kC`|yx;HT%=P>$NV8@4xh>zP z@AN*6d`mtk8Bc&d9%T4w-~~*C3zU{!@$sK-hH^e z+qU<)KmM!wSH|P>K_Wkv22-IyQZHS{{Ww%exHeufiVN7sR|ubE@P&rs>c2F zrn{}5$?f$!KF>{)?#adWd#{?`=y;}O$he+WPO6zQrqh27RV?IG(@gG}vdKaEzs@@t zbr8s{Z2LP;W}KagD-Fb?B~sK_DHBj^P@s1PJf9NqeLk`rIhQU+cSo+f?9n@-J?6N(MAx=@& z?*8%g=_SbUoSWujpFXjqWD+g7`NKrnmwtQ0UCaRhpY0PR*o!^Bu~{@qZQth_Xn`rz zOWF5`0Q$N_K-REmh!n@8#6(7=JH$joavxYx8E4uWAt0Vc7rCE61)4IMpd;4{2F1bo zM2ndy2Z^Bq@6rM#bn6k8M#FIb0Hi2ri0cCi778D4c!Uxhn2>ph+vgf3xTH5oih-Zr zD-vj$5d5Yx1V`E$DlIPkprB}2x9b|AMoLU&rVS0!1MVRbVW{RYm#Q7qF_h_AdaW6So}jj*l!Vz zRR~7y^XXo{+v0x3gYCwP+41Gs(emfwpW}j;#}^;}0B+%w3ZTMp>SWN;C1+CBgrCfP zWOY_&B~nB0jQ@pEAdt#7Pk7`54gw56hfpjMm}> zg~5dgH*j7iBl$!CN%x3}-1HHuB0E7ys13Wk1YEX>7g0{%<>C?~b%nA5T{}i^VjygL zUL->7Z5psA`oM_-kEh?1EQA;7Xcw7sFRlL2kUOd~WIoXe6&;$xrqHr0eW5bhChy7v zM9dl_MxFaYKrUb*c31R_k){0%By`kSuI&|rAFZQZ2!ON*D85lx**)zQQ7}t4 zTa-d5ECdusQ6z`9&@!`Pz&F+~XxdY7{JX^0LE<}#Wt1zn#yF;O!0+nPs)W+v)XCRA zs$fwAbrWPK{OcSMi@r8;VJwqS52YnP${(mERRh`zPqH zy>mPI%~Y}Cc(5vy<-=?HzmCtPoX7DE;^!%NbIGB9i^HmFCE@DCWKc_(om1&$sUdn2 zKlJNn3*T*(zDE`F)^y96I;C`Z4qaN1CFz@u*UJLBdyiL^kV<4H zf6MD@Y9Zh1w77F+x2dGMCHek`&T6vZ#Y;@>^>6Y$cQSdLrIjeHO1UR;ddH&(QRYru zTb%$|{o|P95Lmg0jF3UNsLM~KE?kf~`L?bM>Ck0Fo1hMPQ~Mm!qrV#$q6{`7e*>;g<8s{$d;Lg zG}Z_aka8#DW}a9Jt3-pEmF>lvept$v+o4tqgGIhm)$yKDq5L9f;SsO zR#t4^Z=K^bH?V3Xdq&bS**m0tqD!bYWD~1k{_(2pTtw}=U#BP#^F~N`(SSCyUNYBm z6LL0%CQJ|JJvu^(f^882xwCB%01P{bh+6K}h=Xr#j|~t%Kcr}YkPg?3vJxyl@up<~ z^tIkI>Le29=M57glVP+}(Iidw+8ZDNm40v&WCM}*fX^@?_WuBQg_B#XMSa9vF)-G` zEq%WG!$HiGzi5i+2mtgk6%e#SM7W47nfi8swk;%*+@hi<541vGkv{Qq0wM0kA+%e= z%&iWa*g->NPow7w1;~hD$`a;hpR`~Qq&l`}keeuRyGEZOG=#DD=@}zsWCjt&mggho zv67;uxc7~t4VY#x8%zk>{ox=X{o-I+b}$H$YrG&E7>JZQMo0+Xa$;zU>k=W-Kf@X; zB9QigED>U0M41Bb6^a+NzuqPwcf3?W-ON=$fcj7A6WEC%#`X{qJM$2sA$xR*1&*dy zv{n`ab^;+TZxs-d%;FIc965l?%Tv9n;qh^8TSl!@61&8}>5gJPLmtsr=b%OO9 z*nW|QCsiSj$|vS&9mN_1$%%U*H&N}*IHZn5dpp9$P^ipV@_s&r;Bt-yrfoRH>LtpM zs)e00hLsnXQ*~%aQ95>L^SnxY7#vfp{5qYz4k=GB8eG2<>8FLyhGq$d=G-F|;}$=L zVRI`$sZLVMG!u?5PzrUV)FnwwxWYAdI&6y%v2Dy_I z6DU|E4#4%}Hu5B+-qrM6?e_1>(Co_#c-~8|I_u=S{Oh^u?-XAe&Kz;q{Y`^q+)oz6 zztiamDW4=w!f`Aq3Ja*HGSWoZMRL=jFRTKgaj9ZE`tNC-#!*g}^z{DTOMdUM)6nqX zylt*0zZW*Vzq!EA9X}H+Z$IOC6BtEpB`mCSht;%`{{RTUN~)VCvS60vY7A;AmNsy* z@zv32=aFQ%?wVEQeED`exwVTQ4NGTl>0goQ9|2z!?Ee7ay5iWgBIhOI-x)VDj+jB^WGfD{hS^ zw@dE6zK5feTOK|%+FjG${JS&Nei*zR@h8RJC5}?$>_}JSygFhl@oalAtr&I}gUh({ zYUa)+T$zL)%7v(`zMXr=p^`ZE$?Vi+9;wn_9k%j+BdZMAN;RApRa2I5An!AT;jwOCr@VAHCSl7De7Vb?lZ4fRY)LXYq;zl~qW$-@2T zIQevw=g;Psq3U6iSz$RXqY1kB#c$Db=>Gsi<3Gd~jM%Ri_{Bvp6|bFLGcI6weiRCs zDU~%c6EdYKNMxlVs%-WE000065$ye!(?%M1kt%bPpTg;V5y@;d zqmR>wX4OGNfln%F9G5#nr?3A2T=kxD~FCV5E9|T`$R$&VcV1K14NrTiC(0;If0{g8oh^Dk(MdjV&)b} zg1su+ZgDUdwcMTJMv;{%_WD9(kLGxWjDiSwiIe)eK#&pJVqOvtv_t{M(GhRR!a=AG zP~8wab9ihl2L9247vFE|8uAbX^?&CU;2}(5>Q;#QQh7X9USLI@Gens?q+TO7FQ}8( zaSq(Thy#>HfB^ej^@u2m)L>&`8Tt-!p&@=&A83*@Km(n*Kr~GM0Os(KJ*{{wsJ7fU z$}Pr-kC=$dBy7y^p{~N96x`xu&~EL#1w;*rXwbey4(({HIf*s~<_jba*5wmo$Sb$n z0Al)JBB6lpt@R5}gPj1|yvLZ-`1?|oeB`7o& zWq=y56_VW(x!wXo7$0~+1@_%?45jTLW4CBq)pRyhUYuL1e?F_JtJ=r#)b7 zg(bO`i7>JXbNWMOfO?BRc&@;8-Qu#dX;s<=CW?Mu@FvK@lYacVMuLFu!X9E}nApYu zZtt^0dy``BJ)!1E(nb0}%^+A~XaYzB?(qS%DfE_sq$hPMa#JXzp(-b0Tqjs@-mNr&Y|8MiAv9aOl8@%1OI5CrI~xQt=gy_+rTzb_0~@u-qFlO;7C#{CyHN z;<8sYBSfh)RN|jRy*{Z)Ou|%MZD{dz8W?KwJlP$^Y?n`0-*eW|Yv-oN?6IVq-M+qu zxI7woqr~ZP3^xP7aJ<2e=DfpSE=1odrAu9PWa++{g(Q{DSp`Y;C?(lM7Gu!y9V{V^ z*3@_OncU=@z3b=bauddHhze|M;yx5uLLJ7PT2TjMTQAHj-&2Mv6j% zlI>A68HLg%k@FaHLlo3uzWe#V(R`cqN7LuQ?O@v5Z*_L{^L=`yw${!8=i2I=y^yKu z0@Y27Ql@SXSfrNxZ8XAWN}JsO0M(SCunCpa$J*&~;?y->r^aeM4%cS}uQPlrqDb=p00+D-$M}cF+_^sm zc~v-de2V1F30%hV=A~B%1-~!xFz*htQw(XvE0-YBY53%&CrJCb;EUip!F+?@n=|HK zD%MeA)3Ifv7Li+x`ILBe9;rH=YZ7KAVx*F=7j&HQ%eTh2eUC#V z);#MD2=QL;zm;Cg_h-vbh!s~Cu&yOd%XqFghgIUO+6uWuJMe&groHToYLykO=(^{!;YZK-{G7GfA4KVVHa$%_4o|-*`dHcX z@;Yiqa$Yw^OdXE!gEIEN+9E_;IO`E~AXtBRQ6T)rAtE&%zc>J_4(1}VeIs~+&(O-a z?A*1PXfYWoDW5?(6%v)rD@vUwY4L1rS)8el}c1P=W-iI5g1@ezE)LTYC`dqL_lXAFiACTF1l=~YR#ZS*D>Y-t!(^BNZg3N5LFssGIToMR z4icj*0sUeVTfXryW=*y*ZWd`hdBTlZ0N3RjM2gyXF$DsB%RmH9uXA{dkv5ZfD|15o z0S$u!+I`@n5pSGA$?eF(ks<~AMd~KGLT11VZuf|RTl9hVD<%h%L{=a_Q4nrA8{R4u zfhX+{jo)XAhz8vooFYj&M)!dkpa8%0iZVBVj@k90c?s1=W`b@->C;1Gr$RxHQ_WMkYd~fLLe?oXVe)r%Y5OXNQY=pkuBZ= z4J=?X(17e>q96(1XpIvAd&5CSfo@yC(4ABQL+&FTNXpY^+njPO$mu&PXqX7v+r>ge z-M>hhA_0d;ks1K=jImtKvMEgIZa!V(gWA)hvaq>Fi0GF>i02&VR07zJO%Wfpld8Ra5$aNzZ|IAxL?5tEJeT>c%sPTrF)JX7|Q zj}>xHmHGExN3nPTB=}2Ax>8HmO==f67yUM2TS|M6k7Jl$50*Db@fM zk3T**=(N7iOsTz>tLpl{Hg=YI>op$NQtr9**>qiz;W@iC&(7Jy5XI+>GcgK<&nS1$ z2_z(T0f)*vIB`69qmA@B*)plk%_=?fmUFT2S;IPsczWfdiuulj%BiUZ=Vc5sYHukA zX?3+S$=0Fjl_7dvE1IyM24DK@w!h&=*Qi|TObS6Ii0cx#+iTuCbEa`=CV`#Cty>7C~m6(=@Jl_rq9q@cOj65zksMm#qb zOj2$~KZ)eWnMFkP+`8H<0~(()s+l;H)U1ywN-34|A&K@MSo#hb&Kxk?%=yW<##b%Q zTl_YsW}gt8dCORI`jtt*e`-_EVcB;IY6)2FYSuiuW|RREfO(VWsmdiJ-&)WQk*$vm zmN>2{OX=qS059x%+7_MVz8IsQ{CxQ6Wvpik<5v#qX=Ua-lY!#6USFf1B_c|(Oe{;C zONmrSN^L3Cu56T~G6JO~nJpe}x7s%x3wXC~gmdj2)n zzUKybE8#yo*YV#gQsw$u{N0f8dh<$&_;KEK8JWX&jd zWQDp?OO{K#bn?khPZdx8B|lys-M8v`xVWRJlfGEfRojjK0F(LG&&pj^KUTHsQszuj zlvG@m66O2c$JgkhqXiU?lh#gB$tg+R=ZnoqO3RDKr5ClHe38&u?;NHKvFz~?mM3=h zgaO#Z4G<15v`Gka-M&$I2@z;QiGXJi6F^IQKomC@J47Jv2pdF1EMY=v^>X)x5N!Od z0T!Yl1_scFsjV#bg&H#7I2jT2!bDDjXD(V`U{{Y5~5MQ0(A_bx&I*XgaL`Wn;*HR}RH~}CEWfRY&D4H&Jii(Vq@irrI zV9=lqU59vy30L%sZbSiAh>Lr*-~>S~Zq|fEmK>oFv$Jn_&6#Y2H(0hs$by)3gp(p( z!{?HK;(K07w-V!ag->eowOP1OYBKBtbLDVS9j;k}qSkalT>A)uN`^gw`XS_ zcNIo;>QlG(j&!y<@^v&$zr zz27sdO*|!O*@elB$zE|VnJ@)RP$WwP{$e+@cj2h0HkGt>C#SrLJ(E6`{5>-6S@3)C+~Svr>}G1lW2}=? zkT`CI4GX8Ns*+P(R)qfm-kCEGuaHx2&EiWlgL0bp1sl1r6`f+AxHBhkVA_&BXJ&-CyOd@$1CC6 z(fOWpj$BgWoLW-leNps>;Sb~6Hh3@L4q>R_)(?l`6ER#<530;H1Ql1|@}$m7$x?aJ zOhH)IERw%b1SUKUR;yWuP?Dt|#V&u`_B8k~X2Vlk{%`lO^<(1g!zzsV@Ui?h3?||z z$Fmg7UWm+@sY{bT%$+P16TX!tJMSDCm+UmK%D23YuQb-*L$#)FHhhq+E~zh50aykTG_E7z2LM2T=vnc+zHw*->mn z&jAxS+WW-FQp7+&;U{Q_iFAtyh`VnQ2wQG9+99$kzR>^@bnSRZfh6q#0W3PaBt*uU z3tr#t86YM3LuiWN7>KmAR7CbRh=G{7&?ltc*x8^AUS*ccg-1)@xvB^Tv* zMF|{@?GTeXqM))b2?Dox&zYBEcO1!ufjzm!VwsRZcjo|;Ta~`?Qz14lyTU|WtrHSw z(|h%A4EbcV$OLpMViKtS)fgi6;C z5i8UgnWAKoX|=81FF^#UhqOqEn`=A_g{}>RBoBXRfJ>W?)*%CXn42N`7J`6)-u8>s zi&L9z3t|8ljPqn`PLXIx&+##dGO^fgv?Mxpx9ipb0yaCskq+kO;xYtwg_?09MLv7abh7KK4jY7{M5WIu^9?05 zv2v8S)U6=0Z0aC5caJ|b<%0v3IPpuO?%(f!BfqA^vu07rDvwv$bvhaQF;V7x(^pr9 z&?gGQ)U6a$VS3Fpl-UVVzlm*iDTbvL77o#^9x39)qmo=w>ifUbw~%XdLndb|N}~94b?JQn0DTfYUlf)-G}e+^)j52&UoGEe z+53JLxPQYMoVzbGOU-qv%F<>_m5Jc^<`+$j(_o62rUGn|uQ4)|qC#iOD0cxxDX zUJQ+J6Z2T@;hDWkxMRh zYO>;Ls_?0j$CC|Pe^6q!=^o*nXK5WbylAr!wlqAYpbfrv@t+d?pX6^g^(nzJP7Pc_XlgN9%881y zT4tJQGNvU6a0yX28A}HrPpKWGDbR#PEbj!=6u}o8Uc- zL2yRz%07k;)uY3bY12ANI=*qUCP`~TMatHN5C$Y#+eAc5J-(3v9{jq+%s|-g81{%6 zZeOej6Cz)$#*GuQpz0k+3trF(Y^ZvLink%f;b=>jIGRKOPuc?&xmwq8383e+6htl3 z&=nJ(Xh=zbMZF;P5YZWTS7^x=pH2Qy(Gxc)fRrJjA9&FMgP&;406(aM0wPIxP*{@9 zv_oaEBViH*$PSihyNS4GW{5}RYh!`E>5$0B(?U1B1WCPqe1|(gFwQ?OC%5F8KDhYdzehJ+(bx){o*u!#Rf{Q#PIc0 z$(5}M1ou!K1a+sZ#|dyr?sl>0^3E=CTOW|LX)Jf<4=C&%Qz^7WX}}%fB1q}H436fK zZ;}+J^%10Yc*L)vs4c-NW4lKkcRNd!BVuV#0>T{C&GD;1naQ$@mDV^7gb=xC1NsWRf=SVO)^rjrGx`wtst}6 z9sW;o<~TC=&EGJ}cPzP`T|%+fH)_?1k`iIeLo=S)db)Kp50 zw5apx8Pnr>d=Z3U$u2{!lymB3l370Ue9`Z}3O*h2c|2CZ*Te23@aHjO6{ORgJrk;v z_^C=Cyp=jtO)?U>WiO}~OI({gdEO-0WyHQ^}oU!uXr)e@ed(zX16Y zf;=Y6*yb}!h04V0Wk{HuGY+UTFv(M<5M_x>-gwsG3m}36y1)xPKM&IBvP1a2RINIt z^j>b?!_{tfyh~S}86KNU8fxxccHQ|ZT>AH?vB`ccV|AIEBj#K;DB=k@iw2gGWy??+ zm8VgX_hM1f;FQO;;yERs225I6d+_boynbI=JZ}!g969mj)x+GK^Z6-!&y>C{JZfPT znRZ4KpYd!?U1e&ONl8s6uuEE%tIL?Gi8BznD$s1Cl(}%AN>v{YlycX#_n&9`?c3&k zeA>X=VEAkB_#Y-dARJ)fc5a)9<&2$z%D_=eT`>bOQq;^{K41venMG0*rG6jMrG7#N zr7=Q44fOsSr;_*U;rXM(*J>4T^?gnfd|Z z^HYOQbMxPue507-GB*T>0>s(vcvymrG(gsU+AYAjmL3PBao!$=hUOq(N3>0q2rcu9$by;J zKwA?%jhZAD4X0>%5(Oo>#L+TI^z(Dl1jvB2X%M#M!HdkSfCqS}TLEM35+YG>>`Y7; z3m<4X6^Yz^o*OGA799PcWke4B;Y7vlv?5N?Fta$gk(`}I>Jp0G5)aym+>@IMYiJc5RtirYPkn6{NO7d zQ_4;ojcRAs|?PXh;dtSdzzh z%QDcU*qd4uXg3`i5;QFUBxHy7iHDH2`CcI*VYEa7;w3^Srtb(7Gi?$iK!1iaTah$s zii@9Ugqq)I%kDr1t^J`yBr)Y^2(DfvfPk=g(3Ol00G**C1{lXpI2D<1CHLI#K{@U*`oHT+Ja~mJJw^ zIpZTq3>weMGq}khJz6yrhDalxv#fzOHCIWOSXh?G7P@X1_TtX>_A<5Oo;VYzz%{6JWlH7HM+Rb3<( zRVsC$B2vbg>jWqiOHfzG_|$Uh^Q{IYQC{?<)%qoT-&fHt_I-zf%NCDMEq+OR&uFCS zzU}s3Uqk7)g3pVG5%_WN{{Z6O5_2A5nV7N4>~2TkRarC4nId})b7d0YCR@rWVWfGV zm5WD5Q-dxQ{5}T#>U;CGz4<>gk{Pk&Yf+jim8x8+s;^HY-Jb>@i(l=mlbUf{)rl^; zvZppvimCMkCSuW5D9Z{{7P62OeV~q}ejhlfb9Ue7=hxICi- zk`9$2K!qhi!AS%bB0k$g7)}aNc8`3w-AvOh>FRaw^$k?(!$Xs6eWkw zAoT)u9hxIRk!TVjNYZ(j&^sgV$|0fw;$jTl9Kl2^#9Ltr5Ch&I^#FZe+9DkcLHjfm zWeu9#xkiluWAf_(4)3$XA*H?I0wbT#XoNX5K*+K8fDo2Y?+BsN@X(M+4X}*RSSdSn ziiDkp_J)XxK>o1<5CMLX6_HB_S^{Q1&<%+MjiMqcVP-K1X#_+ z0TC8!LPXA&v_wHHf22T7eVPgqV)r}3L|pO#;vl=gLPLAP41#qK>|zp#h=NAK4?-pn zv?N3gm_!DcJ-Nk1jIr$ymo1{ABV&EyBG@&r5fCh|@Ihe5jMUacC%rf}Twi*ogth>lF|u)OLc1>PtvhA#LJxMhSBb6^cs%XN)v$Na}*b zxN*ueM>3U>ERWZ;Nf?oUtyi-~&J$p^z;wJ+L|12Tlno7?L=vftF8e$VJxMdWqMtEK zM5KC_wK72JZMV`mWr<%A%^Z^2C%xtI-hL6mY-1s!X&7mrJhD{bb458xJ;7BhpYfx_ z$);~r?V`JUto2@g9X|r=%>3^STyChzSZ-*-#x8K-iO{B^l`P_>rb#J8y-(>rT-oI& z?xdwQa7RL>4R9Pad6O0Y z08L^e@fd~-s)ZUk7@`K5lhZF?rGoA@O7!xMw}bdbJb5P>t<$yIx_o@i_@9Z+SfeO9 zQdIsOJvyG7#ap_m?j}FVOY6i3tJAN2rf5#>#H7q6LOFXd2uohpE|sgh;u$i6Sj8 zvosVy#FmDLn3L8nfF!u(2@&NHD& zHAFXz>gfRy z4bYf~k@7H+ZvCPTrKQ=T+*sdYA|waYeWGB)y9R(!HMZU=Dl|HVgqalmyKNN^F=n&= zu`*&GRib3b2KmCDKt-{Dt8q=ic&yQE zSbbt5-(z7B0W4YKB5(kHLLwC07>v+ArT$S3foHTrYj}+FA{(4SnE>If5P&Zb2us=o zAOpJq!Vt0_nc}e#aDP~t6Y_X~H&vP-vKKdqMBMi25Rn?j;y$-Xah$Xo%|5Ni{Rlgojd#3-gRlYAcDFj9i+EKYuoG z&k@QvOp4l+%JOHH1uF!D+(((C@oXBYIAi9H{>4AC)}R}_Rzi~NyTpim#yp*^-Udf| zfmRv}MqNN>k^9u!nr=Sv#hTn&Mx^{PG7&Gv?nhDxOnUg;gD1-u2F(8J0*rbv4ju(kX zBFMS&eupy3<&EQ$+nV)1E=@}5<|1^Zu2k6y3QE$V6qN$tgUE)Cio_j+Bvu!I8C}5V5EHNh5naTW z8?(eFc>@tqp>*=JKxDJC##$0*Oe93uM96~!5f|}xhRAMh-XbDH@9zLu3#3FeKr=V? zih_t-JV>?>Ue5?!0Wb4_QzmzaNEhi4SnBk<_Jl!SXb8zJe@GiMW`R0MHncmDDfKiK zDUc4Pg$)5=->f!6(`&>OL(-Rh;s6S>n1!Mqp%93)MtXrw;AqiYmg@-+y0 zh>`^zkIEt)UYE2&Any<|3>&;Gfhj*o3WsQf9GHkri*ks7rstRu0FPHY#8iL(+4)gF AYXATM literal 0 HcmV?d00001 diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/data/lcet10.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/data/lcet10.txt new file mode 100644 index 000000000..1dbdfc56e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/data/lcet10.txt @@ -0,0 +1,7519 @@ + + +The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC TEXTS + + + + + WORKSHOP ON ELECTRONIC TEXTS + + PROCEEDINGS + + + + Edited by James Daly + + + + + + + + 9-10 June 1992 + + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + + *** *** *** ****** *** *** *** + + + TABLE OF CONTENTS + + +Acknowledgements + +Introduction + +Proceedings + Welcome + Prosser Gifford and Carl Fleischhauer + + Session I. Content in a New Form: Who Will Use It and What Will They Do? + James Daly (Moderator) + Avra Michelson, Overview + Susan H. Veccia, User Evaluation + Joanne Freeman, Beyond the Scholar + Discussion + + Session II. Show and Tell + Jacqueline Hess (Moderator) + Elli Mylonas, Perseus Project + Discussion + Eric M. Calaluca, Patrologia Latina Database + Carl Fleischhauer and Ricky Erway, American Memory + Discussion + Dorothy Twohig, The Papers of George Washington + Discussion + Maria L. Lebron, The Online Journal of Current Clinical Trials + Discussion + Lynne K. Personius, Cornell mathematics books + Discussion + + Session III. Distribution, Networks, and Networking: + Options for Dissemination + Robert G. Zich (Moderator) + Clifford A. Lynch + Discussion + Howard Besser + Discussion + Ronald L. Larsen + Edwin B. Brownrigg + Discussion + + Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats + William L. Hooton (Moderator) + A) Principal Methods for Image Capture of Text: + direct scanning, use of microform + Anne R. Kenney + Pamela Q.J. Andre + Judith A. Zidar + Donald J. Waters + Discussion + B) Special Problems: bound volumes, conservation, + reproducing printed halftones + George Thoma + Carl Fleischhauer + Discussion + C) Image Standards and Implications for Preservation + Jean Baronas + Patricia Battin + Discussion + D) Text Conversion: OCR vs. rekeying, standards of accuracy + and use of imperfect texts, service bureaus + Michael Lesk + Ricky Erway + Judith A. Zidar + Discussion + + Session V. Approaches to Preparing Electronic Texts + Susan Hockey (Moderator) + Stuart Weibel + Discussion + C.M. Sperberg-McQueen + Discussion + Eric M. Calaluca + Discussion + + Session VI. Copyright Issues + Marybeth Peters + + Session VII. Conclusion + Prosser Gifford (Moderator) + General discussion + +Appendix I: Program + +Appendix II: Abstracts + +Appendix III: Directory of Participants + + + *** *** *** ****** *** *** *** + + + Acknowledgements + +I would like to thank Carl Fleischhauer and Prosser Gifford for the +opportunity to learn about areas of human activity unknown to me a scant +ten months ago, and the David and Lucile Packard Foundation for +supporting that opportunity. The help given by others is acknowledged on +a separate page. + + 19 October 1992 + + + *** *** *** ****** *** *** *** + + + INTRODUCTION + +The Workshop on Electronic Texts (1) drew together representatives of +various projects and interest groups to compare ideas, beliefs, +experiences, and, in particular, methods of placing and presenting +historical textual materials in computerized form. Most attendees gained +much in insight and outlook from the event. But the assembly did not +form a new nation, or, to put it another way, the diversity of projects +and interests was too great to draw the representatives into a cohesive, +action-oriented body.(2) + +Everyone attending the Workshop shared an interest in preserving and +providing access to historical texts. But within this broad field the +attendees represented a variety of formal, informal, figurative, and +literal groups, with many individuals belonging to more than one. These +groups may be defined roughly according to the following topics or +activities: + +* Imaging +* Searchable coded texts +* National and international computer networks +* CD-ROM production and dissemination +* Methods and technology for converting older paper materials into +electronic form +* Study of the use of digital materials by scholars and others + +This summary is arranged thematically and does not follow the actual +sequence of presentations. + +NOTES: + (1) In this document, the phrase electronic text is used to mean + any computerized reproduction or version of a document, book, + article, or manuscript (including images), and not merely a machine- + readable or machine-searchable text. + + (2) The Workshop was held at the Library of Congress on 9-10 June + 1992, with funding from the David and Lucile Packard Foundation. + The document that follows represents a summary of the presentations + made at the Workshop and was compiled by James DALY. This + introduction was written by DALY and Carl FLEISCHHAUER. + + +PRESERVATION AND IMAGING + +Preservation, as that term is used by archivists,(3) was most explicitly +discussed in the context of imaging. Anne KENNEY and Lynne PERSONIUS +explained how the concept of a faithful copy and the user-friendliness of +the traditional book have guided their project at Cornell University.(4) +Although interested in computerized dissemination, participants in the +Cornell project are creating digital image sets of older books in the +public domain as a source for a fresh paper facsimile or, in a future +phase, microfilm. The books returned to the library shelves are +high-quality and useful replacements on acid-free paper that should last +a long time. To date, the Cornell project has placed little or no +emphasis on creating searchable texts; one would not be surprised to find +that the project participants view such texts as new editions, and thus +not as faithful reproductions. + +In her talk on preservation, Patricia BATTIN struck an ecumenical and +flexible note as she endorsed the creation and dissemination of a variety +of types of digital copies. Do not be too narrow in defining what counts +as a preservation element, BATTIN counseled; for the present, at least, +digital copies made with preservation in mind cannot be as narrowly +standardized as, say, microfilm copies with the same objective. Setting +standards precipitously can inhibit creativity, but delay can result in +chaos, she advised. + +In part, BATTIN's position reflected the unsettled nature of image-format +standards, and attendees could hear echoes of this unsettledness in the +comments of various speakers. For example, Jean BARONAS reviewed the +status of several formal standards moving through committees of experts; +and Clifford LYNCH encouraged the use of a new guideline for transmitting +document images on Internet. Testimony from participants in the National +Agricultural Library's (NAL) Text Digitization Program and LC's American +Memory project highlighted some of the challenges to the actual creation +or interchange of images, including difficulties in converting +preservation microfilm to digital form. Donald WATERS reported on the +progress of a master plan for a project at Yale University to convert +books on microfilm to digital image sets, Project Open Book (POB). + +The Workshop offered rather less of an imaging practicum than planned, +but "how-to" hints emerge at various points, for example, throughout +KENNEY's presentation and in the discussion of arcana such as +thresholding and dithering offered by George THOMA and FLEISCHHAUER. + +NOTES: + (3) Although there is a sense in which any reproductions of + historical materials preserve the human record, specialists in the + field have developed particular guidelines for the creation of + acceptable preservation copies. + + (4) Titles and affiliations of presenters are given at the + beginning of their respective talks and in the Directory of + Participants (Appendix III). + + +THE MACHINE-READABLE TEXT: MARKUP AND USE + +The sections of the Workshop that dealt with machine-readable text tended +to be more concerned with access and use than with preservation, at least +in the narrow technical sense. Michael SPERBERG-McQUEEN made a forceful +presentation on the Text Encoding Initiative's (TEI) implementation of +the Standard Generalized Markup Language (SGML). His ideas were echoed +by Susan HOCKEY, Elli MYLONAS, and Stuart WEIBEL. While the +presentations made by the TEI advocates contained no practicum, their +discussion focused on the value of the finished product, what the +European Community calls reusability, but what may also be termed +durability. They argued that marking up--that is, coding--a text in a +well-conceived way will permit it to be moved from one computer +environment to another, as well as to be used by various users. Two +kinds of markup were distinguished: 1) procedural markup, which +describes the features of a text (e.g., dots on a page), and 2) +descriptive markup, which describes the structure or elements of a +document (e.g., chapters, paragraphs, and front matter). + +The TEI proponents emphasized the importance of texts to scholarship. +They explained how heavily coded (and thus analyzed and annotated) texts +can underlie research, play a role in scholarly communication, and +facilitate classroom teaching. SPERBERG-McQUEEN reminded listeners that +a written or printed item (e.g., a particular edition of a book) is +merely a representation of the abstraction we call a text. To concern +ourselves with faithfully reproducing a printed instance of the text, +SPERBERG-McQUEEN argued, is to concern ourselves with the representation +of a representation ("images as simulacra for the text"). The TEI proponents' +interest in images tends to focus on corollary materials for use in teaching, +for example, photographs of the Acropolis to accompany a Greek text. + +By the end of the Workshop, SPERBERG-McQUEEN confessed to having been +converted to a limited extent to the view that electronic images +constitute a promising alternative to microfilming; indeed, an +alternative probably superior to microfilming. But he was not convinced +that electronic images constitute a serious attempt to represent text in +electronic form. HOCKEY and MYLONAS also conceded that their experience +at the Pierce Symposium the previous week at Georgetown University and +the present conference at the Library of Congress had compelled them to +reevaluate their perspective on the usefulness of text as images. +Attendees could see that the text and image advocates were in +constructive tension, so to say. + +Three nonTEI presentations described approaches to preparing +machine-readable text that are less rigorous and thus less expensive. In +the case of the Papers of George Washington, Dorothy TWOHIG explained +that the digital version will provide a not-quite-perfect rendering of +the transcribed text--some 135,000 documents, available for research +during the decades while the perfect or print version is completed. +Members of the American Memory team and the staff of NAL's Text +Digitization Program (see below) also outlined a middle ground concerning +searchable texts. In the case of American Memory, contractors produce +texts with about 99-percent accuracy that serve as "browse" or +"reference" versions of written or printed originals. End users who need +faithful copies or perfect renditions must refer to accompanying sets of +digital facsimile images or consult copies of the originals in a nearby +library or archive. American Memory staff argued that the high cost of +producing 100-percent accurate copies would prevent LC from offering +access to large parts of its collections. + + +THE MACHINE-READABLE TEXT: METHODS OF CONVERSION + +Although the Workshop did not include a systematic examination of the +methods for converting texts from paper (or from facsimile images) into +machine-readable form, nevertheless, various speakers touched upon this +matter. For example, WEIBEL reported that OCLC has experimented with a +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000. + +Pamela ANDRE presented an overview of NAL's Text Digitization Program and +Judith ZIDAR discussed the technical details. ZIDAR explained how NAL +purchased hardware and software capable of performing optical character +recognition (OCR) and text conversion and used its own staff to convert +texts. The process, ZIDAR said, required extensive editing and project +staff found themselves considering alternatives, including rekeying +and/or creating abstracts or summaries of texts. NAL reckoned costs at +$7 per page. By way of contrast, Ricky ERWAY explained that American +Memory had decided from the start to contract out conversion to external +service bureaus. The criteria used to select these contractors were cost +and quality of results, as opposed to methods of conversion. ERWAY noted +that historical documents or books often do not lend themselves to OCR. +Bound materials represent a special problem. In her experience, quality +control--inspecting incoming materials, counting errors in samples--posed +the most time-consuming aspect of contracting out conversion. ERWAY +reckoned American Memory's costs at $4 per page, but cautioned that fewer +cost-elements had been included than in NAL's figure. + + +OPTIONS FOR DISSEMINATION + +The topic of dissemination proper emerged at various points during the +Workshop. At the session devoted to national and international computer +networks, LYNCH, Howard BESSER, Ronald LARSEN, and Edwin BROWNRIGG +highlighted the virtues of Internet today and of the network that will +evolve from Internet. Listeners could discern in these narratives a +vision of an information democracy in which millions of citizens freely +find and use what they need. LYNCH noted that a lack of standards +inhibits disseminating multimedia on the network, a topic also discussed +by BESSER. LARSEN addressed the issues of network scalability and +modularity and commented upon the difficulty of anticipating the effects +of growth in orders of magnitude. BROWNRIGG talked about the ability of +packet radio to provide certain links in a network without the need for +wiring. However, the presenters also called attention to the +shortcomings and incongruities of present-day computer networks. For +example: 1) Network use is growing dramatically, but much network +traffic consists of personal communication (E-mail). 2) Large bodies of +information are available, but a user's ability to search across their +entirety is limited. 3) There are significant resources for science and +technology, but few network sources provide content in the humanities. +4) Machine-readable texts are commonplace, but the capability of the +system to deal with images (let alone other media formats) lags behind. +A glimpse of a multimedia future for networks, however, was provided by +Maria LEBRON in her overview of the Online Journal of Current Clinical +Trials (OJCCT), and the process of scholarly publishing on-line. + +The contrasting form of the CD-ROM disk was never systematically +analyzed, but attendees could glean an impression from several of the +show-and-tell presentations. The Perseus and American Memory examples +demonstrated recently published disks, while the descriptions of the +IBYCUS version of the Papers of George Washington and Chadwyck-Healey's +Patrologia Latina Database (PLD) told of disks to come. According to +Eric CALALUCA, PLD's principal focus has been on converting Jacques-Paul +Migne's definitive collection of Latin texts to machine-readable form. +Although everyone could share the network advocates' enthusiasm for an +on-line future, the possibility of rolling up one's sleeves for a session +with a CD-ROM containing both textual materials and a powerful retrieval +engine made the disk seem an appealing vessel indeed. The overall +discussion suggested that the transition from CD-ROM to on-line networked +access may prove far slower and more difficult than has been anticipated. + + +WHO ARE THE USERS AND WHAT DO THEY DO? + +Although concerned with the technicalities of production, the Workshop +never lost sight of the purposes and uses of electronic versions of +textual materials. As noted above, those interested in imaging discussed +the problematical matter of digital preservation, while the TEI proponents +described how machine-readable texts can be used in research. This latter +topic received thorough treatment in the paper read by Avra MICHELSON. +She placed the phenomenon of electronic texts within the context of +broader trends in information technology and scholarly communication. + +Among other things, MICHELSON described on-line conferences that +represent a vigorous and important intellectual forum for certain +disciplines. Internet now carries more than 700 conferences, with about +80 percent of these devoted to topics in the social sciences and the +humanities. Other scholars use on-line networks for "distance learning." +Meanwhile, there has been a tremendous growth in end-user computing; +professors today are less likely than their predecessors to ask the +campus computer center to process their data. Electronic texts are one +key to these sophisticated applications, MICHELSON reported, and more and +more scholars in the humanities now work in an on-line environment. +Toward the end of the Workshop, Michael LESK presented a corollary to +MICHELSON's talk, reporting the results of an experiment that compared +the work of one group of chemistry students using traditional printed +texts and two groups using electronic sources. The experiment +demonstrated that in the event one does not know what to read, one needs +the electronic systems; the electronic systems hold no advantage at the +moment if one knows what to read, but neither do they impose a penalty. + +DALY provided an anecdotal account of the revolutionizing impact of the +new technology on his previous methods of research in the field of classics. +His account, by extrapolation, served to illustrate in part the arguments +made by MICHELSON concerning the positive effects of the sudden and radical +transformation being wrought in the ways scholars work. + +Susan VECCIA and Joanne FREEMAN delineated the use of electronic +materials outside the university. The most interesting aspect of their +use, FREEMAN said, could be seen as a paradox: teachers in elementary +and secondary schools requested access to primary source materials but, +at the same time, found that "primariness" itself made these materials +difficult for their students to use. + + +OTHER TOPICS + +Marybeth PETERS reviewed copyright law in the United States and offered +advice during a lively discussion of this subject. But uncertainty +remains concerning the price of copyright in a digital medium, because a +solution remains to be worked out concerning management and synthesis of +copyrighted and out-of-copyright pieces of a database. + +As moderator of the final session of the Workshop, Prosser GIFFORD directed +discussion to future courses of action and the potential role of LC in +advancing them. Among the recommendations that emerged were the following: + + * Workshop participants should 1) begin to think about working + with image material, but structure and digitize it in such a + way that at a later stage it can be interpreted into text, and + 2) find a common way to build text and images together so that + they can be used jointly at some stage in the future, with + appropriate network support, because that is how users will want + to access these materials. The Library might encourage attempts + to bring together people who are working on texts and images. + + * A network version of American Memory should be developed or + consideration should be given to making the data in it + available to people interested in doing network multimedia. + Given the current dearth of digital data that is appealing and + unencumbered by extremely complex rights problems, developing a + network version of American Memory could do much to help make + network multimedia a reality. + + * Concerning the thorny issue of electronic deposit, LC should + initiate a catalytic process in terms of distributed + responsibility, that is, bring together the distributed + organizations and set up a study group to look at all the + issues related to electronic deposit and see where we as a + nation should move. For example, LC might attempt to persuade + one major library in each state to deal with its state + equivalent publisher, which might produce a cooperative project + that would be equitably distributed around the country, and one + in which LC would be dealing with a minimal number of publishers + and minimal copyright problems. LC must also deal with the + concept of on-line publishing, determining, among other things, + how serials such as OJCCT might be deposited for copyright. + + * Since a number of projects are planning to carry out + preservation by creating digital images that will end up in + on-line or near-line storage at some institution, LC might play + a helpful role, at least in the near term, by accelerating how + to catalog that information into the Research Library Information + Network (RLIN) and then into OCLC, so that it would be accessible. + This would reduce the possibility of multiple institutions digitizing + the same work. + + +CONCLUSION + +The Workshop was valuable because it brought together partisans from +various groups and provided an occasion to compare goals and methods. +The more committed partisans frequently communicate with others in their +groups, but less often across group boundaries. The Workshop was also +valuable to attendees--including those involved with American Memory--who +came less committed to particular approaches or concepts. These +attendees learned a great deal, and plan to select and employ elements of +imaging, text-coding, and networked distribution that suit their +respective projects and purposes. + +Still, reality rears its ugly head: no breakthrough has been achieved. +On the imaging side, one confronts a proliferation of competing +data-interchange standards and a lack of consensus on the role of digital +facsimiles in preservation. In the realm of machine-readable texts, one +encounters a reasonably mature standard but methodological difficulties +and high costs. These latter problems, of course, represent a special +impediment to the desire, as it is sometimes expressed in the popular +press, "to put the [contents of the] Library of Congress on line." In +the words of one participant, there was "no solution to the economic +problems--the projects that are out there are surviving, but it is going +to be a lot of work to transform the information industry, and so far the +investment to do that is not forthcoming" (LESK, per litteras). + + + *** *** *** ****** *** *** *** + + + PROCEEDINGS + + +WELCOME + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GIFFORD * Origin of Workshop in current Librarian's desire to make LC's +collections more widely available * Desiderata arising from the prospect +of greater interconnectedness * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +After welcoming participants on behalf of the Library of Congress, +American Memory (AM), and the National Demonstration Lab, Prosser +GIFFORD, director for scholarly programs, Library of Congress, located +the origin of the Workshop on Electronic Texts in a conversation he had +had considerably more than a year ago with Carl FLEISCHHAUER concerning +some of the issues faced by AM. On the assumption that numerous other +people were asking the same questions, the decision was made to bring +together as many of these people as possible to ask the same questions +together. In a deeper sense, GIFFORD said, the origin of the Workshop +lay in the desire of the current Librarian of Congress, James H. +Billington, to make the collections of the Library, especially those +offering unique or unusual testimony on aspects of the American +experience, available to a much wider circle of users than those few +people who can come to Washington to use them. This meant that the +emphasis of AM, from the outset, has been on archival collections of the +basic material, and on making these collections themselves available, +rather than selected or heavily edited products. + +From AM's emphasis followed the questions with which the Workshop began: +who will use these materials, and in what form will they wish to use +them. But an even larger issue deserving mention, in GIFFORD's view, was +the phenomenal growth in Internet connectivity. He expressed the hope +that the prospect of greater interconnectedness than ever before would +lead to: 1) much more cooperative and mutually supportive endeavors; 2) +development of systems of shared and distributed responsibilities to +avoid duplication and to ensure accuracy and preservation of unique +materials; and 3) agreement on the necessary standards and development of +the appropriate directories and indices to make navigation +straightforward among the varied resources that are, and increasingly +will be, available. In this connection, GIFFORD requested that +participants reflect from the outset upon the sorts of outcomes they +thought the Workshop might have. Did those present constitute a group +with sufficient common interests to propose a next step or next steps, +and if so, what might those be? They would return to these questions the +following afternoon. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * Core of Workshop concerns preparation and production of +materials * Special challenge in conversion of textual materials * +Quality versus quantity * Do the several groups represented share common +interests? * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +emphasized that he would attempt to represent the people who perform some +of the work of converting or preparing materials and that the core of +the Workshop had to do with preparation and production. FLEISCHHAUER +then drew a distinction between the long term, when many things would be +available and connected in the ways that GIFFORD described, and the short +term, in which AM not only has wrestled with the issue of what is the +best course to pursue but also has faced a variety of technical +challenges. + +FLEISCHHAUER remarked AM's endeavors to deal with a wide range of library +formats, such as motion picture collections, sound-recording collections, +and pictorial collections of various sorts, especially collections of +photographs. In the course of these efforts, AM kept coming back to +textual materials--manuscripts or rare printed matter, bound materials, +etc. Text posed the greatest conversion challenge of all. Thus, the +genesis of the Workshop, which reflects the problems faced by AM. These +problems include physical problems. For example, those in the library +and archive business deal with collections made up of fragile and rare +manuscript items, bound materials, especially the notoriously brittle +bound materials of the late nineteenth century. These are precious +cultural artifacts, however, as well as interesting sources of +information, and LC desires to retain and conserve them. AM needs to +handle things without damaging them. Guillotining a book to run it +through a sheet feeder must be avoided at all costs. + +Beyond physical problems, issues pertaining to quality arose. For +example, the desire to provide users with a searchable text is affected +by the question of acceptable level of accuracy. One hundred percent +accuracy is tremendously expensive. On the other hand, the output of +optical character recognition (OCR) can be tremendously inaccurate. +Although AM has attempted to find a middle ground, uncertainty persists +as to whether or not it has discovered the right solution. + +Questions of quality arose concerning images as well. FLEISCHHAUER +contrasted the extremely high level of quality of the digital images in +the Cornell Xerox Project with AM's efforts to provide a browse-quality +or access-quality image, as opposed to an archival or preservation image. +FLEISCHHAUER therefore welcomed the opportunity to compare notes. + +FLEISCHHAUER observed in passing that conversations he had had about +networks have begun to signal that for various forms of media a +determination may be made that there is a browse-quality item, or a +distribution-and-access-quality item that may coexist in some systems +with a higher quality archival item that would be inconvenient to send +through the network because of its size. FLEISCHHAUER referred, of +course, to images more than to searchable text. + +As AM considered those questions, several conceptual issues arose: ought +AM occasionally to reproduce materials entirely through an image set, at +other times, entirely through a text set, and in some cases, a mix? +There probably would be times when the historical authenticity of an +artifact would require that its image be used. An image might be +desirable as a recourse for users if one could not provide 100-percent +accurate text. Again, AM wondered, as a practical matter, if a +distinction could be drawn between rare printed matter that might exist +in multiple collections--that is, in ten or fifteen libraries. In such +cases, the need for perfect reproduction would be less than for unique +items. Implicit in his remarks, FLEISCHHAUER conceded, was the admission +that AM has been tilting strongly towards quantity and drawing back a +little from perfect quality. That is, it seemed to AM that society would +be better served if more things were distributed by LC--even if they were +not quite perfect--than if fewer things, perfectly represented, were +distributed. This was stated as a proposition to be tested, with +responses to be gathered from users. + +In thinking about issues related to reproduction of materials and seeing +other people engaged in parallel activities, AM deemed it useful to +convene a conference. Hence, the Workshop. FLEISCHHAUER thereupon +surveyed the several groups represented: 1) the world of images (image +users and image makers); 2) the world of text and scholarship and, within +this group, those concerned with language--FLEISCHHAUER confessed to finding +delightful irony in the fact that some of the most advanced thinkers on +computerized texts are those dealing with ancient Greek and Roman materials; +3) the network world; and 4) the general world of library science, which +includes people interested in preservation and cataloging. + +FLEISCHHAUER concluded his remarks with special thanks to the David and +Lucile Packard Foundation for its support of the meeting, the American +Memory group, the Office for Scholarly Programs, the National +Demonstration Lab, and the Office of Special Events. He expressed the +hope that David Woodley Packard might be able to attend, noting that +Packard's work and the work of the foundation had sponsored a number of +projects in the text area. + + ****** + +SESSION I. CONTENT IN A NEW FORM: WHO WILL USE IT AND WHAT WILL THEY DO? + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DALY * Acknowledgements * A new Latin authors disk * Effects of the new +technology on previous methods of research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Serving as moderator, James DALY acknowledged the generosity of all the +presenters for giving of their time, counsel, and patience in planning +the Workshop, as well as of members of the American Memory project and +other Library of Congress staff, and the David and Lucile Packard +Foundation and its executive director, Colburn S. Wilbur. + +DALY then recounted his visit in March to the Center for Electronic Texts +in the Humanities (CETH) and the Department of Classics at Rutgers +University, where an old friend, Lowell Edmunds, introduced him to the +department's IBYCUS scholarly personal computer, and, in particular, the +new Latin CD-ROM, containing, among other things, almost all classical +Latin literary texts through A.D. 200. Packard Humanities Institute +(PHI), Los Altos, California, released this disk late in 1991, with a +nominal triennial licensing fee. + +Playing with the disk for an hour or so at Rutgers brought home to DALY +at once the revolutionizing impact of the new technology on his previous +methods of research. Had this disk been available two or three years +earlier, DALY contended, when he was engaged in preparing a commentary on +Book 10 of Virgil's Aeneid for Cambridge University Press, he would not +have required a forty-eight-square-foot table on which to spread the +numerous, most frequently consulted items, including some ten or twelve +concordances to key Latin authors, an almost equal number of lexica to +authors who lacked concordances, and where either lexica or concordances +were lacking, numerous editions of authors antedating and postdating Virgil. + +Nor, when checking each of the average six to seven words contained in +the Virgilian hexameter for its usage elsewhere in Virgil's works or +other Latin authors, would DALY have had to maintain the laborious +mechanical process of flipping through these concordances, lexica, and +editions each time. Nor would he have had to frequent as often the +Milton S. Eisenhower Library at the Johns Hopkins University to consult +the Thesaurus Linguae Latinae. Instead of devoting countless hours, or +the bulk of his research time, to gathering data concerning Virgil's use +of words, DALY--now freed by PHI's Latin authors disk from the +tyrannical, yet in some ways paradoxically happy scholarly drudgery-- +would have been able to devote that same bulk of time to analyzing and +interpreting Virgilian verbal usage. + +Citing Theodore Brunner, Gregory Crane, Elli MYLONAS, and Avra MICHELSON, +DALY argued that this reversal in his style of work, made possible by the +new technology, would perhaps have resulted in better, more productive +research. Indeed, even in the course of his browsing the Latin authors +disk at Rutgers, its powerful search, retrieval, and highlighting +capabilities suggested to him several new avenues of research into +Virgil's use of sound effects. This anecdotal account, DALY maintained, +may serve to illustrate in part the sudden and radical transformation +being wrought in the ways scholars work. + + ****** + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MICHELSON * Elements related to scholarship and technology * Electronic +texts within the context of broader trends within information technology +and scholarly communication * Evaluation of the prospects for the use of +electronic texts * Relationship of electronic texts to processes of +scholarly communication in humanities research * New exchange formats +created by scholars * Projects initiated to increase scholarly access to +converted text * Trend toward making electronic resources available +through research and education networks * Changes taking place in +scholarly communication among humanities scholars * Network-mediated +scholarship transforming traditional scholarly practices * Key +information technology trends affecting the conduct of scholarly +communication over the next decade * The trend toward end-user computing +* The trend toward greater connectivity * Effects of these trends * Key +transformations taking place * Summary of principal arguments * +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Avra MICHELSON, Archival Research and Evaluation Staff, National Archives +and Records Administration (NARA), argued that establishing who will use +electronic texts and what they will use them for involves a consideration +of both information technology and scholarship trends. This +consideration includes several elements related to scholarship and +technology: 1) the key trends in information technology that are most +relevant to scholarship; 2) the key trends in the use of currently +available technology by scholars in the nonscientific community; and 3) +the relationship between these two very distinct but interrelated trends. +The investment in understanding this relationship being made by +information providers, technologists, and public policy developers, as +well as by scholars themselves, seems to be pervasive and growing, +MICHELSON contended. She drew on collaborative work with Jeff Rothenberg +on the scholarly use of technology. + +MICHELSON sought to place the phenomenon of electronic texts within the +context of broader trends within information technology and scholarly +communication. She argued that electronic texts are of most use to +researchers to the extent that the researchers' working context (i.e., +their relevant bibliographic sources, collegial feedback, analytic tools, +notes, drafts, etc.), along with their field's primary and secondary +sources, also is accessible in electronic form and can be integrated in +ways that are unique to the on-line environment. + +Evaluation of the prospects for the use of electronic texts includes two +elements: 1) an examination of the ways in which researchers currently +are using electronic texts along with other electronic resources, and 2) +an analysis of key information technology trends that are affecting the +long-term conduct of scholarly communication. MICHELSON limited her +discussion of the use of electronic texts to the practices of humanists +and noted that the scientific community was outside the panel's overview. + +MICHELSON examined the nature of the current relationship of electronic +texts in particular, and electronic resources in general, to what she +maintained were, essentially, five processes of scholarly communication +in humanities research. Researchers 1) identify sources, 2) communicate +with their colleagues, 3) interpret and analyze data, 4) disseminate +their research findings, and 5) prepare curricula to instruct the next +generation of scholars and students. This examination would produce a +clearer understanding of the synergy among these five processes that +fuels the tendency of the use of electronic resources for one process to +stimulate its use for other processes of scholarly communication. + +For the first process of scholarly communication, the identification of +sources, MICHELSON remarked the opportunity scholars now enjoy to +supplement traditional word-of-mouth searches for sources among their +colleagues with new forms of electronic searching. So, for example, +instead of having to visit the library, researchers are able to explore +descriptions of holdings in their offices. Furthermore, if their own +institutions' holdings prove insufficient, scholars can access more than +200 major American library catalogues over Internet, including the +universities of California, Michigan, Pennsylvania, and Wisconsin. +Direct access to the bibliographic databases offers intellectual +empowerment to scholars by presenting a comprehensive means of browsing +through libraries from their homes and offices at their convenience. + +The second process of communication involves communication among +scholars. Beyond the most common methods of communication, scholars are +using E-mail and a variety of new electronic communications formats +derived from it for further academic interchange. E-mail exchanges are +growing at an astonishing rate, reportedly 15 percent a month. They +currently constitute approximately half the traffic on research and +education networks. Moreover, the global spread of E-mail has been so +rapid that it is now possible for American scholars to use it to +communicate with colleagues in close to 140 other countries. + +Other new exchange formats created by scholars and operating on Internet +include more than 700 conferences, with about 80 percent of these devoted +to topics in the social sciences and humanities. The rate of growth of +these scholarly electronic conferences also is astonishing. From l990 to +l991, 200 new conferences were identified on Internet. From October 1991 +to June 1992, an additional 150 conferences in the social sciences and +humanities were added to this directory of listings. Scholars have +established conferences in virtually every field, within every different +discipline. For example, there are currently close to 600 active social +science and humanities conferences on topics such as art and +architecture, ethnomusicology, folklore, Japanese culture, medical +education, and gifted and talented education. The appeal to scholars of +communicating through these conferences is that, unlike any other medium, +electronic conferences today provide a forum for global communication +with peers at the front end of the research process. + +Interpretation and analysis of sources constitutes the third process of +scholarly communication that MICHELSON discussed in terms of texts and +textual resources. The methods used to analyze sources fall somewhere on +a continuum from quantitative analysis to qualitative analysis. +Typically, evidence is culled and evaluated using methods drawn from both +ends of this continuum. At one end, quantitative analysis involves the +use of mathematical processes such as a count of frequencies and +distributions of occurrences or, on a higher level, regression analysis. +At the other end of the continuum, qualitative analysis typically +involves nonmathematical processes oriented toward language +interpretation or the building of theory. Aspects of this work involve +the processing--either manual or computational--of large and sometimes +massive amounts of textual sources, although the use of nontextual +sources as evidence, such as photographs, sound recordings, film footage, +and artifacts, is significant as well. + +Scholars have discovered that many of the methods of interpretation and +analysis that are related to both quantitative and qualitative methods +are processes that can be performed by computers. For example, computers +can count. They can count brush strokes used in a Rembrandt painting or +perform regression analysis for understanding cause and effect. By means +of advanced technologies, computers can recognize patterns, analyze text, +and model concepts. Furthermore, computers can complete these processes +faster with more sources and with greater precision than scholars who +must rely on manual interpretation of data. But if scholars are to use +computers for these processes, source materials must be in a form +amenable to computer-assisted analysis. For this reason many scholars, +once they have identified the sources that are key to their research, are +converting them to machine-readable form. Thus, a representative example +of the numerous textual conversion projects organized by scholars around +the world in recent years to support computational text analysis is the +TLG, the Thesaurus Linguae Graecae. This project is devoted to +converting the extant ancient texts of classical Greece. (Editor's note: +according to the TLG Newsletter of May l992, TLG was in use in thirty-two +different countries. This figure updates MICHELSON's previous count by one.) + +The scholars performing these conversions have been asked to recognize +that the electronic sources they are converting for one use possess value +for other research purposes as well. As a result, during the past few +years, humanities scholars have initiated a number of projects to +increase scholarly access to converted text. So, for example, the Text +Encoding Initiative (TEI), about which more is said later in the program, +was established as an effort by scholars to determine standard elements +and methods for encoding machine-readable text for electronic exchange. +In a second effort to facilitate the sharing of converted text, scholars +have created a new institution, the Center for Electronic Texts in the +Humanities (CETH). The center estimates that there are 8,000 series of +source texts in the humanities that have been converted to +machine-readable form worldwide. CETH is undertaking an international +search for converted text in the humanities, compiling it into an +electronic library, and preparing bibliographic descriptions of the +sources for the Research Libraries Information Network's (RLIN) +machine-readable data file. The library profession has begun to initiate +large conversion projects as well, such as American Memory. + +While scholars have been making converted text available to one another, +typically on disk or on CD-ROM, the clear trend is toward making these +resources available through research and education networks. Thus, the +American and French Research on the Treasury of the French Language +(ARTFL) and the Dante Project are already available on Internet. +MICHELSON summarized this section on interpretation and analysis by +noting that: 1) increasing numbers of humanities scholars in the library +community are recognizing the importance to the advancement of +scholarship of retrospective conversion of source materials in the arts +and humanities; and 2) there is a growing realization that making the +sources available on research and education networks maximizes their +usefulness for the analysis performed by humanities scholars. + +The fourth process of scholarly communication is dissemination of +research findings, that is, publication. Scholars are using existing +research and education networks to engineer a new type of publication: +scholarly-controlled journals that are electronically produced and +disseminated. Although such journals are still emerging as a +communication format, their number has grown, from approximately twelve +to thirty-six during the past year (July 1991 to June 1992). Most of +these electronic scholarly journals are devoted to topics in the +humanities. As with network conferences, scholarly enthusiasm for these +electronic journals stems from the medium's unique ability to advance +scholarship in a way that no other medium can do by supporting global +feedback and interchange, practically in real time, early in the research +process. Beyond scholarly journals, MICHELSON remarked the delivery of +commercial full-text products, such as articles in professional journals, +newsletters, magazines, wire services, and reference sources. These are +being delivered via on-line local library catalogues, especially through +CD-ROMs. Furthermore, according to MICHELSON, there is general optimism +that the copyright and fees issues impeding the delivery of full text on +existing research and education networks soon will be resolved. + +The final process of scholarly communication is curriculum development +and instruction, and this involves the use of computer information +technologies in two areas. The first is the development of +computer-oriented instructional tools, which includes simulations, +multimedia applications, and computer tools that are used to assist in +the analysis of sources in the classroom, etc. The Perseus Project, a +database that provides a multimedia curriculum on classical Greek +civilization, is a good example of the way in which entire curricula are +being recast using information technologies. It is anticipated that the +current difficulty in exchanging electronically computer-based +instructional software, which in turn makes it difficult for one scholar +to build upon the work of others, will be resolved before too long. +Stand-alone curricular applications that involve electronic text will be +shareable through networks, reinforcing their significance as intellectual +products as well as instructional tools. + +The second aspect of electronic learning involves the use of research and +education networks for distance education programs. Such programs +interactively link teachers with students in geographically scattered +locations and rely on the availability of electronic instructional +resources. Distance education programs are gaining wide appeal among +state departments of education because of their demonstrated capacity to +bring advanced specialized course work and an array of experts to many +classrooms. A recent report found that at least 32 states operated at +least one statewide network for education in 1991, with networks under +development in many of the remaining states. + +MICHELSON summarized this section by noting two striking changes taking +place in scholarly communication among humanities scholars. First is the +extent to which electronic text in particular, and electronic resources +in general, are being infused into each of the five processes described +above. As mentioned earlier, there is a certain synergy at work here. +The use of electronic resources for one process tends to stimulate its +use for other processes, because the chief course of movement is toward a +comprehensive on-line working context for humanities scholars that +includes on-line availability of key bibliographies, scholarly feedback, +sources, analytical tools, and publications. MICHELSON noted further +that the movement toward a comprehensive on-line working context for +humanities scholars is not new. In fact, it has been underway for more +than forty years in the humanities, since Father Roberto Busa began +developing an electronic concordance of the works of Saint Thomas Aquinas +in 1949. What we are witnessing today, MICHELSON contended, is not the +beginning of this on-line transition but, for at least some humanities +scholars, the turning point in the transition from a print to an +electronic working context. Coinciding with the on-line transition, the +second striking change is the extent to which research and education +networks are becoming the new medium of scholarly communication. The +existing Internet and the pending National Education and Research Network +(NREN) represent the new meeting ground where scholars are going for +bibliographic information, scholarly dialogue and feedback, the most +current publications in their field, and high-level educational +offerings. Traditional scholarly practices are undergoing tremendous +transformations as a result of the emergence and growing prominence of +what is called network-mediated scholarship. + +MICHELSON next turned to the second element of the framework she proposed +at the outset of her talk for evaluating the prospects for electronic +text, namely the key information technology trends affecting the conduct +of scholarly communication over the next decade: 1) end-user computing +and 2) connectivity. + +End-user computing means that the person touching the keyboard, or +performing computations, is the same as the person who initiates or +consumes the computation. The emergence of personal computers, along +with a host of other forces, such as ubiquitous computing, advances in +interface design, and the on-line transition, is prompting the consumers +of computation to do their own computing, and is thus rendering obsolete +the traditional distinction between end users and ultimate users. + +The trend toward end-user computing is significant to consideration of +the prospects for electronic texts because it means that researchers are +becoming more adept at doing their own computations and, thus, more +competent in the use of electronic media. By avoiding programmer +intermediaries, computation is becoming central to the researcher's +thought process. This direct involvement in computing is changing the +researcher's perspective on the nature of research itself, that is, the +kinds of questions that can be posed, the analytical methodologies that +can be used, the types and amount of sources that are appropriate for +analyses, and the form in which findings are presented. The trend toward +end-user computing means that, increasingly, electronic media and +computation are being infused into all processes of humanities +scholarship, inspiring remarkable transformations in scholarly +communication. + +The trend toward greater connectivity suggests that researchers are using +computation increasingly in network environments. Connectivity is +important to scholarship because it erases the distance that separates +students from teachers and scholars from their colleagues, while allowing +users to access remote databases, share information in many different +media, connect to their working context wherever they are, and +collaborate in all phases of research. + +The combination of the trend toward end-user computing and the trend +toward connectivity suggests that the scholarly use of electronic +resources, already evident among some researchers, will soon become an +established feature of scholarship. The effects of these trends, along +with ongoing changes in scholarly practices, point to a future in which +humanities researchers will use computation and electronic communication +to help them formulate ideas, access sources, perform research, +collaborate with colleagues, seek peer review, publish and disseminate +results, and engage in many other professional and educational activities. + +In summary, MICHELSON emphasized four points: 1) A portion of humanities +scholars already consider electronic texts the preferred format for +analysis and dissemination. 2) Scholars are using these electronic +texts, in conjunction with other electronic resources, in all the +processes of scholarly communication. 3) The humanities scholars' +working context is in the process of changing from print technology to +electronic technology, in many ways mirroring transformations that have +occurred or are occurring within the scientific community. 4) These +changes are occurring in conjunction with the development of a new +communication medium: research and education networks that are +characterized by their capacity to advance scholarship in a wholly unique +way. + +MICHELSON also reiterated her three principal arguments: l) Electronic +texts are best understood in terms of the relationship to other +electronic resources and the growing prominence of network-mediated +scholarship. 2) The prospects for electronic texts lie in their capacity +to be integrated into the on-line network of electronic resources that +comprise the new working context for scholars. 3) Retrospective conversion +of portions of the scholarly record should be a key strategy as information +providers respond to changes in scholarly communication practices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +VECCIA * AM's evaluation project and public users of electronic resources +* AM and its design * Site selection and evaluating the Macintosh +implementation of AM * Characteristics of the six public libraries +selected * Characteristics of AM's users in these libraries * Principal +ways AM is being used * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan VECCIA, team leader, and Joanne FREEMAN, associate coordinator, +American Memory, Library of Congress, gave a joint presentation. First, +by way of introduction, VECCIA explained her and FREEMAN's roles in +American Memory (AM). Serving principally as an observer, VECCIA has +assisted with the evaluation project of AM, placing AM collections in a +variety of different sites around the country and helping to organize and +implement that project. FREEMAN has been an associate coordinator of AM +and has been involved principally with the interpretative materials, +preparing some of the electronic exhibits and printed historical +information that accompanies AM and that is requested by users. VECCIA +and FREEMAN shared anecdotal observations concerning AM with public users +of electronic resources. Notwithstanding a fairly structured evaluation +in progress, both VECCIA and FREEMAN chose not to report on specifics in +terms of numbers, etc., because they felt it was too early in the +evaluation project to do so. + +AM is an electronic archive of primary source materials from the Library +of Congress, selected collections representing a variety of formats-- +photographs, graphic arts, recorded sound, motion pictures, broadsides, +and soon, pamphlets and books. In terms of the design of this system, +the interpretative exhibits have been kept separate from the primary +resources, with good reason. Accompanying this collection are printed +documentation and user guides, as well as guides that FREEMAN prepared for +teachers so that they may begin using the content of the system at once. + +VECCIA described the evaluation project before talking about the public +users of AM, limiting her remarks to public libraries, because FREEMAN +would talk more specifically about schools from kindergarten to twelfth +grade (K-12). Having started in spring 1991, the evaluation currently +involves testing of the Macintosh implementation of AM. Since the +primary goal of this evaluation is to determine the most appropriate +audience or audiences for AM, very different sites were selected. This +makes evaluation difficult because of the varying degrees of technology +literacy among the sites. AM is situated in forty-four locations, of +which six are public libraries and sixteen are schools. Represented +among the schools are elementary, junior high, and high schools. +District offices also are involved in the evaluation, which will +conclude in summer 1993. + +VECCIA focused the remainder of her talk on the six public libraries, one +of which doubles as a state library. They represent a range of +geographic areas and a range of demographic characteristics. For +example, three are located in urban settings, two in rural settings, and +one in a suburban setting. A range of technical expertise is to be found +among these facilities as well. For example, one is an "Apple library of +the future," while two others are rural one-room libraries--in one, AM +sits at the front desk next to a tractor manual. + +All public libraries have been extremely enthusiastic, supportive, and +appreciative of the work that AM has been doing. VECCIA characterized +various users: Most users in public libraries describe themselves as +general readers; of the students who use AM in the public libraries, +those in fourth grade and above seem most interested. Public libraries +in rural sites tend to attract retired people, who have been highly +receptive to AM. Users tend to fall into two additional categories: +people interested in the content and historical connotations of these +primary resources, and those fascinated by the technology. The format +receiving the most comments has been motion pictures. The adult users in +public libraries are more comfortable with IBM computers, whereas young +people seem comfortable with either IBM or Macintosh, although most of +them seem to come from a Macintosh background. This same tendency is +found in the schools. + +What kinds of things do users do with AM? In a public library there are +two main goals or ways that AM is being used: as an individual learning +tool, and as a leisure activity. Adult learning was one area that VECCIA +would highlight as a possible application for a tool such as AM. She +described a patron of a rural public library who comes in every day on +his lunch hour and literally reads AM, methodically going through the +collection image by image. At the end of his hour he makes an electronic +bookmark, puts it in his pocket, and returns to work. The next day he +comes in and resumes where he left off. Interestingly, this man had +never been in the library before he used AM. In another small, rural +library, the coordinator reports that AM is a popular activity for some +of the older, retired people in the community, who ordinarily would not +use "those things,"--computers. Another example of adult learning in +public libraries is book groups, one of which, in particular, is using AM +as part of its reading on industrialization, integration, and urbanization +in the early 1900s. + +One library reports that a family is using AM to help educate their +children. In another instance, individuals from a local museum came in +to use AM to prepare an exhibit on toys of the past. These two examples +emphasize the mission of the public library as a cultural institution, +reaching out to people who do not have the same resources available to +those who live in a metropolitan area or have access to a major library. +One rural library reports that junior high school students in large +numbers came in one afternoon to use AM for entertainment. A number of +public libraries reported great interest among postcard collectors in the +Detroit collection, which was essentially a collection of images used on +postcards around the turn of the century. Train buffs are similarly +interested because that was a time of great interest in railroading. +People, it was found, relate to things that they know of firsthand. For +example, in both rural public libraries where AM was made available, +observers reported that the older people with personal remembrances of +the turn of the century were gravitating to the Detroit collection. +These examples served to underscore MICHELSON's observation re the +integration of electronic tools and ideas--that people learn best when +the material relates to something they know. + +VECCIA made the final point that in many cases AM serves as a +public-relations tool for the public libraries that are testing it. In +one case, AM is being used as a vehicle to secure additional funding for +the library. In another case, AM has served as an inspiration to the +staff of a major local public library in the South to think about ways to +make its own collection of photographs more accessible to the public. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FREEMAN * AM and archival electronic resources in a school environment * +Questions concerning context * Questions concerning the electronic format +itself * Computer anxiety * Access and availability of the system * +Hardware * Strengths gained through the use of archival resources in +schools * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Reiterating an observation made by VECCIA, that AM is an archival +resource made up of primary materials with very little interpretation, +FREEMAN stated that the project has attempted to bridge the gap between +these bare primary materials and a school environment, and in that cause +has created guided introductions to AM collections. Loud demand from the +educational community, chiefly from teachers working with the upper +grades of elementary school through high school, greeted the announcement +that AM would be tested around the country. + +FREEMAN reported not only on what was learned about AM in a school +environment, but also on several universal questions that were raised +concerning archival electronic resources in schools. She discussed +several strengths of this type of material in a school environment as +opposed to a highly structured resource that offers a limited number of +paths to follow. + +FREEMAN first raised several questions about using AM in a school +environment. There is often some difficulty in developing a sense of +what the system contains. Many students sit down at a computer resource +and assume that, because AM comes from the Library of Congress, all of +American history is now at their fingertips. As a result of that sort of +mistaken judgment, some students are known to conclude that AM contains +nothing of use to them when they look for one or two things and do not +find them. It is difficult to discover that middle ground where one has +a sense of what the system contains. Some students grope toward the idea +of an archive, a new idea to them, since they have not previously +experienced what it means to have access to a vast body of somewhat +random information. + +Other questions raised by FREEMAN concerned the electronic format itself. +For instance, in a school environment it is often difficult both for +teachers and students to gain a sense of what it is they are viewing. +They understand that it is a visual image, but they do not necessarily +know that it is a postcard from the turn of the century, a panoramic +photograph, or even machine-readable text of an eighteenth-century +broadside, a twentieth-century printed book, or a nineteenth-century +diary. That distinction is often difficult for people in a school +environment to grasp. Because of that, it occasionally becomes difficult +to draw conclusions from what one is viewing. + +FREEMAN also noted the obvious fear of the computer, which constitutes a +difficulty in using an electronic resource. Though students in general +did not suffer from this anxiety, several older students feared that they +were computer-illiterate, an assumption that became self-fulfilling when +they searched for something but failed to find it. FREEMAN said she +believed that some teachers also fear computer resources, because they +believe they lack complete control. FREEMAN related the example of +teachers shooing away students because it was not their time to use the +system. This was a case in which the situation had to be extremely +structured so that the teachers would not feel that they had lost their +grasp on what the system contained. + +A final question raised by FREEMAN concerned access and availability of +the system. She noted the occasional existence of a gap in communication +between school librarians and teachers. Often AM sits in a school +library and the librarian is the person responsible for monitoring the +system. Teachers do not always take into their world new library +resources about which the librarian is excited. Indeed, at the sites +where AM had been used most effectively within a library, the librarian +was required to go to specific teachers and instruct them in its use. As +a result, several AM sites will have in-service sessions over a summer, +in the hope that perhaps, with a more individualized link, teachers will +be more likely to use the resource. + +A related issue in the school context concerned the number of +workstations available at any one location. Centralization of equipment +at the district level, with teachers invited to download things and walk +away with them, proved unsuccessful because the hours these offices were +open were also school hours. + +Another issue was hardware. As VECCIA observed, a range of sites exists, +some technologically advanced and others essentially acquiring their +first computer for the primary purpose of using it in conjunction with +AM's testing. Users at technologically sophisticated sites want even +more sophisticated hardware, so that they can perform even more +sophisticated tasks with the materials in AM. But once they acquire a +newer piece of hardware, they must learn how to use that also; at an +unsophisticated site it takes an extremely long time simply to become +accustomed to the computer, not to mention the program offered with the +computer. All of these small issues raise one large question, namely, +are systems like AM truly rewarding in a school environment, or do they +simply act as innovative toys that do little more than spark interest? + +FREEMAN contended that the evaluation project has revealed several strengths +that were gained through the use of archival resources in schools, including: + + * Psychic rewards from using AM as a vast, rich database, with + teachers assigning various projects to students--oral presentations, + written reports, a documentary, a turn-of-the-century newspaper-- + projects that start with the materials in AM but are completed using + other resources; AM thus is used as a research tool in conjunction + with other electronic resources, as well as with books and items in + the library where the system is set up. + + * Students are acquiring computer literacy in a humanities context. + + * This sort of system is overcoming the isolation between disciplines + that often exists in schools. For example, many English teachers are + requiring their students to write papers on historical topics + represented in AM. Numerous teachers have reported that their + students are learning critical thinking skills using the system. + + * On a broader level, AM is introducing primary materials, not only + to students but also to teachers, in an environment where often + simply none exist--an exciting thing for the students because it + helps them learn to conduct research, to interpret, and to draw + their own conclusions. In learning to conduct research and what it + means, students are motivated to seek knowledge. That relates to + another positive outcome--a high level of personal involvement of + students with the materials in this system and greater motivation to + conduct their own research and draw their own conclusions. + + * Perhaps the most ironic strength of these kinds of archival + electronic resources is that many of the teachers AM interviewed + were desperate, it is no exaggeration to say, not only for primary + materials but for unstructured primary materials. These would, they + thought, foster personally motivated research, exploration, and + excitement in their students. Indeed, these materials have done + just that. Ironically, however, this lack of structure produces + some of the confusion to which the newness of these kinds of + resources may also contribute. The key to effective use of archival + products in a school environment is a clear, effective introduction + to the system and to what it contains. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Nothing known, quantitatively, about the number of +humanities scholars who must see the original versus those who would +settle for an edited transcript, or about the ways in which humanities +scholars are using information technology * Firm conclusions concerning +the manner and extent of the use of supporting materials in print +provided by AM to await completion of evaluative study * A listener's +reflections on additional applications of electronic texts * Role of +electronic resources in teaching elementary research skills to students * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed the presentations by MICHELSON, +VECCIA, and FREEMAN, additional points emerged. + +LESK asked if MICHELSON could give any quantitative estimate of the +number of humanities scholars who must see or want to see the original, +or the best possible version of the material, versus those who typically +would settle for an edited transcript. While unable to provide a figure, +she offered her impressions as an archivist who has done some reference +work and has discussed this issue with other archivists who perform +reference, that those who use archives and those who use primary sources +for what would be considered very high-level scholarly research, as +opposed to, say, undergraduate papers, were few in number, especially +given the public interest in using primary sources to conduct +genealogical or avocational research and the kind of professional +research done by people in private industry or the federal government. +More important in MICHELSON's view was that, quantitatively, nothing is +known about the ways in which, for example, humanities scholars are using +information technology. No studies exist to offer guidance in creating +strategies. The most recent study was conducted in 1985 by the American +Council of Learned Societies (ACLS), and what it showed was that 50 +percent of humanities scholars at that time were using computers. That +constitutes the extent of our knowledge. + +Concerning AM's strategy for orienting people toward the scope of +electronic resources, FREEMAN could offer no hard conclusions at this +point, because she and her colleagues were still waiting to see, +particularly in the schools, what has been made of their efforts. Within +the system, however, AM has provided what are called electronic exhibits- +-such as introductions to time periods and materials--and these are +intended to offer a student user a sense of what a broadside is and what +it might tell her or him. But FREEMAN conceded that the project staff +would have to talk with students next year, after teachers have had a +summer to use the materials, and attempt to discover what the students +were learning from the materials. In addition, FREEMAN described +supporting materials in print provided by AM at the request of local +teachers during a meeting held at LC. These included time lines, +bibliographies, and other materials that could be reproduced on a +photocopier in a classroom. Teachers could walk away with and use these, +and in this way gain a better understanding of the contents. But again, +reaching firm conclusions concerning the manner and extent of their use +would have to wait until next year. + +As to the changes she saw occurring at the National Archives and Records +Administration (NARA) as a result of the increasing emphasis on +technology in scholarly research, MICHELSON stated that NARA at this +point was absorbing the report by her and Jeff Rothenberg addressing +strategies for the archival profession in general, although not for the +National Archives specifically. NARA is just beginning to establish its +role and what it can do. In terms of changes and initiatives that NARA +can take, no clear response could be given at this time. + +GREENFIELD remarked two trends mentioned in the session. Reflecting on +DALY's opening comments on how he could have used a Latin collection of +text in an electronic form, he said that at first he thought most scholars +would be unwilling to do that. But as he thought of that in terms of the +original meaning of research--that is, having already mastered these texts, +researching them for critical and comparative purposes--for the first time, +the electronic format made a lot of sense. GREENFIELD could envision +growing numbers of scholars learning the new technologies for that very +aspect of their scholarship and for convenience's sake. + +Listening to VECCIA and FREEMAN, GREENFIELD thought of an additional +application of electronic texts. He realized that AM could be used as a +guide to lead someone to original sources. Students cannot be expected +to have mastered these sources, things they have never known about +before. Thus, AM is leading them, in theory, to a vast body of +information and giving them a superficial overview of it, enabling them +to select parts of it. GREENFIELD asked if any evidence exists that this +resource will indeed teach the new user, the K-12 students, how to do +research. Scholars already know how to do research and are applying +these new tools. But he wondered why students would go beyond picking +out things that were most exciting to them. + +FREEMAN conceded the correctness of GREENFIELD's observation as applied +to a school environment. The risk is that a student would sit down at a +system, play with it, find some things of interest, and then walk away. +But in the relatively controlled situation of a school library, much will +depend on the instructions a teacher or a librarian gives a student. She +viewed the situation not as one of fine-tuning research skills but of +involving students at a personal level in understanding and researching +things. Given the guidance one can receive at school, it then becomes +possible to teach elementary research skills to students, which in fact +one particular librarian said she was teaching her fifth graders. +FREEMAN concluded that introducing the idea of following one's own path +of inquiry, which is essentially what research entails, involves more +than teaching specific skills. To these comments VECCIA added the +observation that the individual teacher and the use of a creative +resource, rather than AM itself, seemed to make the key difference. +Some schools and some teachers are making excellent use of the nature +of critical thinking and teaching skills, she said. + +Concurring with these remarks, DALY closed the session with the thought that +the more that producers produced for teachers and for scholars to use with +their students, the more successful their electronic products would prove. + + ****** + +SESSION II. SHOW AND TELL + +Jacqueline HESS, director, National Demonstration Laboratory, served as +moderator of the "show-and-tell" session. She noted that a +question-and-answer period would follow each presentation. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +MYLONAS * Overview and content of Perseus * Perseus' primary materials +exist in a system-independent, archival form * A concession * Textual +aspects of Perseus * Tools to use with the Greek text * Prepared indices +and full-text searches in Perseus * English-Greek word search leads to +close study of words and concepts * Navigating Perseus by tracing down +indices * Using the iconography to perform research * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Elli MYLONAS, managing editor, Perseus Project, Harvard University, first +gave an overview of Perseus, a large, collaborative effort based at +Harvard University but with contributors and collaborators located at +numerous universities and colleges in the United States (e.g., Bowdoin, +Maryland, Pomona, Chicago, Virginia). Funded primarily by the +Annenberg/CPB Project, with additional funding from Apple, Harvard, and +the Packard Humanities Institute, among others, Perseus is a multimedia, +hypertextual database for teaching and research on classical Greek +civilization, which was released in February 1992 in version 1.0 and +distributed by Yale University Press. + +Consisting entirely of primary materials, Perseus includes ancient Greek +texts and translations of those texts; catalog entries--that is, museum +catalog entries, not library catalog entries--on vases, sites, coins, +sculpture, and archaeological objects; maps; and a dictionary, among +other sources. The number of objects and the objects for which catalog +entries exist are accompanied by thousands of color images, which +constitute a major feature of the database. Perseus contains +approximately 30 megabytes of text, an amount that will double in +subsequent versions. In addition to these primary materials, the Perseus +Project has been building tools for using them, making access and +navigation easier, the goal being to build part of the electronic +environment discussed earlier in the morning in which students or +scholars can work with their sources. + +The demonstration of Perseus will show only a fraction of the real work +that has gone into it, because the project had to face the dilemma of +what to enter when putting something into machine-readable form: should +one aim for very high quality or make concessions in order to get the +material in? Since Perseus decided to opt for very high quality, all of +its primary materials exist in a system-independent--insofar as it is +possible to be system-independent--archival form. Deciding what that +archival form would be and attaining it required much work and thought. +For example, all the texts are marked up in SGML, which will be made +compatible with the guidelines of the Text Encoding Initiative (TEI) when +they are issued. + +Drawings are postscript files, not meeting international standards, but +at least designed to go across platforms. Images, or rather the real +archival forms, consist of the best available slides, which are being +digitized. Much of the catalog material exists in database form--a form +that the average user could use, manipulate, and display on a personal +computer, but only at great cost. Thus, this is where the concession +comes in: All of this rich, well-marked-up information is stripped of +much of its content; the images are converted into bit-maps and the text +into small formatted chunks. All this information can then be imported +into HyperCard and run on a mid-range Macintosh, which is what Perseus +users have. This fact has made it possible for Perseus to attain wide +use fairly rapidly. Without those archival forms the HyperCard version +being demonstrated could not be made easily, and the project could not +have the potential to move to other forms and machines and software as +they appear, none of which information is in Perseus on the CD. + +Of the numerous multimedia aspects of Perseus, MYLONAS focused on the +textual. Part of what makes Perseus such a pleasure to use, MYLONAS +said, is this effort at seamless integration and the ability to move +around both visual and textual material. Perseus also made the decision +not to attempt to interpret its material any more than one interprets by +selecting. But, MYLONAS emphasized, Perseus is not courseware: No +syllabus exists. There is no effort to define how one teaches a topic +using Perseus, although the project may eventually collect papers by +people who have used it to teach. Rather, Perseus aims to provide +primary material in a kind of electronic library, an electronic sandbox, +so to say, in which students and scholars who are working on this +material can explore by themselves. With that, MYLONAS demonstrated +Perseus, beginning with the Perseus gateway, the first thing one sees +upon opening Perseus--an effort in part to solve the contextualizing +problem--which tells the user what the system contains. + +MYLONAS demonstrated only a very small portion, beginning with primary +texts and running off the CD-ROM. Having selected Aeschylus' Prometheus +Bound, which was viewable in Greek and English pretty much in the same +segments together, MYLONAS demonstrated tools to use with the Greek text, +something not possible with a book: looking up the dictionary entry form +of an unfamiliar word in Greek after subjecting it to Perseus' +morphological analysis for all the texts. After finding out about a +word, a user may then decide to see if it is used anywhere else in Greek. +Because vast amounts of indexing support all of the primary material, one +can find out where else all forms of a particular Greek word appear-- +often not a trivial matter because Greek is highly inflected. Further, +since the story of Prometheus has to do with the origins of sacrifice, a +user may wish to study and explore sacrifice in Greek literature; by +typing sacrifice into a small window, a user goes to the English-Greek +word list--something one cannot do without the computer (Perseus has +indexed the definitions of its dictionary)--the string sacrifice appears +in the definitions of these sixty-five words. One may then find out +where any of those words is used in the work(s) of a particular author. +The English definitions are not lemmatized. + +All of the indices driving this kind of usage were originally devised for +speed, MYLONAS observed; in other words, all that kind of information-- +all forms of all words, where they exist, the dictionary form they belong +to--were collected into databases, which will expedite searching. Then +it was discovered that one can do things searching in these databases +that could not be done searching in the full texts. Thus, although there +are full-text searches in Perseus, much of the work is done behind the +scenes, using prepared indices. Re the indexing that is done behind the +scenes, MYLONAS pointed out that without the SGML forms of the text, it +could not be done effectively. Much of this indexing is based on the +structures that are made explicit by the SGML tagging. + +It was found that one of the things many of Perseus' non-Greek-reading +users do is start from the dictionary and then move into the close study +of words and concepts via this kind of English-Greek word search, by which +means they might select a concept. This exercise has been assigned to +students in core courses at Harvard--to study a concept by looking for the +English word in the dictionary, finding the Greek words, and then finding +the words in the Greek but, of course, reading across in the English. +That tells them a great deal about what a translation means as well. + +Should one also wish to see images that have to do with sacrifice, that +person would go to the object key word search, which allows one to +perform a similar kind of index retrieval on the database of +archaeological objects. Without words, pictures are useless; Perseus has +not reached the point where it can do much with images that are not +cataloged. Thus, although it is possible in Perseus with text and images +to navigate by knowing where one wants to end up--for example, a +red-figure vase from the Boston Museum of Fine Arts--one can perform this +kind of navigation very easily by tracing down indices. MYLONAS +illustrated several generic scenes of sacrifice on vases. The features +demonstrated derived from Perseus 1.0; version 2.0 will implement even +better means of retrieval. + +MYLONAS closed by looking at one of the pictures and noting again that +one can do a great deal of research using the iconography as well as the +texts. For instance, students in a core course at Harvard this year were +highly interested in Greek concepts of foreigners and representations of +non-Greeks. So they performed a great deal of research, both with texts +(e.g., Herodotus) and with iconography on vases and coins, on how the +Greeks portrayed non-Greeks. At the same time, art historians who study +iconography were also interested, and were able to use this material. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Indexing and searchability of all English words in Perseus * +Several features of Perseus 1.0 * Several levels of customization +possible * Perseus used for general education * Perseus' effects on +education * Contextual information in Perseus * Main challenge and +emphasis of Perseus * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Several points emerged in the discussion that followed MYLONAS's presentation. + +Although MYLONAS had not demonstrated Perseus' ability to cross-search +documents, she confirmed that all English words in Perseus are indexed +and can be searched. So, for example, sacrifice could have been searched +in all texts, the historical essay, and all the catalogue entries with +their descriptions--in short, in all of Perseus. + +Boolean logic is not in Perseus 1.0 but will be added to the next +version, although an effort is being made not to restrict Perseus to a +database in which one just performs searching, Boolean or otherwise. It +is possible to move laterally through the documents by selecting a word +one is interested in and selecting an area of information one is +interested in and trying to look that word up in that area. + +Since Perseus was developed in HyperCard, several levels of customization +are possible. Simple authoring tools exist that allow one to create +annotated paths through the information, which are useful for note-taking +and for guided tours for teaching purposes and for expository writing. +With a little more ingenuity it is possible to begin to add or substitute +material in Perseus. + +Perseus has not been used so much for classics education as for general +education, where it seemed to have an impact on the students in the core +course at Harvard (a general required course that students must take in +certain areas). Students were able to use primary material much more. + +The Perseus Project has an evaluation team at the University of Maryland +that has been documenting Perseus' effects on education. Perseus is very +popular, and anecdotal evidence indicates that it is having an effect at +places other than Harvard, for example, test sites at Ball State +University, Drury College, and numerous small places where opportunities +to use vast amounts of primary data may not exist. One documented effect +is that archaeological, anthropological, and philological research is +being done by the same person instead of by three different people. + +The contextual information in Perseus includes an overview essay, a +fairly linear historical essay on the fifth century B.C. that provides +links into the primary material (e.g., Herodotus, Thucydides, and +Plutarch), via small gray underscoring (on the screen) of linked +passages. These are handmade links into other material. + +To different extents, most of the production work was done at Harvard, +where the people and the equipment are located. Much of the +collaborative activity involved data collection and structuring, because +the main challenge and the emphasis of Perseus is the gathering of +primary material, that is, building a useful environment for studying +classical Greece, collecting data, and making it useful. +Systems-building is definitely not the main concern. Thus, much of the +work has involved writing essays, collecting information, rewriting it, +and tagging it. That can be done off site. The creative link for the +overview essay as well as for both systems and data was collaborative, +and was forged via E-mail and paper mail with professors at Pomona and +Bowdoin. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * PLD's principal focus and contribution to scholarship * +Various questions preparatory to beginning the project * Basis for +project * Basic rule in converting PLD * Concerning the images in PLD * +Running PLD under a variety of retrieval software * Encoding the +database a hard-fought issue * Various features demonstrated * Importance +of user documentation * Limitations of the CD-ROM version * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Eric CALALUCA, vice president, Chadwyck-Healey, Inc., demonstrated a +software interpretation of the Patrologia Latina Database (PLD). PLD's +principal focus from the beginning of the project about three-and-a-half +years ago was on converting Migne's Latin series, and in the end, +CALALUCA suggested, conversion of the text will be the major contribution +to scholarship. CALALUCA stressed that, as possibly the only private +publishing organization at the Workshop, Chadwyck-Healey had sought no +federal funds or national foundation support before embarking upon the +project, but instead had relied upon a great deal of homework and +marketing to accomplish the task of conversion. + +Ever since the possibilities of computer-searching have emerged, scholars +in the field of late ancient and early medieval studies (philosophers, +theologians, classicists, and those studying the history of natural law +and the history of the legal development of Western civilization) have +been longing for a fully searchable version of Western literature, for +example, all the texts of Augustine and Bernard of Clairvaux and +Boethius, not to mention all the secondary and tertiary authors. + +Various questions arose, CALALUCA said. Should one convert Migne? +Should the database be encoded? Is it necessary to do that? How should +it be delivered? What about CD-ROM? Since this is a transitional +medium, why even bother to create software to run on a CD-ROM? Since +everybody knows people will be networking information, why go to the +trouble--which is far greater with CD-ROM than with the production of +magnetic data? Finally, how does one make the data available? Can many +of the hurdles to using electronic information that some publishers have +imposed upon databases be eliminated? + +The PLD project was based on the principle that computer-searching of +texts is most effective when it is done with a large database. Because +PLD represented a collection that serves so many disciplines across so +many periods, it was irresistible. + +The basic rule in converting PLD was to do no harm, to avoid the sins of +intrusion in such a database: no introduction of newer editions, no +on-the-spot changes, no eradicating of all possible falsehoods from an +edition. Thus, PLD is not the final act in electronic publishing for +this discipline, but simply the beginning. The conversion of PLD has +evoked numerous unanticipated questions: How will information be used? +What about networking? Can the rights of a database be protected? +Should one protect the rights of a database? How can it be made +available? + +Those converting PLD also tried to avoid the sins of omission, that is, +excluding portions of the collections or whole sections. What about the +images? PLD is full of images, some are extremely pious +nineteenth-century representations of the Fathers, while others contain +highly interesting elements. The goal was to cover all the text of Migne +(including notes, in Greek and in Hebrew, the latter of which, in +particular, causes problems in creating a search structure), all the +indices, and even the images, which are being scanned in separately +searchable files. + +Several North American institutions that have placed acquisition requests +for the PLD database have requested it in magnetic form without software, +which means they are already running it without software, without +anything demonstrated at the Workshop. + +What cannot practically be done is go back and reconvert and re-encode +data, a time-consuming and extremely costly enterprise. CALALUCA sees +PLD as a database that can, and should, be run under a variety of +retrieval software. This will permit the widest possible searches. +Consequently, the need to produce a CD-ROM of PLD, as well as to develop +software that could handle some 1.3 gigabyte of heavily encoded text, +developed out of conversations with collection development and reference +librarians who wanted software both compassionate enough for the +pedestrian but also capable of incorporating the most detailed +lexicographical studies that a user desires to conduct. In the end, the +encoding and conversion of the data will prove the most enduring +testament to the value of the project. + +The encoding of the database was also a hard-fought issue: Did the +database need to be encoded? Were there normative structures for encoding +humanist texts? Should it be SGML? What about the TEI--will it last, +will it prove useful? CALALUCA expressed some minor doubts as to whether +a data bank can be fully TEI-conformant. Every effort can be made, but +in the end to be TEI-conformant means to accept the need to make some +firm encoding decisions that can, indeed, be disputed. The TEI points +the publisher in a proper direction but does not presume to make all the +decisions for him or her. Essentially, the goal of encoding was to +eliminate, as much as possible, the hindrances to information-networking, +so that if an institution acquires a database, everybody associated with +the institution can have access to it. + +CALALUCA demonstrated a portion of Volume 160, because it had the most +anomalies in it. The software was created by Electronic Book +Technologies of Providence, RI, and is called Dynatext. The software +works only with SGML-coded data. + +Viewing a table of contents on the screen, the audience saw how Dynatext +treats each element as a book and attempts to simplify movement through a +volume. Familiarity with the Patrologia in print (i.e., the text, its +source, and the editions) will make the machine-readable versions highly +useful. (Software with a Windows application was sought for PLD, +CALALUCA said, because this was the main trend for scholarly use.) + +CALALUCA also demonstrated how a user can perform a variety of searches +and quickly move to any part of a volume; the look-up screen provides +some basic, simple word-searching. + +CALALUCA argued that one of the major difficulties is not the software. +Rather, in creating a product that will be used by scholars representing +a broad spectrum of computer sophistication, user documentation proves +to be the most important service one can provide. + +CALALUCA next illustrated a truncated search under mysterium within ten +words of virtus and how one would be able to find its contents throughout +the entire database. He said that the exciting thing about PLD is that +many of the applications in the retrieval software being written for it +will exceed the capabilities of the software employed now for the CD-ROM +version. The CD-ROM faces genuine limitations, in terms of speed and +comprehensiveness, in the creation of a retrieval software to run it. +CALALUCA said he hoped that individual scholars will download the data, +if they wish, to their personal computers, and have ready access to +important texts on a constant basis, which they will be able to use in +their research and from which they might even be able to publish. + +(CALALUCA explained that the blue numbers represented Migne's column numbers, +which are the standard scholarly references. Pulling up a note, he stated +that these texts were heavily edited and the image files would appear simply +as a note as well, so that one could quickly access an image.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER/ERWAY * Several problems with which AM is still wrestling * +Various search and retrieval capabilities * Illustration of automatic +stemming and a truncated search * AM's attempt to find ways to connect +cataloging to the texts * AM's gravitation towards SGML * Striking a +balance between quantity and quality * How AM furnishes users recourse to +images * Conducting a search in a full-text environment * Macintosh and +IBM prototypes of AM * Multimedia aspects of AM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +A demonstration of American Memory by its coordinator, Carl FLEISCHHAUER, +and Ricky ERWAY, associate coordinator, Library of Congress, concluded +the morning session. Beginning with a collection of broadsides from the +Continental Congress and the Constitutional Convention, the only text +collection in a presentable form at the time of the Workshop, FLEISCHHAUER +highlighted several of the problems with which AM is still wrestling. +(In its final form, the disk will contain two collections, not only the +broadsides but also the full text with illustrations of a set of +approximately 300 African-American pamphlets from the period 1870 to 1910.) + +As FREEMAN had explained earlier, AM has attempted to use a small amount +of interpretation to introduce collections. In the present case, the +contractor, a company named Quick Source, in Silver Spring, MD., used +software called Toolbook and put together a modestly interactive +introduction to the collection. Like the two preceding speakers, +FLEISCHHAUER argued that the real asset was the underlying collection. + +FLEISCHHAUER proceeded to describe various search and retrieval +capabilities while ERWAY worked the computer. In this particular package +the "go to" pull-down allowed the user in effect to jump out of Toolbook, +where the interactive program was located, and enter the third-party +software used by AM for this text collection, which is called Personal +Librarian. This was the Windows version of Personal Librarian, a +software application put together by a company in Rockville, Md. + +Since the broadsides came from the Revolutionary War period, a search was +conducted using the words British or war, with the default operator reset +as or. FLEISCHHAUER demonstrated both automatic stemming (which finds +other forms of the same root) and a truncated search. One of Personal +Librarian's strongest features, the relevance ranking, was represented by +a chart that indicated how often words being sought appeared in +documents, with the one receiving the most "hits" obtaining the highest +score. The "hit list" that is supplied takes the relevance ranking into +account, making the first hit, in effect, the one the software has +selected as the most relevant example. + +While in the text of one of the broadside documents, FLEISCHHAUER +remarked AM's attempt to find ways to connect cataloging to the texts, +which it does in different ways in different manifestations. In the case +shown, the cataloging was pasted on: AM took MARC records that were +written as on-line records right into one of the Library's mainframe +retrieval programs, pulled them out, and handed them off to the contractor, +who massaged them somewhat to display them in the manner shown. One of +AM's questions is, Does the cataloguing normally performed in the mainframe +work in this context, or had AM ought to think through adjustments? + +FLEISCHHAUER made the additional point that, as far as the text goes, AM +has gravitated towards SGML (he pointed to the boldface in the upper part +of the screen). Although extremely limited in its ability to translate +or interpret SGML, Personal Librarian will furnish both bold and italics +on screen; a fairly easy thing to do, but it is one of the ways in which +SGML is useful. + +Striking a balance between quantity and quality has been a major concern +of AM, with accuracy being one of the places where project staff have +felt that less than 100-percent accuracy was not unacceptable. +FLEISCHHAUER cited the example of the standard of the rekeying industry, +namely 99.95 percent; as one service bureau informed him, to go from +99.95 to 100 percent would double the cost. + +FLEISCHHAUER next demonstrated how AM furnishes users recourse to images, +and at the same time recalled LESK's pointed question concerning the +number of people who would look at those images and the number who would +work only with the text. If the implication of LESK's question was +sound, FLEISCHHAUER said, it raised the stakes for text accuracy and +reduced the value of the strategy for images. + +Contending that preservation is always a bugaboo, FLEISCHHAUER +demonstrated several images derived from a scan of a preservation +microfilm that AM had made. He awarded a grade of C at best, perhaps a +C minus or a C plus, for how well it worked out. Indeed, the matter of +learning if other people had better ideas about scanning in general, and, +in particular, scanning from microfilm, was one of the factors that drove +AM to attempt to think through the agenda for the Workshop. Skew, for +example, was one of the issues that AM in its ignorance had not reckoned +would prove so difficult. + +Further, the handling of images of the sort shown, in a desktop computer +environment, involved a considerable amount of zooming and scrolling. +Ultimately, AM staff feel that perhaps the paper copy that is printed out +might be the most useful one, but they remain uncertain as to how much +on-screen reading users will do. + +Returning to the text, FLEISCHHAUER asked viewers to imagine a person who +might be conducting a search in a full-text environment. With this +scenario, he proceeded to illustrate other features of Personal Librarian +that he considered helpful; for example, it provides the ability to +notice words as one reads. Clicking the "include" button on the bottom +of the search window pops the words that have been highlighted into the +search. Thus, a user can refine the search as he or she reads, +re-executing the search and continuing to find things in the quest for +materials. This software not only contains relevance ranking, Boolean +operators, and truncation, it also permits one to perform word algebra, +so to say, where one puts two or three words in parentheses and links +them with one Boolean operator and then a couple of words in another set +of parentheses and asks for things within so many words of others. + +Until they became acquainted recently with some of the work being done in +classics, the AM staff had not realized that a large number of the +projects that involve electronic texts were being done by people with a +profound interest in language and linguistics. Their search strategies +and thinking are oriented to those fields, as is shown in particular by +the Perseus example. As amateur historians, the AM staff were thinking +more of searching for concepts and ideas than for particular words. +Obviously, FLEISCHHAUER conceded, searching for concepts and ideas and +searching for words may be two rather closely related things. + +While displaying several images, FLEISCHHAUER observed that the Macintosh +prototype built by AM contains a greater diversity of formats. Echoing a +previous speaker, he said that it was easier to stitch things together in +the Macintosh, though it tended to be a little more anemic in search and +retrieval. AM, therefore, increasingly has been investigating +sophisticated retrieval engines in the IBM format. + +FLEISCHHAUER demonstrated several additional examples of the prototype +interfaces: One was AM's metaphor for the network future, in which a +kind of reading-room graphic suggests how one would be able to go around +to different materials. AM contains a large number of photographs in +analog video form worked up from a videodisc, which enable users to make +copies to print or incorporate in digital documents. A frame-grabber is +built into the system, making it possible to bring an image into a window +and digitize or print it out. + +FLEISCHHAUER next demonstrated sound recording, which included texts. +Recycled from a previous project, the collection included sixty 78-rpm +phonograph records of political speeches that were made during and +immediately after World War I. These constituted approximately three +hours of audio, as AM has digitized it, which occupy 150 megabytes on a +CD. Thus, they are considerably compressed. From the catalogue card, +FLEISCHHAUER proceeded to a transcript of a speech with the audio +available and with highlighted text following it as it played. +A photograph has been added and a transcription made. + +Considerable value has been added beyond what the Library of Congress +normally would do in cataloguing a sound recording, which raises several +questions for AM concerning where to draw lines about how much value it can +afford to add and at what point, perhaps, this becomes more than AM could +reasonably do or reasonably wish to do. FLEISCHHAUER also demonstrated +a motion picture. As FREEMAN had reported earlier, the motion picture +materials have proved the most popular, not surprisingly. This says more +about the medium, he thought, than about AM's presentation of it. + +Because AM's goal was to bring together things that could be used by +historians or by people who were curious about history, +turn-of-the-century footage seemed to represent the most appropriate +collections from the Library of Congress in motion pictures. These were +the very first films made by Thomas Edison's company and some others at +that time. The particular example illustrated was a Biograph film, +brought in with a frame-grabber into a window. A single videodisc +contains about fifty titles and pieces of film from that period, all of +New York City. Taken together, AM believes, they provide an interesting +documentary resource. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Using the frame-grabber in AM * Volume of material processed +and to be processed * Purpose of AM within LC * Cataloguing and the +nature of AM's material * SGML coding and the question of quality versus +quantity * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed FLEISCHHAUER's +presentation, several clarifications were made. + +AM is bringing in motion pictures from a videodisc. The frame-grabber +devices create a window on a computer screen, which permits users to +digitize a single frame of the movie or one of the photographs. It +produces a crude, rough-and-ready image that high school students can +incorporate into papers, and that has worked very nicely in this way. + +Commenting on FLEISCHHAUER's assertion that AM was looking more at +searching ideas than words, MYLONAS argued that without words an idea +does not exist. FLEISCHHAUER conceded that he ought to have articulated +his point more clearly. MYLONAS stated that they were in fact both +talking about the same thing. By searching for words and by forcing +people to focus on the word, the Perseus Project felt that they would get +them to the idea. The way one reviews results is tailored more to one +kind of user than another. + +Concerning the total volume of material that has been processed in this +way, AM at this point has in retrievable form seven or eight collections, +all of them photographic. In the Macintosh environment, for example, +there probably are 35,000-40,000 photographs. The sound recordings +number sixty items. The broadsides number about 300 items. There are +500 political cartoons in the form of drawings. The motion pictures, as +individual items, number sixty to seventy. + +AM also has a manuscript collection, the life history portion of one of +the federal project series, which will contain 2,900 individual +documents, all first-person narratives. AM has in process about 350 +African-American pamphlets, or about 12,000 printed pages for the period +1870-1910. Also in the works are some 4,000 panoramic photographs. AM +has recycled a fair amount of the work done by LC's Prints and +Photographs Division during the Library's optical disk pilot project in +the 1980s. For example, a special division of LC has tooled up and +thought through all the ramifications of electronic presentation of +photographs. Indeed, they are wheeling them out in great barrel loads. +The purpose of AM within the Library, it is hoped, is to catalyze several +of the other special collection divisions which have no particular +experience with, in some cases, mixed feelings about, an activity such as +AM. Moreover, in many cases the divisions may be characterized as not +only lacking experience in "electronifying" things but also in automated +cataloguing. MARC cataloguing as practiced in the United States is +heavily weighted toward the description of monograph and serial +materials, but is much thinner when one enters the world of manuscripts +and things that are held in the Library's music collection and other +units. In response to a comment by LESK, that AM's material is very +heavily photographic, and is so primarily because individual records have +been made for each photograph, FLEISCHHAUER observed that an item-level +catalog record exists, for example, for each photograph in the Detroit +Publishing collection of 25,000 pictures. In the case of the Federal +Writers Project, for which nearly 3,000 documents exist, representing +information from twenty-six different states, AM with the assistance of +Karen STUART of the Manuscript Division will attempt to find some way not +only to have a collection-level record but perhaps a MARC record for each +state, which will then serve as an umbrella for the 100-200 documents +that come under it. But that drama remains to be enacted. The AM staff +is conservative and clings to cataloguing, though of course visitors tout +artificial intelligence and neural networks in a manner that suggests that +perhaps one need not have cataloguing or that much of it could be put aside. + +The matter of SGML coding, FLEISCHHAUER conceded, returned the discussion +to the earlier treated question of quality versus quantity in the Library +of Congress. Of course, text conversion can be done with 100-percent +accuracy, but it means that when one's holdings are as vast as LC's only +a tiny amount will be exposed, whereas permitting lower levels of +accuracy can lead to exposing or sharing larger amounts, but with the +quality correspondingly impaired. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +TWOHIG * A contrary experience concerning electronic options * Volume of +material in the Washington papers and a suggestion of David Packard * +Implications of Packard's suggestion * Transcribing the documents for the +CD-ROM * Accuracy of transcriptions * The CD-ROM edition of the Founding +Fathers documents * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Finding encouragement in a comment of MICHELSON's from the morning +session--that numerous people in the humanities were choosing electronic +options to do their work--Dorothy TWOHIG, editor, The Papers of George +Washington, opened her illustrated talk by noting that her experience +with literary scholars and numerous people in editing was contrary to +MICHELSON's. TWOHIG emphasized literary scholars' complete ignorance of +the technological options available to them or their reluctance or, in +some cases, their downright hostility toward these options. + +After providing an overview of the five Founding Fathers projects +(Jefferson at Princeton, Franklin at Yale, John Adams at the +Massachusetts Historical Society, and Madison down the hall from her at +the University of Virginia), TWOHIG observed that the Washington papers, +like all of the projects, include both sides of the Washington +correspondence and deal with some 135,000 documents to be published with +extensive annotation in eighty to eighty-five volumes, a project that +will not be completed until well into the next century. Thus, it was +with considerable enthusiasm several years ago that the Washington Papers +Project (WPP) greeted David Packard's suggestion that the papers of the +Founding Fathers could be published easily and inexpensively, and to the +great benefit of American scholarship, via CD-ROM. + +In pragmatic terms, funding from the Packard Foundation would expedite +the transcription of thousands of documents waiting to be put on disk in +the WPP offices. Further, since the costs of collecting, editing, and +converting the Founding Fathers documents into letterpress editions were +running into the millions of dollars, and the considerable staffs +involved in all of these projects were devoting their careers to +producing the work, the Packard Foundation's suggestion had a +revolutionary aspect: Transcriptions of the entire corpus of the +Founding Fathers papers would be available on CD-ROM to public and +college libraries, even high schools, at a fraction of the cost-- +$100-$150 for the annual license fee--to produce a limited university +press run of 1,000 of each volume of the published papers at $45-$150 per +printed volume. Given the current budget crunch in educational systems +and the corresponding constraints on librarians in smaller institutions +who wish to add these volumes to their collections, producing the +documents on CD-ROM would likely open a greatly expanded audience for the +papers. TWOHIG stressed, however, that development of the Founding +Fathers CD-ROM is still in its infancy. Serious software problems remain +to be resolved before the material can be put into readable form. + +Funding from the Packard Foundation resulted in a major push to +transcribe the 75,000 or so documents of the Washington papers remaining +to be transcribed onto computer disks. Slides illustrated several of the +problems encountered, for example, the present inability of CD-ROM to +indicate the cross-outs (deleted material) in eighteenth century +documents. TWOHIG next described documents from various periods in the +eighteenth century that have been transcribed in chronological order and +delivered to the Packard offices in California, where they are converted +to the CD-ROM, a process that is expected to consume five years to +complete (that is, reckoning from David Packard's suggestion made several +years ago, until about July 1994). TWOHIG found an encouraging +indication of the project's benefits in the ongoing use made by scholars +of the search functions of the CD-ROM, particularly in reducing the time +spent in manually turning the pages of the Washington papers. + +TWOHIG next furnished details concerning the accuracy of transcriptions. +For instance, the insertion of thousands of documents on the CD-ROM +currently does not permit each document to be verified against the +original manuscript several times as in the case of documents that appear +in the published edition. However, the transcriptions receive a cursory +check for obvious typos, the misspellings of proper names, and other +errors from the WPP CD-ROM editor. Eventually, all documents that appear +in the electronic version will be checked by project editors. Although +this process has met with opposition from some of the editors on the +grounds that imperfect work may leave their offices, the advantages in +making this material available as a research tool outweigh fears about the +misspelling of proper names and other relatively minor editorial matters. + +Completion of all five Founding Fathers projects (i.e., retrievability +and searchability of all of the documents by proper names, alternate +spellings, or varieties of subjects) will provide one of the richest +sources of this size for the history of the United States in the latter +part of the eighteenth century. Further, publication on CD-ROM will +allow editors to include even minutiae, such as laundry lists, not +included in the printed volumes. + +It seems possible that the extensive annotation provided in the printed +volumes eventually will be added to the CD-ROM edition, pending +negotiations with the publishers of the papers. At the moment, the +Founding Fathers CD-ROM is accessible only on the IBYCUS, a computer +developed out of the Thesaurus Linguae Graecae project and designed for +the use of classical scholars. There are perhaps 400 IBYCUS computers in +the country, most of which are in university classics departments. +Ultimately, it is anticipated that the CD-ROM edition of the Founding +Fathers documents will run on any IBM-compatible or Macintosh computer +with a CD-ROM drive. Numerous changes in the software will also occur +before the project is completed. (Editor's note: an IBYCUS was +unavailable to demonstrate the CD-ROM.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Several additional features of WPP clarified * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Discussion following TWOHIG's presentation served to clarify several +additional features, including (1) that the project's primary +intellectual product consists in the electronic transcription of the +material; (2) that the text transmitted to the CD-ROM people is not +marked up; (3) that cataloging and subject-indexing of the material +remain to be worked out (though at this point material can be retrieved +by name); and (4) that because all the searching is done in the hardware, +the IBYCUS is designed to read a CD-ROM which contains only sequential +text files. Technically, it then becomes very easy to read the material +off and put it on another device. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LEBRON * Overview of the history of the joint project between AAAS and +OCLC * Several practices the on-line environment shares with traditional +publishing on hard copy * Several technical and behavioral barriers to +electronic publishing * How AAAS and OCLC arrived at the subject of +clinical trials * Advantages of the electronic format and other features +of OJCCT * An illustrated tour of the journal * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Maria LEBRON, managing editor, The Online Journal of Current Clinical +Trials (OJCCT), presented an illustrated overview of the history of the +joint project between the American Association for the Advancement of +Science (AAAS) and the Online Computer Library Center, Inc. (OCLC). The +joint venture between AAAS and OCLC owes its beginning to a +reorganization launched by the new chief executive officer at OCLC about +three years ago and combines the strengths of these two disparate +organizations. In short, OJCCT represents the process of scholarly +publishing on line. + +LEBRON next discussed several practices the on-line environment shares +with traditional publishing on hard copy--for example, peer review of +manuscripts--that are highly important in the academic world. LEBRON +noted in particular the implications of citation counts for tenure +committees and grants committees. In the traditional hard-copy +environment, citation counts are readily demonstrable, whereas the +on-line environment represents an ethereal medium to most academics. + +LEBRON remarked several technical and behavioral barriers to electronic +publishing, for instance, the problems in transmission created by special +characters or by complex graphics and halftones. In addition, she noted +economic limitations such as the storage costs of maintaining back issues +and market or audience education. + +Manuscripts cannot be uploaded to OJCCT, LEBRON explained, because it is +not a bulletin board or E-mail, forms of electronic transmission of +information that have created an ambience clouding people's understanding +of what the journal is attempting to do. OJCCT, which publishes +peer-reviewed medical articles dealing with the subject of clinical +trials, includes text, tabular material, and graphics, although at this +time it can transmit only line illustrations. + +Next, LEBRON described how AAAS and OCLC arrived at the subject of +clinical trials: It is 1) a highly statistical discipline that 2) does +not require halftones but can satisfy the needs of its audience with line +illustrations and graphic material, and 3) there is a need for the speedy +dissemination of high-quality research results. Clinical trials are +research activities that involve the administration of a test treatment +to some experimental unit in order to test its usefulness before it is +made available to the general population. LEBRON proceeded to give +additional information on OJCCT concerning its editor-in-chief, editorial +board, editorial content, and the types of articles it publishes +(including peer-reviewed research reports and reviews), as well as +features shared by other traditional hard-copy journals. + +Among the advantages of the electronic format are faster dissemination of +information, including raw data, and the absence of space constraints +because pages do not exist. (This latter fact creates an interesting +situation when it comes to citations.) Nor are there any issues. AAAS's +capacity to download materials directly from the journal to a +subscriber's printer, hard drive, or floppy disk helps ensure highly +accurate transcription. Other features of OJCCT include on-screen alerts +that allow linkage of subsequently published documents to the original +documents; on-line searching by subject, author, title, etc.; indexing of +every single word that appears in an article; viewing access to an +article by component (abstract, full text, or graphs); numbered +paragraphs to replace page counts; publication in Science every thirty +days of indexing of all articles published in the journal; +typeset-quality screens; and Hypertext links that enable subscribers to +bring up Medline abstracts directly without leaving the journal. + +After detailing the two primary ways to gain access to the journal, +through the OCLC network and Compuserv if one desires graphics or through +the Internet if just an ASCII file is desired, LEBRON illustrated the +speedy editorial process and the coding of the document using SGML tags +after it has been accepted for publication. She also gave an illustrated +tour of the journal, its search-and-retrieval capabilities in particular, +but also including problems associated with scanning in illustrations, +and the importance of on-screen alerts to the medical profession re +retractions or corrections, or more frequently, editorials, letters to +the editors, or follow-up reports. She closed by inviting the audience +to join AAAS on 1 July, when OJCCT was scheduled to go on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional features of OJCCT * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the lengthy discussion that followed LEBRON's presentation, these +points emerged: + + * The SGML text can be tailored as users wish. + + * All these articles have a fairly simple document definition. + + * Document-type definitions (DTDs) were developed and given to OJCCT + for coding. + + * No articles will be removed from the journal. (Because there are + no back issues, there are no lost issues either. Once a subscriber + logs onto the journal he or she has access not only to the currently + published materials, but retrospectively to everything that has been + published in it. Thus the table of contents grows bigger. The date + of publication serves to distinguish between currently published + materials and older materials.) + + * The pricing system for the journal resembles that for most medical + journals: for 1992, $95 for a year, plus telecommunications charges + (there are no connect time charges); for 1993, $110 for the + entire year for single users, though the journal can be put on a + local area network (LAN). However, only one person can access the + journal at a time. Site licenses may come in the future. + + * AAAS is working closely with colleagues at OCLC to display + mathematical equations on screen. + + * Without compromising any steps in the editorial process, the + technology has reduced the time lag between when a manuscript is + originally submitted and the time it is accepted; the review process + does not differ greatly from the standard six-to-eight weeks + employed by many of the hard-copy journals. The process still + depends on people. + + * As far as a preservation copy is concerned, articles will be + maintained on the computer permanently and subscribers, as part of + their subscription, will receive a microfiche-quality archival copy + of everything published during that year; in addition, reprints can + be purchased in much the same way as in a hard-copy environment. + Hard copies are prepared but are not the primary medium for the + dissemination of the information. + + * Because OJCCT is not yet on line, it is difficult to know how many + people would simply browse through the journal on the screen as + opposed to downloading the whole thing and printing it out; a mix of + both types of users likely will result. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PERSONIUS * Developments in technology over the past decade * The CLASS +Project * Advantages for technology and for the CLASS Project * +Developing a network application an underlying assumption of the project +* Details of the scanning process * Print-on-demand copies of books * +Future plans include development of a browsing tool * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Lynne PERSONIUS, assistant director, Cornell Information Technologies for +Scholarly Information Services, Cornell University, first commented on +the tremendous impact that developments in technology over the past ten +years--networking, in particular--have had on the way information is +handled, and how, in her own case, these developments have counterbalanced +Cornell's relative geographical isolation. Other significant technologies +include scanners, which are much more sophisticated than they were ten years +ago; mass storage and the dramatic savings that result from it in terms of +both space and money relative to twenty or thirty years ago; new and +improved printing technologies, which have greatly affected the distribution +of information; and, of course, digital technologies, whose applicability to +library preservation remains at issue. + +Given that context, PERSONIUS described the College Library Access and +Storage System (CLASS) Project, a library preservation project, +primarily, and what has been accomplished. Directly funded by the +Commission on Preservation and Access and by the Xerox Corporation, which +has provided a significant amount of hardware, the CLASS Project has been +working with a development team at Xerox to develop a software +application tailored to library preservation requirements. Within +Cornell, participants in the project have been working jointly with both +library and information technologies. The focus of the project has been +on reformatting and saving books that are in brittle condition. +PERSONIUS showed Workshop participants a brittle book, and described how +such books were the result of developments in papermaking around the +beginning of the Industrial Revolution. The papermaking process was +changed so that a significant amount of acid was introduced into the +actual paper itself, which deteriorates as it sits on library shelves. + +One of the advantages for technology and for the CLASS Project is that +the information in brittle books is mostly out of copyright and thus +offers an opportunity to work with material that requires library +preservation, and to create and work on an infrastructure to save the +material. Acknowledging the familiarity of those working in preservation +with this information, PERSONIUS noted that several things are being +done: the primary preservation technology used today is photocopying of +brittle material. Saving the intellectual content of the material is the +main goal. With microfilm copy, the intellectual content is preserved on +the assumption that in the future the image can be reformatted in any +other way that then exists. + +An underlying assumption of the CLASS Project from the beginning was +that it would develop a network application. Project staff scan books +at a workstation located in the library, near the brittle material. +An image-server filing system is located at a distance from that +workstation, and a printer is located in another building. All of the +materials digitized and stored on the image-filing system are cataloged +in the on-line catalogue. In fact, a record for each of these electronic +books is stored in the RLIN database so that a record exists of what is +in the digital library throughout standard catalogue procedures. In the +future, researchers working from their own workstations in their offices, +or their networks, will have access--wherever they might be--through a +request server being built into the new digital library. A second +assumption is that the preferred means of finding the material will be by +looking through a catalogue. PERSONIUS described the scanning process, +which uses a prototype scanner being developed by Xerox and which scans a +very high resolution image at great speed. Another significant feature, +because this is a preservation application, is the placing of the pages +that fall apart one for one on the platen. Ordinarily, a scanner could +be used with some sort of a document feeder, but because of this +application that is not feasible. Further, because CLASS is a +preservation application, after the paper replacement is made there, a +very careful quality control check is performed. An original book is +compared to the printed copy and verification is made, before proceeding, +that all of the image, all of the information, has been captured. Then, +a new library book is produced: The printed images are rebound by a +commercial binder and a new book is returned to the shelf. +Significantly, the books returned to the library shelves are beautiful +and useful replacements on acid-free paper that should last a long time, +in effect, the equivalent of preservation photocopies. Thus, the project +has a library of digital books. In essence, CLASS is scanning and +storing books as 600 dot-per-inch bit-mapped images, compressed using +Group 4 CCITT (i.e., the French acronym for International Consultative +Committee for Telegraph and Telephone) compression. They are stored as +TIFF files on an optical filing system that is composed of a database +used for searching and locating the books and an optical jukebox that +stores 64 twelve-inch platters. A very-high-resolution printed copy of +these books at 600 dots per inch is created, using a Xerox DocuTech +printer to make the paper replacements on acid-free paper. + +PERSONIUS maintained that the CLASS Project presents an opportunity to +introduce people to books as digital images by using a paper medium. +Books are returned to the shelves while people are also given the ability +to print on demand--to make their own copies of books. (PERSONIUS +distributed copies of an engineering journal published by engineering +students at Cornell around 1900 as an example of what a print-on-demand +copy of material might be like. This very cheap copy would be available +to people to use for their own research purposes and would bridge the gap +between an electronic work and the paper that readers like to have.) +PERSONIUS then attempted to illustrate a very early prototype of +networked access to this digital library. Xerox Corporation has +developed a prototype of a view station that can send images across the +network to be viewed. + +The particular library brought down for demonstration contained two +mathematics books. CLASS is developing and will spend the next year +developing an application that allows people at workstations to browse +the books. Thus, CLASS is developing a browsing tool, on the assumption +that users do not want to read an entire book from a workstation, but +would prefer to be able to look through and decide if they would like to +have a printed copy of it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Re retrieval software * "Digital file copyright" * Scanning +rate during production * Autosegmentation * Criteria employed in +selecting books for scanning * Compression and decompression of images * +OCR not precluded * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed her presentation, +PERSONIUS made these additional points: + + * Re retrieval software, Cornell is developing a Unix-based server + as well as clients for the server that support multiple platforms + (Macintosh, IBM and Sun workstations), in the hope that people from + any of those platforms will retrieve books; a further operating + assumption is that standard interfaces will be used as much as + possible, where standards can be put in place, because CLASS + considers this retrieval software a library application and would + like to be able to look at material not only at Cornell but at other + institutions. + + * The phrase "digital file copyright by Cornell University" was + added at the advice of Cornell's legal staff with the caveat that it + probably would not hold up in court. Cornell does not want people + to copy its books and sell them but would like to keep them + available for use in a library environment for library purposes. + + * In production the scanner can scan about 300 pages per hour, + capturing 600 dots per inch. + + * The Xerox software has filters to scan halftone material and avoid + the moire patterns that occur when halftone material is scanned. + Xerox has been working on hardware and software that would enable + the scanner itself to recognize this situation and deal with it + appropriately--a kind of autosegmentation that would enable the + scanner to handle halftone material as well as text on a single page. + + * The books subjected to the elaborate process described above were + selected because CLASS is a preservation project, with the first 500 + books selected coming from Cornell's mathematics collection, because + they were still being heavily used and because, although they were + in need of preservation, the mathematics library and the mathematics + faculty were uncomfortable having them microfilmed. (They wanted a + printed copy.) Thus, these books became a logical choice for this + project. Other books were chosen by the project's selection committees + for experiments with the technology, as well as to meet a demand or need. + + * Images will be decompressed before they are sent over the line; at + this time they are compressed and sent to the image filing system + and then sent to the printer as compressed images; they are returned + to the workstation as compressed 600-dpi images and the workstation + decompresses and scales them for display--an inefficient way to + access the material though it works quite well for printing and + other purposes. + + * CLASS is also decompressing on Macintosh and IBM, a slow process + right now. Eventually, compression and decompression will take + place on an image conversion server. Trade-offs will be made, based + on future performance testing, concerning where the file is + compressed and what resolution image is sent. + + * OCR has not been precluded; images are being stored that have been + scanned at a high resolution, which presumably would suit them well + to an OCR process. Because the material being scanned is about 100 + years old and was printed with less-than-ideal technologies, very + early and preliminary tests have not produced good results. But the + project is capturing an image that is of sufficient resolution to be + subjected to OCR in the future. Moreover, the system architecture + and the system plan have a logical place to store an OCR image if it + has been captured. But that is not being done now. + + ****** + +SESSION III. DISTRIBUTION, NETWORKS, AND NETWORKING: OPTIONS FOR +DISSEMINATION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZICH * Issues pertaining to CD-ROMs * Options for publishing in CD-ROM * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Robert ZICH, special assistant to the associate librarian for special +projects, Library of Congress, and moderator of this session, first noted +the blessed but somewhat awkward circumstance of having four very +distinguished people representing networks and networking or at least +leaning in that direction, while lacking anyone to speak from the +strongest possible background in CD-ROMs. ZICH expressed the hope that +members of the audience would join the discussion. He stressed the +subtitle of this particular session, "Options for Dissemination," and, +concerning CD-ROMs, the importance of determining when it would be wise +to consider dissemination in CD-ROM versus networks. A shopping list of +issues pertaining to CD-ROMs included: the grounds for selecting +commercial publishers, and in-house publication where possible versus +nonprofit or government publication. A similar list for networks +included: determining when one should consider dissemination through a +network, identifying the mechanisms or entities that exist to place items +on networks, identifying the pool of existing networks, determining how a +producer would choose between networks, and identifying the elements of +a business arrangement in a network. + +Options for publishing in CD-ROM: an outside publisher versus +self-publication. If an outside publisher is used, it can be nonprofit, +such as the Government Printing Office (GPO) or the National Technical +Information Service (NTIS), in the case of government. The pros and cons +associated with employing an outside publisher are obvious. Among the +pros, there is no trouble getting accepted. One pays the bill and, in +effect, goes one's way. Among the cons, when one pays an outside +publisher to perform the work, that publisher will perform the work it is +obliged to do, but perhaps without the production expertise and skill in +marketing and dissemination that some would seek. There is the body of +commercial publishers that do possess that kind of expertise in +distribution and marketing but that obviously are selective. In +self-publication, one exercises full control, but then one must handle +matters such as distribution and marketing. Such are some of the options +for publishing in the case of CD-ROM. + +In the case of technical and design issues, which are also important, +there are many matters which many at the Workshop already knew a good +deal about: retrieval system requirements and costs, what to do about +images, the various capabilities and platforms, the trade-offs between +cost and performance, concerns about local-area networkability, +interoperability, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LYNCH * Creating networked information is different from using networks +as an access or dissemination vehicle * Networked multimedia on a large +scale does not yet work * Typical CD-ROM publication model a two-edged +sword * Publishing information on a CD-ROM in the present world of +immature standards * Contrast between CD-ROM and network pricing * +Examples demonstrated earlier in the day as a set of insular information +gems * Paramount need to link databases * Layering to become increasingly +necessary * Project NEEDS and the issues of information reuse and active +versus passive use * X-Windows as a way of differentiating between +network access and networked information * Barriers to the distribution +of networked multimedia information * Need for good, real-time delivery +protocols * The question of presentation integrity in client-server +computing in the academic world * Recommendations for producing multimedia ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Clifford LYNCH, director, Library Automation, University of California, +opened his talk with the general observation that networked information +constituted a difficult and elusive topic because it is something just +starting to develop and not yet fully understood. LYNCH contended that +creating genuinely networked information was different from using +networks as an access or dissemination vehicle and was more sophisticated +and more subtle. He invited the members of the audience to extrapolate, +from what they heard about the preceding demonstration projects, to what +sort of a world of electronics information--scholarly, archival, +cultural, etc.--they wished to end up with ten or fifteen years from now. +LYNCH suggested that to extrapolate directly from these projects would +produce unpleasant results. + +Putting the issue of CD-ROM in perspective before getting into +generalities on networked information, LYNCH observed that those engaged +in multimedia today who wish to ship a product, so to say, probably do +not have much choice except to use CD-ROM: networked multimedia on a +large scale basically does not yet work because the technology does not +exist. For example, anybody who has tried moving images around over the +Internet knows that this is an exciting touch-and-go process, a +fascinating and fertile area for experimentation, research, and +development, but not something that one can become deeply enthusiastic +about committing to production systems at this time. + +This situation will change, LYNCH said. He differentiated CD-ROM from +the practices that have been followed up to now in distributing data on +CD-ROM. For LYNCH the problem with CD-ROM is not its portability or its +slowness but the two-edged sword of having the retrieval application and +the user interface inextricably bound up with the data, which is the +typical CD-ROM publication model. It is not a case of publishing data +but of distributing a typically stand-alone, typically closed system, +all--software, user interface, and data--on a little disk. Hence, all +the between-disk navigational issues as well as the impossibility in most +cases of integrating data on one disk with that on another. Most CD-ROM +retrieval software does not network very gracefully at present. However, +in the present world of immature standards and lack of understanding of +what network information is or what the ground rules are for creating or +using it, publishing information on a CD-ROM does add value in a very +real sense. + +LYNCH drew a contrast between CD-ROM and network pricing and in doing so +highlighted something bizarre in information pricing. A large +institution such as the University of California has vendors who will +offer to sell information on CD-ROM for a price per year in four digits, +but for the same data (e.g., an abstracting and indexing database) on +magnetic tape, regardless of how many people may use it concurrently, +will quote a price in six digits. + +What is packaged with the CD-ROM in one sense adds value--a complete +access system, not just raw, unrefined information--although it is not +generally perceived that way. This is because the access software, +although it adds value, is viewed by some people, particularly in the +university environment where there is a very heavy commitment to +networking, as being developed in the wrong direction. + +Given that context, LYNCH described the examples demonstrated as a set of +insular information gems--Perseus, for example, offers nicely linked +information, but would be very difficult to integrate with other +databases, that is, to link together seamlessly with other source files +from other sources. It resembles an island, and in this respect is +similar to numerous stand-alone projects that are based on videodiscs, +that is, on the single-workstation concept. + +As scholarship evolves in a network environment, the paramount need will +be to link databases. We must link personal databases to public +databases, to group databases, in fairly seamless ways--which is +extremely difficult in the environments under discussion with copies of +databases proliferating all over the place. + +The notion of layering also struck LYNCH as lurking in several of the +projects demonstrated. Several databases in a sense constitute +information archives without a significant amount of navigation built in. +Educators, critics, and others will want a layered structure--one that +defines or links paths through the layers to allow users to reach +specific points. In LYNCH's view, layering will become increasingly +necessary, and not just within a single resource but across resources +(e.g., tracing mythology and cultural themes across several classics +databases as well as a database of Renaissance culture). This ability to +organize resources, to build things out of multiple other things on the +network or select pieces of it, represented for LYNCH one of the key +aspects of network information. + +Contending that information reuse constituted another significant issue, +LYNCH commended to the audience's attention Project NEEDS (i.e., National +Engineering Education Delivery System). This project's objective is to +produce a database of engineering courseware as well as the components +that can be used to develop new courseware. In a number of the existing +applications, LYNCH said, the issue of reuse (how much one can take apart +and reuse in other applications) was not being well considered. He also +raised the issue of active versus passive use, one aspect of which is +how much information will be manipulated locally by users. Most people, +he argued, may do a little browsing and then will wish to print. LYNCH +was uncertain how these resources would be used by the vast majority of +users in the network environment. + +LYNCH next said a few words about X-Windows as a way of differentiating +between network access and networked information. A number of the +applications demonstrated at the Workshop could be rewritten to use X +across the network, so that one could run them from any X-capable device- +-a workstation, an X terminal--and transact with a database across the +network. Although this opens up access a little, assuming one has enough +network to handle it, it does not provide an interface to develop a +program that conveniently integrates information from multiple databases. +X is a viewing technology that has limits. In a real sense, it is just a +graphical version of remote log-in across the network. X-type applications +represent only one step in the progression towards real access. + +LYNCH next discussed barriers to the distribution of networked multimedia +information. The heart of the problem is a lack of standards to provide +the ability for computers to talk to each other, retrieve information, +and shuffle it around fairly casually. At the moment, little progress is +being made on standards for networked information; for example, present +standards do not cover images, digital voice, and digital video. A +useful tool kit of exchange formats for basic texts is only now being +assembled. The synchronization of content streams (i.e., synchronizing a +voice track to a video track, establishing temporal relations between +different components in a multimedia object) constitutes another issue +for networked multimedia that is just beginning to receive attention. + +Underlying network protocols also need some work; good, real-time +delivery protocols on the Internet do not yet exist. In LYNCH's view, +highly important in this context is the notion of networked digital +object IDs, the ability of one object on the network to point to another +object (or component thereof) on the network. Serious bandwidth issues +also exist. LYNCH was uncertain if billion-bit-per-second networks would +prove sufficient if numerous people ran video in parallel. + +LYNCH concluded by offering an issue for database creators to consider, +as well as several comments about what might constitute good trial +multimedia experiments. In a networked information world the database +builder or service builder (publisher) does not exercise the same +extensive control over the integrity of the presentation; strange +programs "munge" with one's data before the user sees it. Serious +thought must be given to what guarantees integrity of presentation. Part +of that is related to where one draws the boundaries around a networked +information service. This question of presentation integrity in +client-server computing has not been stressed enough in the academic +world, LYNCH argued, though commercial service providers deal with it +regularly. + +Concerning multimedia, LYNCH observed that good multimedia at the moment +is hideously expensive to produce. He recommended producing multimedia +with either very high sale value, or multimedia with a very long life +span, or multimedia that will have a very broad usage base and whose +costs therefore can be amortized among large numbers of users. In this +connection, historical and humanistically oriented material may be a good +place to start, because it tends to have a longer life span than much of +the scientific material, as well as a wider user base. LYNCH noted, for +example, that American Memory fits many of the criteria outlined. He +remarked the extensive discussion about bringing the Internet or the +National Research and Education Network (NREN) into the K-12 environment +as a way of helping the American educational system. + +LYNCH closed by noting that the kinds of applications demonstrated struck +him as excellent justifications of broad-scale networking for K-12, but +that at this time no "killer" application exists to mobilize the K-12 +community to obtain connectivity. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Dearth of genuinely interesting applications on the network +a slow-changing situation * The issue of the integrity of presentation in +a networked environment * Several reasons why CD-ROM software does not +network * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period that followed LYNCH's presentation, several +additional points were made. + +LYNCH reiterated even more strongly his contention that, historically, +once one goes outside high-end science and the group of those who need +access to supercomputers, there is a great dearth of genuinely +interesting applications on the network. He saw this situation changing +slowly, with some of the scientific databases and scholarly discussion +groups and electronic journals coming on as well as with the availability +of Wide Area Information Servers (WAIS) and some of the databases that +are being mounted there. However, many of those things do not seem to +have piqued great popular interest. For instance, most high school +students of LYNCH's acquaintance would not qualify as devotees of serious +molecular biology. + +Concerning the issue of the integrity of presentation, LYNCH believed +that a couple of information providers have laid down the law at least on +certain things. For example, his recollection was that the National +Library of Medicine feels strongly that one needs to employ the +identifier field if he or she is to mount a database commercially. The +problem with a real networked environment is that one does not know who +is reformatting and reprocessing one's data when one enters a client +server mode. It becomes anybody's guess, for example, if the network +uses a Z39.50 server, or what clients are doing with one's data. A data +provider can say that his contract will only permit clients to have +access to his data after he vets them and their presentation and makes +certain it suits him. But LYNCH held out little expectation that the +network marketplace would evolve in that way, because it required too +much prior negotiation. + +CD-ROM software does not network for a variety of reasons, LYNCH said. +He speculated that CD-ROM publishers are not eager to have their products +really hook into wide area networks, because they fear it will make their +data suppliers nervous. Moreover, until relatively recently, one had to +be rather adroit to run a full TCP/IP stack plus applications on a +PC-size machine, whereas nowadays it is becoming easier as PCs grow +bigger and faster. LYNCH also speculated that software providers had not +heard from their customers until the last year or so, or had not heard +from enough of their customers. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BESSER * Implications of disseminating images on the network; planning +the distribution of multimedia documents poses two critical +implementation problems * Layered approach represents the way to deal +with users' capabilities * Problems in platform design; file size and its +implications for networking * Transmission of megabyte size images +impractical * Compression and decompression at the user's end * Promising +trends for compression * A disadvantage of using X-Windows * A project at +the Smithsonian that mounts images on several networks * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Howard BESSER, School of Library and Information Science, University of +Pittsburgh, spoke primarily about multimedia, focusing on images and the +broad implications of disseminating them on the network. He argued that +planning the distribution of multimedia documents posed two critical +implementation problems, which he framed in the form of two questions: +1) What platform will one use and what hardware and software will users +have for viewing of the material? and 2) How can one deliver a +sufficiently robust set of information in an accessible format in a +reasonable amount of time? Depending on whether network or CD-ROM is the +medium used, this question raises different issues of storage, +compression, and transmission. + +Concerning the design of platforms (e.g., sound, gray scale, simple +color, etc.) and the various capabilities users may have, BESSER +maintained that a layered approach was the way to deal with users' +capabilities. A result would be that users with less powerful +workstations would simply have less functionality. He urged members of +the audience to advocate standards and accompanying software that handle +layered functionality across a wide variety of platforms. + +BESSER also addressed problems in platform design, namely, deciding how +large a machine to design for situations when the largest number of users +have the lowest level of the machine, and one desires higher +functionality. BESSER then proceeded to the question of file size and +its implications for networking. He discussed still images in the main. +For example, a digital color image that fills the screen of a standard +mega-pel workstation (Sun or Next) will require one megabyte of storage +for an eight-bit image or three megabytes of storage for a true color or +twenty-four-bit image. Lossless compression algorithms (that is, +computational procedures in which no data is lost in the process of +compressing [and decompressing] an image--the exact bit-representation is +maintained) might bring storage down to a third of a megabyte per image, +but not much further than that. The question of size makes it difficult +to fit an appropriately sized set of these images on a single disk or to +transmit them quickly enough on a network. + +With these full screen mega-pel images that constitute a third of a +megabyte, one gets 1,000-3,000 full-screen images on a one-gigabyte disk; +a standard CD-ROM represents approximately 60 percent of that. Storing +images the size of a PC screen (just 8 bit color) increases storage +capacity to 4,000-12,000 images per gigabyte; 60 percent of that gives +one the size of a CD-ROM, which in turn creates a major problem. One +cannot have full-screen, full-color images with lossless compression; one +must compress them or use a lower resolution. For megabyte-size images, +anything slower than a T-1 speed is impractical. For example, on a +fifty-six-kilobaud line, it takes three minutes to transfer a +one-megabyte file, if it is not compressed; and this speed assumes ideal +circumstances (no other user contending for network bandwidth). Thus, +questions of disk access, remote display, and current telephone +connection speed make transmission of megabyte-size images impractical. + +BESSER then discussed ways to deal with these large images, for example, +compression and decompression at the user's end. In this connection, the +issues of how much one is willing to lose in the compression process and +what image quality one needs in the first place are unknown. But what is +known is that compression entails some loss of data. BESSER urged that +more studies be conducted on image quality in different situations, for +example, what kind of images are needed for what kind of disciplines, and +what kind of image quality is needed for a browsing tool, an intermediate +viewing tool, and archiving. + +BESSER remarked two promising trends for compression: from a technical +perspective, algorithms that use what is called subjective redundancy +employ principles from visual psycho-physics to identify and remove +information from the image that the human eye cannot perceive; from an +interchange and interoperability perspective, the JPEG (i.e., Joint +Photographic Experts Group, an ISO standard) compression algorithms also +offer promise. These issues of compression and decompression, BESSER +argued, resembled those raised earlier concerning the design of different +platforms. Gauging the capabilities of potential users constitutes a +primary goal. BESSER advocated layering or separating the images from +the applications that retrieve and display them, to avoid tying them to +particular software. + +BESSER detailed several lessons learned from his work at Berkeley with +Imagequery, especially the advantages and disadvantages of using +X-Windows. In the latter category, for example, retrieval is tied +directly to one's data, an intolerable situation in the long run on a +networked system. Finally, BESSER described a project of Jim Wallace at +the Smithsonian Institution, who is mounting images in a extremely +rudimentary way on the Compuserv and Genie networks and is preparing to +mount them on America On Line. Although the average user takes over +thirty minutes to download these images (assuming a fairly fast modem), +nevertheless, images have been downloaded 25,000 times. + +BESSER concluded his talk with several comments on the business +arrangement between the Smithsonian and Compuserv. He contended that not +enough is known concerning the value of images. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating digitized photographic collections nearly +impossible except with large organizations like museums * Need for study +to determine quality of images users will tolerate * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief exchange between LESK and BESSER that followed, several +clarifications emerged. + +LESK argued that the photographers were far ahead of BESSER: It is +almost impossible to create such digitized photographic collections +except with large organizations like museums, because all the +photographic agencies have been going crazy about this and will not sign +licensing agreements on any sort of reasonable terms. LESK had heard +that National Geographic, for example, had tried to buy the right to use +some image in some kind of educational production for $100 per image, but +the photographers will not touch it. They want accounting and payment +for each use, which cannot be accomplished within the system. BESSER +responded that a consortium of photographers, headed by a former National +Geographic photographer, had started assembling its own collection of +electronic reproductions of images, with the money going back to the +cooperative. + +LESK contended that BESSER was unnecessarily pessimistic about multimedia +images, because people are accustomed to low-quality images, particularly +from video. BESSER urged the launching of a study to determine what +users would tolerate, what they would feel comfortable with, and what +absolutely is the highest quality they would ever need. Conceding that +he had adopted a dire tone in order to arouse people about the issue, +BESSER closed on a sanguine note by saying that he would not be in this +business if he did not think that things could be accomplished. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LARSEN * Issues of scalability and modularity * Geometric growth of the +Internet and the role played by layering * Basic functions sustaining +this growth * A library's roles and functions in a network environment * +Effects of implementation of the Z39.50 protocol for information +retrieval on the library system * The trade-off between volumes of data +and its potential usage * A snapshot of current trends * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Ronald LARSEN, associate director for information technology, University +of Maryland at College Park, first addressed the issues of scalability +and modularity. He noted the difficulty of anticipating the effects of +orders-of-magnitude growth, reflecting on the twenty years of experience +with the Arpanet and Internet. Recalling the day's demonstrations of +CD-ROM and optical disk material, he went on to ask if the field has yet +learned how to scale new systems to enable delivery and dissemination +across large-scale networks. + +LARSEN focused on the geometric growth of the Internet from its inception +circa 1969 to the present, and the adjustments required to respond to +that rapid growth. To illustrate the issue of scalability, LARSEN +considered computer networks as including three generic components: +computers, network communication nodes, and communication media. Each +component scales (e.g., computers range from PCs to supercomputers; +network nodes scale from interface cards in a PC through sophisticated +routers and gateways; and communication media range from 2,400-baud +dial-up facilities through 4.5-Mbps backbone links, and eventually to +multigigabit-per-second communication lines), and architecturally, the +components are organized to scale hierarchically from local area networks +to international-scale networks. Such growth is made possible by +building layers of communication protocols, as BESSER pointed out. +By layering both physically and logically, a sense of scalability is +maintained from local area networks in offices, across campuses, through +bridges, routers, campus backbones, fiber-optic links, etc., up into +regional networks and ultimately into national and international +networks. + +LARSEN then illustrated the geometric growth over a two-year period-- +through September 1991--of the number of networks that comprise the +Internet. This growth has been sustained largely by the availability of +three basic functions: electronic mail, file transfer (ftp), and remote +log-on (telnet). LARSEN also reviewed the growth in the kind of traffic +that occurs on the network. Network traffic reflects the joint contributions +of a larger population of users and increasing use per user. Today one sees +serious applications involving moving images across the network--a rarity +ten years ago. LARSEN recalled and concurred with BESSER's main point +that the interesting problems occur at the application level. + +LARSEN then illustrated a model of a library's roles and functions in a +network environment. He noted, in particular, the placement of on-line +catalogues onto the network and patrons obtaining access to the library +increasingly through local networks, campus networks, and the Internet. +LARSEN supported LYNCH's earlier suggestion that we need to address +fundamental questions of networked information in order to build +environments that scale in the information sense as well as in the +physical sense. + +LARSEN supported the role of the library system as the access point into +the nation's electronic collections. Implementation of the Z39.50 +protocol for information retrieval would make such access practical and +feasible. For example, this would enable patrons in Maryland to search +California libraries, or other libraries around the world that are +conformant with Z39.50 in a manner that is familiar to University of +Maryland patrons. This client-server model also supports moving beyond +secondary content into primary content. (The notion of how one links +from secondary content to primary content, LARSEN said, represents a +fundamental problem that requires rigorous thought.) After noting +numerous network experiments in accessing full-text materials, including +projects supporting the ordering of materials across the network, LARSEN +revisited the issue of transmitting high-density, high-resolution color +images across the network and the large amounts of bandwidth they +require. He went on to address the bandwidth and synchronization +problems inherent in sending full-motion video across the network. + +LARSEN illustrated the trade-off between volumes of data in bytes or +orders of magnitude and the potential usage of that data. He discussed +transmission rates (particularly, the time it takes to move various forms +of information), and what one could do with a network supporting +multigigabit-per-second transmission. At the moment, the network +environment includes a composite of data-transmission requirements, +volumes and forms, going from steady to bursty (high-volume) and from +very slow to very fast. This aggregate must be considered in the design, +construction, and operation of multigigabyte networks. + +LARSEN's objective is to use the networks and library systems now being +constructed to increase access to resources wherever they exist, and +thus, to evolve toward an on-line electronic virtual library. + +LARSEN concluded by offering a snapshot of current trends: continuing +geometric growth in network capacity and number of users; slower +development of applications; and glacial development and adoption of +standards. The challenge is to design and develop each new application +system with network access and scalability in mind. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BROWNRIGG * Access to the Internet cannot be taken for granted * Packet +radio and the development of MELVYL in 1980-81 in the Division of Library +Automation at the University of California * Design criteria for packet +radio * A demonstration project in San Diego and future plans * Spread +spectrum * Frequencies at which the radios will run and plans to +reimplement the WAIS server software in the public domain * Need for an +infrastructure of radios that do not move around * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Edwin BROWNRIGG, executive director, Memex Research Institute, first +polled the audience in order to seek out regular users of the Internet as +well as those planning to use it some time in the future. With nearly +everybody in the room falling into one category or the other, BROWNRIGG +made a point re access, namely that numerous individuals, especially those +who use the Internet every day, take for granted their access to it, the +speeds with which they are connected, and how well it all works. +However, as BROWNRIGG discovered between 1987 and 1989 in Australia, +if one wants access to the Internet but cannot afford it or has some +physical boundary that prevents her or him from gaining access, it can +be extremely frustrating. He suggested that because of economics and +physical barriers we were beginning to create a world of haves and have-nots +in the process of scholarly communication, even in the United States. + +BROWNRIGG detailed the development of MELVYL in academic year 1980-81 in +the Division of Library Automation at the University of California, in +order to underscore the issue of access to the system, which at the +outset was extremely limited. In short, the project needed to build a +network, which at that time entailed use of satellite technology, that is, +putting earth stations on campus and also acquiring some terrestrial links +from the State of California's microwave system. The installation of +satellite links, however, did not solve the problem (which actually +formed part of a larger problem involving politics and financial resources). +For while the project team could get a signal onto a campus, it had no means +of distributing the signal throughout the campus. The solution involved +adopting a recent development in wireless communication called packet radio, +which combined the basic notion of packet-switching with radio. The project +used this technology to get the signal from a point on campus where it +came down, an earth station for example, into the libraries, because it +found that wiring the libraries, especially the older marble buildings, +would cost $2,000-$5,000 per terminal. + +BROWNRIGG noted that, ten years ago, the project had neither the public +policy nor the technology that would have allowed it to use packet radio +in any meaningful way. Since then much had changed. He proceeded to +detail research and development of the technology, how it is being +deployed in California, and what direction he thought it would take. +The design criteria are to produce a high-speed, one-time, low-cost, +high-quality, secure, license-free device (packet radio) that one can +plug in and play today, forget about it, and have access to the Internet. +By high speed, BROWNRIGG meant 1 megabyte and 1.5 megabytes. Those units +have been built, he continued, and are in the process of being +type-certified by an independent underwriting laboratory so that they can +be type-licensed by the Federal Communications Commission. As is the +case with citizens band, one will be able to purchase a unit and not have +to worry about applying for a license. + +The basic idea, BROWNRIGG elaborated, is to take high-speed radio data +transmission and create a backbone network that at certain strategic +points in the network will "gateway" into a medium-speed packet radio +(i.e., one that runs at 38.4 kilobytes), so that perhaps by 1994-1995 +people, like those in the audience for the price of a VCR could purchase +a medium-speed radio for the office or home, have full network connectivity +to the Internet, and partake of all its services, with no need for an FCC +license and no regular bill from the local common carrier. BROWNRIGG +presented several details of a demonstration project currently taking +place in San Diego and described plans, pending funding, to install a +full-bore network in the San Francisco area. This network will have 600 +nodes running at backbone speeds, and 100 of these nodes will be libraries, +which in turn will be the gateway ports to the 38.4 kilobyte radios that +will give coverage for the neighborhoods surrounding the libraries. + +BROWNRIGG next explained Part 15.247, a new rule within Title 47 of the +Code of Federal Regulations enacted by the FCC in 1985. This rule +challenged the industry, which has only now risen to the occasion, to +build a radio that would run at no more than one watt of output power and +use a fairly exotic method of modulating the radio wave called spread +spectrum. Spread spectrum in fact permits the building of networks so +that numerous data communications can occur simultaneously, without +interfering with each other, within the same wide radio channel. + +BROWNRIGG explained that the frequencies at which the radios would run +are very short wave signals. They are well above standard microwave and +radar. With a radio wave that small, one watt becomes a tremendous punch +per bit and thus makes transmission at reasonable speed possible. In +order to minimize the potential for congestion, the project is +undertaking to reimplement software which has been available in the +networking business and is taken for granted now, for example, TCP/IP, +routing algorithms, bridges, and gateways. In addition, the project +plans to take the WAIS server software in the public domain and +reimplement it so that one can have a WAIS server on a Mac instead of a +Unix machine. The Memex Research Institute believes that libraries, in +particular, will want to use the WAIS servers with packet radio. This +project, which has a team of about twelve people, will run through 1993 +and will include the 100 libraries already mentioned as well as other +professionals such as those in the medical profession, engineering, and +law. Thus, the need is to create an infrastructure of radios that do not +move around, which, BROWNRIGG hopes, will solve a problem not only for +libraries but for individuals who, by and large today, do not have access +to the Internet from their homes and offices. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Project operating frequencies * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During a brief discussion period, which also concluded the day's +proceedings, BROWNRIGG stated that the project was operating in four +frequencies. The slow speed is operating at 435 megahertz, and it would +later go up to 920 megahertz. With the high-speed frequency, the +one-megabyte radios will run at 2.4 gigabits, and 1.5 will run at 5.7. +At 5.7, rain can be a factor, but it would have to be tropical rain, +unlike what falls in most parts of the United States. + + ****** + +SESSION IV. IMAGE CAPTURE, TEXT CAPTURE, OVERVIEW OF TEXT AND + IMAGE STORAGE FORMATS + +William HOOTON, vice president of operations, I-NET, moderated this session. + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +KENNEY * Factors influencing development of CXP * Advantages of using +digital technology versus photocopy and microfilm * A primary goal of +CXP; publishing challenges * Characteristics of copies printed * Quality +of samples achieved in image capture * Several factors to be considered +in choosing scanning * Emphasis of CXP on timely and cost-effective +production of black-and-white printed facsimiles * Results of producing +microfilm from digital files * Advantages of creating microfilm * Details +concerning production * Costs * Role of digital technology in library +preservation * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Anne KENNEY, associate director, Department of Preservation and +Conservation, Cornell University, opened her talk by observing that the +Cornell Xerox Project (CXP) has been guided by the assumption that the +ability to produce printed facsimiles or to replace paper with paper +would be important, at least for the present generation of users and +equipment. She described three factors that influenced development of +the project: 1) Because the project has emphasized the preservation of +deteriorating brittle books, the quality of what was produced had to be +sufficiently high to return a paper replacement to the shelf. CXP was +only interested in using: 2) a system that was cost-effective, which +meant that it had to be cost-competitive with the processes currently +available, principally photocopy and microfilm, and 3) new or currently +available product hardware and software. + +KENNEY described the advantages that using digital technology offers over +both photocopy and microfilm: 1) The potential exists to create a higher +quality reproduction of a deteriorating original than conventional +light-lens technology. 2) Because a digital image is an encoded +representation, it can be reproduced again and again with no resulting +loss of quality, as opposed to the situation with light-lens processes, +in which there is discernible difference between a second and a +subsequent generation of an image. 3) A digital image can be manipulated +in a number of ways to improve image capture; for example, Xerox has +developed a windowing application that enables one to capture a page +containing both text and illustrations in a manner that optimizes the +reproduction of both. (With light-lens technology, one must choose which +to optimize, text or the illustration; in preservation microfilming, the +current practice is to shoot an illustrated page twice, once to highlight +the text and the second time to provide the best capture for the +illustration.) 4) A digital image can also be edited, density levels +adjusted to remove underlining and stains, and to increase legibility for +faint documents. 5) On-screen inspection can take place at the time of +initial setup and adjustments made prior to scanning, factors that +substantially reduce the number of retakes required in quality control. + +A primary goal of CXP has been to evaluate the paper output printed on +the Xerox DocuTech, a high-speed printer that produces 600-dpi pages from +scanned images at a rate of 135 pages a minute. KENNEY recounted several +publishing challenges to represent faithful and legible reproductions of +the originals that the 600-dpi copy for the most part successfully +captured. For example, many of the deteriorating volumes in the project +were heavily illustrated with fine line drawings or halftones or came in +languages such as Japanese, in which the buildup of characters comprised +of varying strokes is difficult to reproduce at lower resolutions; a +surprising number of them came with annotations and mathematical +formulas, which it was critical to be able to duplicate exactly. + +KENNEY noted that 1) the copies are being printed on paper that meets the +ANSI standards for performance, 2) the DocuTech printer meets the machine +and toner requirements for proper adhesion of print to page, as described +by the National Archives, and thus 3) paper product is considered to be +the archival equivalent of preservation photocopy. + +KENNEY then discussed several samples of the quality achieved in the +project that had been distributed in a handout, for example, a copy of a +print-on-demand version of the 1911 Reed lecture on the steam turbine, +which contains halftones, line drawings, and illustrations embedded in +text; the first four loose pages in the volume compared the capture +capabilities of scanning to photocopy for a standard test target, the +IEEE standard 167A 1987 test chart. In all instances scanning proved +superior to photocopy, though only slightly more so in one. + +Conceding the simplistic nature of her review of the quality of scanning +to photocopy, KENNEY described it as one representation of the kinds of +settings that could be used with scanning capabilities on the equipment +CXP uses. KENNEY also pointed out that CXP investigated the quality +achieved with binary scanning only, and noted the great promise in gray +scale and color scanning, whose advantages and disadvantages need to be +examined. She argued further that scanning resolutions and file formats +can represent a complex trade-off between the time it takes to capture +material, file size, fidelity to the original, and on-screen display; and +printing and equipment availability. All these factors must be taken +into consideration. + +CXP placed primary emphasis on the production in a timely and +cost-effective manner of printed facsimiles that consisted largely of +black-and-white text. With binary scanning, large files may be +compressed efficiently and in a lossless manner (i.e., no data is lost in +the process of compressing [and decompressing] an image--the exact +bit-representation is maintained) using Group 4 CCITT (i.e., the French +acronym for International Consultative Committee for Telegraph and +Telephone) compression. CXP was getting compression ratios of about +forty to one. Gray-scale compression, which primarily uses JPEG, is much +less economical and can represent a lossy compression (i.e., not +lossless), so that as one compresses and decompresses, the illustration +is subtly changed. While binary files produce a high-quality printed +version, it appears 1) that other combinations of spatial resolution with +gray and/or color hold great promise as well, and 2) that gray scale can +represent a tremendous advantage for on-screen viewing. The quality +associated with binary and gray scale also depends on the equipment used. +For instance, binary scanning produces a much better copy on a binary +printer. + +Among CXP's findings concerning the production of microfilm from digital +files, KENNEY reported that the digital files for the same Reed lecture +were used to produce sample film using an electron beam recorder. The +resulting film was faithful to the image capture of the digital files, +and while CXP felt that the text and image pages represented in the Reed +lecture were superior to that of the light-lens film, the resolution +readings for the 600 dpi were not as high as standard microfilming. +KENNEY argued that the standards defined for light-lens technology are +not totally transferable to a digital environment. Moreover, they are +based on definition of quality for a preservation copy. Although making +this case will prove to be a long, uphill struggle, CXP plans to continue +to investigate the issue over the course of the next year. + +KENNEY concluded this portion of her talk with a discussion of the +advantages of creating film: it can serve as a primary backup and as a +preservation master to the digital file; it could then become the print +or production master and service copies could be paper, film, optical +disks, magnetic media, or on-screen display. + +Finally, KENNEY presented details re production: + + * Development and testing of a moderately-high resolution production + scanning workstation represented a third goal of CXP; to date, 1,000 + volumes have been scanned, or about 300,000 images. + + * The resulting digital files are stored and used to produce + hard-copy replacements for the originals and additional prints on + demand; although the initial costs are high, scanning technology + offers an affordable means for reformatting brittle material. + + * A technician in production mode can scan 300 pages per hour when + performing single-sheet scanning, which is a necessity when working + with truly brittle paper; this figure is expected to increase + significantly with subsequent iterations of the software from Xerox; + a three-month time-and-cost study of scanning found that the average + 300-page book would take about an hour and forty minutes to scan + (this figure included the time for setup, which involves keying in + primary bibliographic data, going into quality control mode to + define page size, establishing front-to-back registration, and + scanning sample pages to identify a default range of settings for + the entire book--functions not dissimilar to those performed by + filmers or those preparing a book for photocopy). + + * The final step in the scanning process involved rescans, which + happily were few and far between, representing well under 1 percent + of the total pages scanned. + +In addition to technician time, CXP costed out equipment, amortized over +four years, the cost of storing and refreshing the digital files every +four years, and the cost of printing and binding, book-cloth binding, a +paper reproduction. The total amounted to a little under $65 per single +300-page volume, with 30 percent overhead included--a figure competitive +with the prices currently charged by photocopy vendors. + +Of course, with scanning, in addition to the paper facsimile, one is left +with a digital file from which subsequent copies of the book can be +produced for a fraction of the cost of photocopy, with readers afforded +choices in the form of these copies. + +KENNEY concluded that digital technology offers an electronic means for a +library preservation effort to pay for itself. If a brittle-book program +included the means of disseminating reprints of books that are in demand +by libraries and researchers alike, the initial investment in capture +could be recovered and used to preserve additional but less popular +books. She disclosed that an economic model for a self-sustaining +program could be developed for CXP's report to the Commission on +Preservation and Access (CPA). + +KENNEY stressed that the focus of CXP has been on obtaining high quality +in a production environment. The use of digital technology is viewed as +an affordable alternative to other reformatting options. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ANDRE * Overview and history of NATDP * Various agricultural CD-ROM +products created inhouse and by service bureaus * Pilot project on +Internet transmission * Additional products in progress * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Pamela ANDRE, associate director for automation, National Agricultural +Text Digitizing Program (NATDP), National Agricultural Library (NAL), +presented an overview of NATDP, which has been underway at NAL the last +four years, before Judith ZIDAR discussed the technical details. ANDRE +defined agricultural information as a broad range of material going from +basic and applied research in the hard sciences to the one-page pamphlets +that are distributed by the cooperative state extension services on such +things as how to grow blueberries. + +NATDP began in late 1986 with a meeting of representatives from the +land-grant library community to deal with the issue of electronic +information. NAL and forty-five of these libraries banded together to +establish this project--to evaluate the technology for converting what +were then source documents in paper form into electronic form, to provide +access to that digital information, and then to distribute it. +Distributing that material to the community--the university community as +well as the extension service community, potentially down to the county +level--constituted the group's chief concern. + +Since January 1988 (when the microcomputer-based scanning system was +installed at NAL), NATDP has done a variety of things, concerning which +ZIDAR would provide further details. For example, the first technology +considered in the project's discussion phase was digital videodisc, which +indicates how long ago it was conceived. + +Over the four years of this project, four separate CD-ROM products on +four different agricultural topics were created, two at a +scanning-and-OCR station installed at NAL, and two by service bureaus. +Thus, NATDP has gained comparative information in terms of those relative +costs. Each of these products contained the full ASCII text as well as +page images of the material, or between 4,000 and 6,000 pages of material +on these disks. Topics included aquaculture, food, agriculture and +science (i.e., international agriculture and research), acid rain, and +Agent Orange, which was the final product distributed (approximately +eighteen months before the Workshop). + +The third phase of NATDP focused on delivery mechanisms other than +CD-ROM. At the suggestion of Clifford LYNCH, who was a technical +consultant to the project at this point, NATDP became involved with the +Internet and initiated a project with the help of North Carolina State +University, in which fourteen of the land-grant university libraries are +transmitting digital images over the Internet in response to interlibrary +loan requests--a topic for another meeting. At this point, the pilot +project had been completed for about a year and the final report would be +available shortly after the Workshop. In the meantime, the project's +success had led to its extension. (ANDRE noted that one of the first +things done under the program title was to select a retrieval package to +use with subsequent products; Windows Personal Librarian was the package +of choice after a lengthy evaluation.) + +Three additional products had been planned and were in progress: + + 1) An arrangement with the American Society of Agronomy--a + professional society that has published the Agronomy Journal since + about 1908--to scan and create bit-mapped images of its journal. + ASA granted permission first to put and then to distribute this + material in electronic form, to hold it at NAL, and to use these + electronic images as a mechanism to deliver documents or print out + material for patrons, among other uses. Effectively, NAL has the + right to use this material in support of its program. + (Significantly, this arrangement offers a potential cooperative + model for working with other professional societies in agriculture + to try to do the same thing--put the journals of particular interest + to agriculture research into electronic form.) + + 2) An extension of the earlier product on aquaculture. + + 3) The George Washington Carver Papers--a joint project with + Tuskegee University to scan and convert from microfilm some 3,500 + images of Carver's papers, letters, and drawings. + +It was anticipated that all of these products would appear no more than +six months after the Workshop. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * (A separate arena for scanning) * Steps in creating a database * +Image capture, with and without performing OCR * Keying in tracking data +* Scanning, with electronic and manual tracking * Adjustments during +scanning process * Scanning resolutions * Compression * De-skewing and +filtering * Image capture from microform: the papers and letters of +George Washington Carver * Equipment used for a scanning system * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), illustrated the technical +details of NATDP, including her primary responsibility, scanning and +creating databases on a topic and putting them on CD-ROM. + +(ZIDAR remarked a separate arena from the CD-ROM projects, although the +processing of the material is nearly identical, in which NATDP is also +scanning material and loading it on a Next microcomputer, which in turn +is linked to NAL's integrated library system. Thus, searches in NAL's +bibliographic database will enable people to pull up actual page images +and text for any documents that have been entered.) + +In accordance with the session's topic, ZIDAR focused her illustrated +talk on image capture, offering a primer on the three main steps in the +process: 1) assemble the printed publications; 2) design the database +(database design occurs in the process of preparing the material for +scanning; this step entails reviewing and organizing the material, +defining the contents--what will constitute a record, what kinds of +fields will be captured in terms of author, title, etc.); 3) perform a +certain amount of markup on the paper publications. NAL performs this +task record by record, preparing work sheets or some other sort of +tracking material and designing descriptors and other enhancements to be +added to the data that will not be captured from the printed publication. +Part of this process also involves determining NATDP's file and directory +structure: NATDP attempts to avoid putting more than approximately 100 +images in a directory, because placing more than that on a CD-ROM would +reduce the access speed. + +This up-front process takes approximately two weeks for a +6,000-7,000-page database. The next step is to capture the page images. +How long this process takes is determined by the decision whether or not +to perform OCR. Not performing OCR speeds the process, whereas text +capture requires greater care because of the quality of the image: it +has to be straighter and allowance must be made for text on a page, not +just for the capture of photographs. + +NATDP keys in tracking data, that is, a standard bibliographic record +including the title of the book and the title of the chapter, which will +later either become the access information or will be attached to the +front of a full-text record so that it is searchable. + +Images are scanned from a bound or unbound publication, chiefly from +bound publications in the case of NATDP, however, because often they are +the only copies and the publications are returned to the shelves. NATDP +usually scans one record at a time, because its database tracking system +tracks the document in that way and does not require further logical +separating of the images. After performing optical character +recognition, NATDP moves the images off the hard disk and maintains a +volume sheet. Though the system tracks electronically, all the +processing steps are also tracked manually with a log sheet. + +ZIDAR next illustrated the kinds of adjustments that one can make when +scanning from paper and microfilm, for example, redoing images that need +special handling, setting for dithering or gray scale, and adjusting for +brightness or for the whole book at one time. + +NATDP is scanning at 300 dots per inch, a standard scanning resolution. +Though adequate for capturing text that is all of a standard size, 300 +dpi is unsuitable for any kind of photographic material or for very small +text. Many scanners allow for different image formats, TIFF, of course, +being a de facto standard. But if one intends to exchange images with +other people, the ability to scan other image formats, even if they are +less common, becomes highly desirable. + +CCITT Group 4 is the standard compression for normal black-and-white +images, JPEG for gray scale or color. ZIDAR recommended 1) using the +standard compressions, particularly if one attempts to make material +available and to allow users to download images and reuse them from +CD-ROMs; and 2) maintaining the ability to output an uncompressed image, +because in image exchange uncompressed images are more likely to be able +to cross platforms. + +ZIDAR emphasized the importance of de-skewing and filtering as +requirements on NATDP's upgraded system. For instance, scanning bound +books, particularly books published by the federal government whose pages +are skewed, and trying to scan them straight if OCR is to be performed, +is extremely time-consuming. The same holds for filtering of +poor-quality or older materials. + +ZIDAR described image capture from microform, using as an example three +reels from a sixty-seven-reel set of the papers and letters of George +Washington Carver that had been produced by Tuskegee University. These +resulted in approximately 3,500 images, which NATDP had had scanned by +its service contractor, Science Applications International Corporation +(SAIC). NATDP also created bibliographic records for access. (NATDP did +not have such specialized equipment as a microfilm scanner. + +Unfortunately, the process of scanning from microfilm was not an +unqualified success, ZIDAR reported: because microfilm frame sizes vary, +occasionally some frames were missed, which without spending much time +and money could not be recaptured. + +OCR could not be performed from the scanned images of the frames. The +bleeding in the text simply output text, when OCR was run, that could not +even be edited. NATDP tested for negative versus positive images, +landscape versus portrait orientation, and single- versus dual-page +microfilm, none of which seemed to affect the quality of the image; but +also on none of them could OCR be performed. + +In selecting the microfilm they would use, therefore, NATDP had other +factors in mind. ZIDAR noted two factors that influenced the quality of +the images: 1) the inherent quality of the original and 2) the amount of +size reduction on the pages. + +The Carver papers were selected because they are informative and visually +interesting, treat a single subject, and are valuable in their own right. +The images were scanned and divided into logical records by SAIC, then +delivered, and loaded onto NATDP's system, where bibliographic +information taken directly from the images was added. Scanning was +completed in summer 1991 and by the end of summer 1992 the disk was +scheduled to be published. + +Problems encountered during processing included the following: Because +the microfilm scanning had to be done in a batch, adjustment for +individual page variations was not possible. The frame size varied on +account of the nature of the material, and therefore some of the frames +were missed while others were just partial frames. The only way to go +back and capture this material was to print out the page with the +microfilm reader from the missing frame and then scan it in from the +page, which was extremely time-consuming. The quality of the images +scanned from the printout of the microfilm compared unfavorably with that +of the original images captured directly from the microfilm. The +inability to perform OCR also was a major disappointment. At the time, +computer output microfilm was unavailable to test. + +The equipment used for a scanning system was the last topic addressed by +ZIDAR. The type of equipment that one would purchase for a scanning +system included: a microcomputer, at least a 386, but preferably a 486; +a large hard disk, 380 megabyte at minimum; a multi-tasking operating +system that allows one to run some things in batch in the background +while scanning or doing text editing, for example, Unix or OS/2 and, +theoretically, Windows; a high-speed scanner and scanning software that +allows one to make the various adjustments mentioned earlier; a +high-resolution monitor (150 dpi ); OCR software and hardware to perform +text recognition; an optical disk subsystem on which to archive all the +images as the processing is done; file management and tracking software. + +ZIDAR opined that the software one purchases was more important than the +hardware and might also cost more than the hardware, but it was likely to +prove critical to the success or failure of one's system. In addition to +a stand-alone scanning workstation for image capture, then, text capture +requires one or two editing stations networked to this scanning station +to perform editing. Editing the text takes two or three times as long as +capturing the images. + +Finally, ZIDAR stressed the importance of buying an open system that allows +for more than one vendor, complies with standards, and can be upgraded. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WATERS *Yale University Library's master plan to convert microfilm to +digital imagery (POB) * The place of electronic tools in the library of +the future * The uses of images and an image library * Primary input from +preservation microfilm * Features distinguishing POB from CXP and key +hypotheses guiding POB * Use of vendor selection process to facilitate +organizational work * Criteria for selecting vendor * Finalists and +results of process for Yale * Key factor distinguishing vendors * +Components, design principles, and some estimated costs of POB * Role of +preservation materials in developing imaging market * Factors affecting +quality and cost * Factors affecting the usability of complex documents +in image form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Donald WATERS, head of the Systems Office, Yale University Library, +reported on the progress of a master plan for a project at Yale to +convert microfilm to digital imagery, Project Open Book (POB). Stating +that POB was in an advanced stage of planning, WATERS detailed, in +particular, the process of selecting a vendor partner and several key +issues under discussion as Yale prepares to move into the project itself. +He commented first on the vision that serves as the context of POB and +then described its purpose and scope. + +WATERS sees the library of the future not necessarily as an electronic +library but as a place that generates, preserves, and improves for its +clients ready access to both intellectual and physical recorded +knowledge. Electronic tools must find a place in the library in the +context of this vision. Several roles for electronic tools include +serving as: indirect sources of electronic knowledge or as "finding" +aids (the on-line catalogues, the article-level indices, registers for +documents and archives); direct sources of recorded knowledge; full-text +images; and various kinds of compound sources of recorded knowledge (the +so-called compound documents of Hypertext, mixed text and image, +mixed-text image format, and multimedia). + +POB is looking particularly at images and an image library, the uses to +which images will be put (e.g., storage, printing, browsing, and then use +as input for other processes), OCR as a subsequent process to image +capture, or creating an image library, and also possibly generating +microfilm. + +While input will come from a variety of sources, POB is considering +especially input from preservation microfilm. A possible outcome is that +the film and paper which provide the input for the image library +eventually may go off into remote storage, and that the image library may +be the primary access tool. + +The purpose and scope of POB focus on imaging. Though related to CXP, +POB has two features which distinguish it: 1) scale--conversion of +10,000 volumes into digital image form; and 2) source--conversion from +microfilm. Given these features, several key working hypotheses guide +POB, including: 1) Since POB is using microfilm, it is not concerned with +the image library as a preservation medium. 2) Digital imagery can improve +access to recorded knowledge through printing and network distribution at +a modest incremental cost of microfilm. 3) Capturing and storing documents +in a digital image form is necessary to further improvements in access. +(POB distinguishes between the imaging, digitizing process and OCR, +which at this stage it does not plan to perform.) + +Currently in its first or organizational phase, POB found that it could +use a vendor selection process to facilitate a good deal of the +organizational work (e.g., creating a project team and advisory board, +confirming the validity of the plan, establishing the cost of the project +and a budget, selecting the materials to convert, and then raising the +necessary funds). + +POB developed numerous selection criteria, including: a firm committed +to image-document management, the ability to serve as systems integrator +in a large-scale project over several years, interest in developing the +requisite software as a standard rather than a custom product, and a +willingness to invest substantial resources in the project itself. + +Two vendors, DEC and Xerox, were selected as finalists in October 1991, +and with the support of the Commission on Preservation and Access, each +was commissioned to generate a detailed requirements analysis for the +project and then to submit a formal proposal for the completion of the +project, which included a budget and costs. The terms were that POB would +pay the loser. The results for Yale of involving a vendor included: +broad involvement of Yale staff across the board at a relatively low +cost, which may have long-term significance in carrying out the project +(twenty-five to thirty university people are engaged in POB); better +understanding of the factors that affect corporate response to markets +for imaging products; a competitive proposal; and a more sophisticated +view of the imaging markets. + +The most important factor that distinguished the vendors under +consideration was their identification with the customer. The size and +internal complexity of the company also was an important factor. POB was +looking at large companies that had substantial resources. In the end, +the process generated for Yale two competitive proposals, with Xerox's +the clear winner. WATERS then described the components of the proposal, +the design principles, and some of the costs estimated for the process. + +Components are essentially four: a conversion subsystem, a +network-accessible storage subsystem for 10,000 books (and POB expects +200 to 600 dpi storage), browsing stations distributed on the campus +network, and network access to the image printers. + +Among the design principles, POB wanted conversion at the highest +possible resolution. Assuming TIFF files, TIFF files with Group 4 +compression, TCP/IP, and ethernet network on campus, POB wanted a +client-server approach with image documents distributed to the +workstations and made accessible through native workstation interfaces +such as Windows. POB also insisted on a phased approach to +implementation: 1) a stand-alone, single-user, low-cost entry into the +business with a workstation focused on conversion and allowing POB to +explore user access; 2) movement into a higher-volume conversion with +network-accessible storage and multiple access stations; and 3) a +high-volume conversion, full-capacity storage, and multiple browsing +stations distributed throughout the campus. + +The costs proposed for start-up assumed the existence of the Yale network +and its two DocuTech image printers. Other start-up costs are estimated +at $1 million over the three phases. At the end of the project, the annual +operating costs estimated primarily for the software and hardware proposed +come to about $60,000, but these exclude costs for labor needed in the +conversion process, network and printer usage, and facilities management. + +Finally, the selection process produced for Yale a more sophisticated +view of the imaging markets: the management of complex documents in +image form is not a preservation problem, not a library problem, but a +general problem in a broad, general industry. Preservation materials are +useful for developing that market because of the qualities of the +material. For example, much of it is out of copyright. The resolution +of key issues such as the quality of scanning and image browsing also +will affect development of that market. + +The technology is readily available but changing rapidly. In this +context of rapid change, several factors affect quality and cost, to +which POB intends to pay particular attention, for example, the various +levels of resolution that can be achieved. POB believes it can bring +resolution up to 600 dpi, but an interpolation process from 400 to 600 is +more likely. The variation quality in microfilm will prove to be a +highly important factor. POB may reexamine the standards used to film in +the first place by looking at this process as a follow-on to microfilming. + +Other important factors include: the techniques available to the +operator for handling material, the ways of integrating quality control +into the digitizing work flow, and a work flow that includes indexing and +storage. POB's requirement was to be able to deal with quality control +at the point of scanning. Thus, thanks to Xerox, POB anticipates having +a mechanism which will allow it not only to scan in batch form, but to +review the material as it goes through the scanner and control quality +from the outset. + +The standards for measuring quality and costs depend greatly on the uses +of the material, including subsequent OCR, storage, printing, and +browsing. But especially at issue for POB is the facility for browsing. +This facility, WATERS said, is perhaps the weakest aspect of imaging +technology and the most in need of development. + +A variety of factors affect the usability of complex documents in image +form, among them: 1) the ability of the system to handle the full range +of document types, not just monographs but serials, multi-part +monographs, and manuscripts; 2) the location of the database of record +for bibliographic information about the image document, which POB wants +to enter once and in the most useful place, the on-line catalog; 3) a +document identifier for referencing the bibliographic information in one +place and the images in another; 4) the technique for making the basic +internal structure of the document accessible to the reader; and finally, +5) the physical presentation on the CRT of those documents. POB is ready +to complete this phase now. One last decision involves deciding which +material to scan. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * TIFF files constitute de facto standard * NARA's experience +with image conversion software and text conversion * RFC 1314 * +Considerable flux concerning available hardware and software solutions * +NAL through-put rate during scanning * Window management questions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In the question-and-answer period that followed WATERS's presentation, +the following points emerged: + + * ZIDAR's statement about using TIFF files as a standard meant de + facto standard. This is what most people use and typically exchange + with other groups, across platforms, or even occasionally across + display software. + + * HOLMES commented on the unsuccessful experience of NARA in + attempting to run image-conversion software or to exchange between + applications: What are supposedly TIFF files go into other software + that is supposed to be able to accept TIFF but cannot recognize the + format and cannot deal with it, and thus renders the exchange + useless. Re text conversion, he noted the different recognition + rates obtained by substituting the make and model of scanners in + NARA's recent test of an "intelligent" character-recognition product + for a new company. In the selection of hardware and software, + HOLMES argued, software no longer constitutes the overriding factor + it did until about a year ago; rather it is perhaps important to + look at both now. + + * Danny Cohen and Alan Katz of the University of Southern California + Information Sciences Institute began circulating as an Internet RFC + (RFC 1314) about a month ago a standard for a TIFF interchange + format for Internet distribution of monochrome bit-mapped images, + which LYNCH said he believed would be used as a de facto standard. + + * FLEISCHHAUER's impression from hearing these reports and thinking + about AM's experience was that there is considerable flux concerning + available hardware and software solutions. HOOTON agreed and + commented at the same time on ZIDAR's statement that the equipment + employed affects the results produced. One cannot draw a complete + conclusion by saying it is difficult or impossible to perform OCR + from scanning microfilm, for example, with that device, that set of + parameters, and system requirements, because numerous other people + are accomplishing just that, using other components, perhaps. + HOOTON opined that both the hardware and the software were highly + important. Most of the problems discussed today have been solved in + numerous different ways by other people. Though it is good to be + cognizant of various experiences, this is not to say that it will + always be thus. + + * At NAL, the through-put rate of the scanning process for paper, + page by page, performing OCR, ranges from 300 to 600 pages per day; + not performing OCR is considerably faster, although how much faster + is not known. This is for scanning from bound books, which is much + slower. + + * WATERS commented on window management questions: DEC proposed an + X-Windows solution which was problematical for two reasons. One was + POB's requirement to be able to manipulate images on the workstation + and bring them down to the workstation itself and the other was + network usage. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +THOMA * Illustration of deficiencies in scanning and storage process * +Image quality in this process * Different costs entailed by better image +quality * Techniques for overcoming various de-ficiencies: fixed +thresholding, dynamic thresholding, dithering, image merge * Page edge +effects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +George THOMA, chief, Communications Engineering Branch, National Library +of Medicine (NLM), illustrated several of the deficiencies discussed by +the previous speakers. He introduced the topic of special problems by +noting the advantages of electronic imaging. For example, it is regenerable +because it is a coded file, and real-time quality control is possible with +electronic capture, whereas in photographic capture it is not. + +One of the difficulties discussed in the scanning and storage process was +image quality which, without belaboring the obvious, means different +things for maps, medical X-rays, or broadcast television. In the case of +documents, THOMA said, image quality boils down to legibility of the +textual parts, and fidelity in the case of gray or color photo print-type +material. Legibility boils down to scan density, the standard in most +cases being 300 dpi. Increasing the resolution with scanners that +perform 600 or 1200 dpi, however, comes at a cost. + +Better image quality entails at least four different kinds of costs: 1) +equipment costs, because the CCD (i.e., charge-couple device) with +greater number of elements costs more; 2) time costs that translate to +the actual capture costs, because manual labor is involved (the time is +also dependent on the fact that more data has to be moved around in the +machine in the scanning or network devices that perform the scanning as +well as the storage); 3) media costs, because at high resolutions larger +files have to be stored; and 4) transmission costs, because there is just +more data to be transmitted. + +But while resolution takes care of the issue of legibility in image +quality, other deficiencies have to do with contrast and elements on the +page scanned or the image that needed to be removed or clarified. Thus, +THOMA proceeded to illustrate various deficiencies, how they are +manifested, and several techniques to overcome them. + +Fixed thresholding was the first technique described, suitable for +black-and-white text, when the contrast does not vary over the page. One +can have many different threshold levels in scanning devices. Thus, +THOMA offered an example of extremely poor contrast, which resulted from +the fact that the stock was a heavy red. This is the sort of image that +when microfilmed fails to provide any legibility whatsoever. Fixed +thresholding is the way to change the black-to-red contrast to the +desired black-to-white contrast. + +Other examples included material that had been browned or yellowed by +age. This was also a case of contrast deficiency, and correction was +done by fixed thresholding. A final example boils down to the same +thing, slight variability, but it is not significant. Fixed thresholding +solves this problem as well. The microfilm equivalent is certainly legible, +but it comes with dark areas. Though THOMA did not have a slide of the +microfilm in this case, he did show the reproduced electronic image. + +When one has variable contrast over a page or the lighting over the page +area varies, especially in the case where a bound volume has light +shining on it, the image must be processed by a dynamic thresholding +scheme. One scheme, dynamic averaging, allows the threshold level not to +be fixed but to be recomputed for every pixel from the neighboring +characteristics. The neighbors of a pixel determine where the threshold +should be set for that pixel. + +THOMA showed an example of a page that had been made deficient by a +variety of techniques, including a burn mark, coffee stains, and a yellow +marker. Application of a fixed-thresholding scheme, THOMA argued, might +take care of several deficiencies on the page but not all of them. +Performing the calculation for a dynamic threshold setting, however, +removes most of the deficiencies so that at least the text is legible. + +Another problem is representing a gray level with black-and-white pixels +by a process known as dithering or electronic screening. But dithering +does not provide good image quality for pure black-and-white textual +material. THOMA illustrated this point with examples. Although its +suitability for photoprint is the reason for electronic screening or +dithering, it cannot be used for every compound image. In the document +that was distributed by CXP, THOMA noticed that the dithered image of the +IEEE test chart evinced some deterioration in the text. He presented an +extreme example of deterioration in the text in which compounded +documents had to be set right by other techniques. The technique +illustrated by the present example was an image merge in which the page +is scanned twice and the settings go from fixed threshold to the +dithering matrix; the resulting images are merged to give the best +results with each technique. + +THOMA illustrated how dithering is also used in nonphotographic or +nonprint materials with an example of a grayish page from a medical text, +which was reproduced to show all of the gray that appeared in the +original. Dithering provided a reproduction of all the gray in the +original of another example from the same text. + +THOMA finally illustrated the problem of bordering, or page-edge, +effects. Books and bound volumes that are placed on a photocopy machine +or a scanner produce page-edge effects that are undesirable for two +reasons: 1) the aesthetics of the image; after all, if the image is to +be preserved, one does not necessarily want to keep all of its +deficiencies; 2) compression (with the bordering problem THOMA +illustrated, the compression ratio deteriorated tremendously). One way +to eliminate this more serious problem is to have the operator at the +point of scanning window the part of the image that is desirable and +automatically turn all of the pixels out of that picture to white. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +FLEISCHHAUER * AM's experience with scanning bound materials * Dithering +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Carl FLEISCHHAUER, coordinator, American Memory, Library of Congress, +reported AM's experience with scanning bound materials, which he likened +to the problems involved in using photocopying machines. Very few +devices in the industry offer book-edge scanning, let alone book cradles. +The problem may be unsolvable, FLEISCHHAUER said, because a large enough +market does not exist for a preservation-quality scanner. AM is using a +Kurzweil scanner, which is a book-edge scanner now sold by Xerox. + +Devoting the remainder of his brief presentation to dithering, +FLEISCHHAUER related AM's experience with a contractor who was using +unsophisticated equipment and software to reduce moire patterns from +printed halftones. AM took the same image and used the dithering +algorithm that forms part of the same Kurzweil Xerox scanner; it +disguised moire patterns much more effectively. + +FLEISCHHAUER also observed that dithering produces a binary file which is +useful for numerous purposes, for example, printing it on a laser printer +without having to "re-halftone" it. But it tends to defeat efficient +compression, because the very thing that dithers to reduce moire patterns +also tends to work against compression schemes. AM thought the +difference in image quality was worth it. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Relative use as a criterion for POB's selection of books to +be converted into digital form * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion period, WATERS noted that one of the criteria for +selecting books among the 10,000 to be converted into digital image form +would be how much relative use they would receive--a subject still +requiring evaluation. The challenge will be to understand whether +coherent bodies of material will increase usage or whether POB should +seek material that is being used, scan that, and make it more accessible. +POB might decide to digitize materials that are already heavily used, in +order to make them more accessible and decrease wear on them. Another +approach would be to provide a large body of intellectually coherent +material that may be used more in digital form than it is currently used +in microfilm. POB would seek material that was out of copyright. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BARONAS * Origin and scope of AIIM * Types of documents produced in +AIIM's standards program * Domain of AIIM's standardization work * AIIM's +structure * TC 171 and MS23 * Electronic image management standards * +Categories of EIM standardization where AIIM standards are being +developed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Jean BARONAS, senior manager, Department of Standards and Technology, +Association for Information and Image Management (AIIM), described the +not-for-profit association and the national and international programs +for standardization in which AIIM is active. + +Accredited for twenty-five years as the nation's standards development +organization for document image management, AIIM began life in a library +community developing microfilm standards. Today the association +maintains both its library and business-image management standardization +activities--and has moved into electronic image-management +standardization (EIM). + +BARONAS defined the program's scope. AIIM deals with: 1) the +terminology of standards and of the technology it uses; 2) methods of +measurement for the systems, as well as quality; 3) methodologies for +users to evaluate and measure quality; 4) the features of apparatus used +to manage and edit images; and 5) the procedures used to manage images. + +BARONAS noted that three types of documents are produced in the AIIM +standards program: the first two, accredited by the American National +Standards Institute (ANSI), are standards and standard recommended +practices. Recommended practices differ from standards in that they +contain more tutorial information. A technical report is not an ANSI +standard. Because AIIM's policies and procedures for developing +standards are approved by ANSI, its standards are labeled ANSI/AIIM, +followed by the number and title of the standard. + +BARONAS then illustrated the domain of AIIM's standardization work. For +example, AIIM is the administrator of the U.S. Technical Advisory Group +(TAG) to the International Standards Organization's (ISO) technical +committee, TC l7l Micrographics and Optical Memories for Document and +Image Recording, Storage, and Use. AIIM officially works through ANSI in +the international standardization process. + +BARONAS described AIIM's structure, including its board of directors, its +standards board of twelve individuals active in the image-management +industry, its strategic planning and legal admissibility task forces, and +its National Standards Council, which is comprised of the members of a +number of organizations who vote on every AIIM standard before it is +published. BARONAS pointed out that AIIM's liaisons deal with numerous +other standards developers, including the optical disk community, office +and publishing systems, image-codes-and-character set committees, and the +National Information Standards Organization (NISO). + +BARONAS illustrated the procedures of TC l7l, which covers all aspects of +image management. When AIIM's national program has conceptualized a new +project, it is usually submitted to the international level, so that the +member countries of TC l7l can simultaneously work on the development of +the standard or the technical report. BARONAS also illustrated a classic +microfilm standard, MS23, which deals with numerous imaging concepts that +apply to electronic imaging. Originally developed in the l970s, revised +in the l980s, and revised again in l991, this standard is scheduled for +another revision. MS23 is an active standard whereby users may propose +new density ranges and new methods of evaluating film images in the +standard's revision. + +BARONAS detailed several electronic image-management standards, for +instance, ANSI/AIIM MS44, a quality-control guideline for scanning 8.5" +by 11" black-and-white office documents. This standard is used with the +IEEE fax image--a continuous tone photographic image with gray scales, +text, and several continuous tone pictures--and AIIM test target number +2, a representative document used in office document management. + +BARONAS next outlined the four categories of EIM standardization in which +AIIM standards are being developed: transfer and retrieval, evaluation, +optical disc and document scanning applications, and design and +conversion of documents. She detailed several of the main projects of +each: 1) in the category of image transfer and retrieval, a bi-level +image transfer format, ANSI/AIIM MS53, which is a proposed standard that +describes a file header for image transfer between unlike systems when +the images are compressed using G3 and G4 compression; 2) the category of +image evaluation, which includes the AIIM-proposed TR26 tutorial on image +resolution (this technical report will treat the differences and +similarities between classical or photographic and electronic imaging); +3) design and conversion, which includes a proposed technical report +called "Forms Design Optimization for EIM" (this report considers how +general-purpose business forms can be best designed so that scanning is +optimized; reprographic characteristics such as type, rules, background, +tint, and color will likewise be treated in the technical report); 4) +disk and document scanning applications includes a project a) on planning +platters and disk management, b) on generating an application profile for +EIM when images are stored and distributed on CD-ROM, and c) on +evaluating SCSI2, and how a common command set can be generated for SCSI2 +so that document scanners are more easily integrated. (ANSI/AIIM MS53 +will also apply to compressed images.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +BATTIN * The implications of standards for preservation * A major +obstacle to successful cooperation * A hindrance to access in the digital +environment * Standards a double-edged sword for those concerned with the +preservation of the human record * Near-term prognosis for reliable +archival standards * Preservation concerns for electronic media * Need +for reconceptualizing our preservation principles * Standards in the real +world and the politics of reproduction * Need to redefine the concept of +archival and to begin to think in terms of life cycles * Cooperation and +the La Guardia Eight * Concerns generated by discussions on the problems +of preserving text and image * General principles to be adopted in a +world without standards * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Patricia BATTIN, president, the Commission on Preservation and Access +(CPA), addressed the implications of standards for preservation. She +listed several areas where the library profession and the analog world of +the printed book had made enormous contributions over the past hundred +years--for example, in bibliographic formats, binding standards, and, most +important, in determining what constitutes longevity or archival quality. + +Although standards have lightened the preservation burden through the +development of national and international collaborative programs, +nevertheless, a pervasive mistrust of other people's standards remains a +major obstacle to successful cooperation, BATTIN said. + +The zeal to achieve perfection, regardless of the cost, has hindered +rather than facilitated access in some instances, and in the digital +environment, where no real standards exist, has brought an ironically +just reward. + +BATTIN argued that standards are a double-edged sword for those concerned +with the preservation of the human record, that is, the provision of +access to recorded knowledge in a multitude of media as far into the +future as possible. Standards are essential to facilitate +interconnectivity and access, but, BATTIN said, as LYNCH pointed out +yesterday, if set too soon they can hinder creativity, expansion of +capability, and the broadening of access. The characteristics of +standards for digital imagery differ radically from those for analog +imagery. And the nature of digital technology implies continuing +volatility and change. To reiterate, precipitous standard-setting can +inhibit creativity, but delayed standard-setting results in chaos. + +Since in BATTIN'S opinion the near-term prognosis for reliable archival +standards, as defined by librarians in the analog world, is poor, two +alternatives remain: standing pat with the old technology, or +reconceptualizing. + +Preservation concerns for electronic media fall into two general domains. +One is the continuing assurance of access to knowledge originally +generated, stored, disseminated, and used in electronic form. This +domain contains several subdivisions, including 1) the closed, +proprietary systems discussed the previous day, bundled information such +as electronic journals and government agency records, and electronically +produced or captured raw data; and 2) the application of digital +technologies to the reformatting of materials originally published on a +deteriorating analog medium such as acid paper or videotape. + +The preservation of electronic media requires a reconceptualizing of our +preservation principles during a volatile, standardless transition which +may last far longer than any of us envision today. BATTIN urged the +necessity of shifting focus from assessing, measuring, and setting +standards for the permanence of the medium to the concept of managing +continuing access to information stored on a variety of media and +requiring a variety of ever-changing hardware and software for access--a +fundamental shift for the library profession. + +BATTIN offered a primer on how to move forward with reasonable confidence +in a world without standards. Her comments fell roughly into two sections: +1) standards in the real world and 2) the politics of reproduction. + +In regard to real-world standards, BATTIN argued the need to redefine the +concept of archive and to begin to think in terms of life cycles. In +the past, the naive assumption that paper would last forever produced a +cavalier attitude toward life cycles. The transient nature of the +electronic media has compelled people to recognize and accept upfront the +concept of life cycles in place of permanency. + +Digital standards have to be developed and set in a cooperative context +to ensure efficient exchange of information. Moreover, during this +transition period, greater flexibility concerning how concepts such as +backup copies and archival copies in the CXP are defined is necessary, +or the opportunity to move forward will be lost. + +In terms of cooperation, particularly in the university setting, BATTIN +also argued the need to avoid going off in a hundred different +directions. The CPA has catalyzed a small group of universities called +the La Guardia Eight--because La Guardia Airport is where meetings take +place--Harvard, Yale, Cornell, Princeton, Penn State, Tennessee, +Stanford, and USC, to develop a digital preservation consortium to look +at all these issues and develop de facto standards as we move along, +instead of waiting for something that is officially blessed. Continuing +to apply analog values and definitions of standards to the digital +environment, BATTIN said, will effectively lead to forfeiture of the +benefits of digital technology to research and scholarship. + +Under the second rubric, the politics of reproduction, BATTIN reiterated +an oft-made argument concerning the electronic library, namely, that it +is more difficult to transform than to create, and nowhere is that belief +expressed more dramatically than in the conversion of brittle books to +new media. Preserving information published in electronic media involves +making sure the information remains accessible and that digital +information is not lost through reproduction. In the analog world of +photocopies and microfilm, the issue of fidelity to the original becomes +paramount, as do issues of "Whose fidelity?" and "Whose original?" + +BATTIN elaborated these arguments with a few examples from a recent study +conducted by the CPA on the problems of preserving text and image. +Discussions with scholars, librarians, and curators in a variety of +disciplines dependent on text and image generated a variety of concerns, +for example: 1) Copy what is, not what the technology is capable of. +This is very important for the history of ideas. Scholars wish to know +what the author saw and worked from. And make available at the +workstation the opportunity to erase all the defects and enhance the +presentation. 2) The fidelity of reproduction--what is good enough, what +can we afford, and the difference it makes--issues of subjective versus +objective resolution. 3) The differences between primary and secondary +users. Restricting the definition of primary user to the one in whose +discipline the material has been published runs one headlong into the +reality that these printed books have had a host of other users from a +host of other disciplines, who not only were looking for very different +things, but who also shared values very different from those of the +primary user. 4) The relationship of the standard of reproduction to new +capabilities of scholarship--the browsing standard versus an archival +standard. How good must the archival standard be? Can a distinction be +drawn between potential users in setting standards for reproduction? +Archival storage, use copies, browsing copies--ought an attempt to set +standards even be made? 5) Finally, costs. How much are we prepared to +pay to capture absolute fidelity? What are the trade-offs between vastly +enhanced access, degrees of fidelity, and costs? + +These standards, BATTIN concluded, serve to complicate further the +reproduction process, and add to the long list of technical standards +that are necessary to ensure widespread access. Ways to articulate and +analyze the costs that are attached to the different levels of standards +must be found. + +Given the chaos concerning standards, which promises to linger for the +foreseeable future, BATTIN urged adoption of the following general +principles: + + * Strive to understand the changing information requirements of + scholarly disciplines as more and more technology is integrated into + the process of research and scholarly communication in order to meet + future scholarly needs, not to build for the past. Capture + deteriorating information at the highest affordable resolution, even + though the dissemination and display technologies will lag. + + * Develop cooperative mechanisms to foster agreement on protocols + for document structure and other interchange mechanisms necessary + for widespread dissemination and use before official standards are + set. + + * Accept that, in a transition period, de facto standards will have + to be developed. + + * Capture information in a way that keeps all options open and + provides for total convertibility: OCR, scanning of microfilm, + producing microfilm from scanned documents, etc. + + * Work closely with the generators of information and the builders + of networks and databases to ensure that continuing accessibility is + a primary concern from the beginning. + + * Piggyback on standards under development for the broad market, and + avoid library-specific standards; work with the vendors, in order to + take advantage of that which is being standardized for the rest of + the world. + + * Concentrate efforts on managing permanence in the digital world, + rather than perfecting the longevity of a particular medium. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Additional comments on TIFF * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the brief discussion period that followed BATTIN's presentation, +BARONAS explained that TIFF was not developed in collaboration with or +under the auspices of AIIM. TIFF is a company product, not a standard, +is owned by two corporations, and is always changing. BARONAS also +observed that ANSI/AIIM MS53, a bi-level image file transfer format that +allows unlike systems to exchange images, is compatible with TIFF as well +as with DEC's architecture and IBM's MODCA/IOCA. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOOTON * Several questions to be considered in discussing text conversion +* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON introduced the final topic, text conversion, by noting that it is +becoming an increasingly important part of the imaging business. Many +people now realize that it enhances their system to be able to have more +and more character data as part of their imaging system. Re the issue of +OCR versus rekeying, HOOTON posed several questions: How does one get +text into computer-readable form? Does one use automated processes? +Does one attempt to eliminate the use of operators where possible? +Standards for accuracy, he said, are extremely important: it makes a +major difference in cost and time whether one sets as a standard 98.5 +percent acceptance or 99.5 percent. He mentioned outsourcing as a +possibility for converting text. Finally, what one does with the image +to prepare it for the recognition process is also important, he said, +because such preparation changes how recognition is viewed, as well as +facilitates recognition itself. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +LESK * Roles of participants in CORE * Data flow * The scanning process * +The image interface * Results of experiments involving the use of +electronic resources and traditional paper copies * Testing the issue of +serendipity * Conclusions * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Michael LESK, executive director, Computer Science Research, Bell +Communications Research, Inc. (Bellcore), discussed the Chemical Online +Retrieval Experiment (CORE), a cooperative project involving Cornell +University, OCLC, Bellcore, and the American Chemical Society (ACS). + +LESK spoke on 1) how the scanning was performed, including the unusual +feature of page segmentation, and 2) the use made of the text and the +image in experiments. + +Working with the chemistry journals (because ACS has been saving its +typesetting tapes since the mid-1970s and thus has a significant back-run +of the most important chemistry journals in the United States), CORE is +attempting to create an automated chemical library. Approximately a +quarter of the pages by square inch are made up of images of +quasi-pictorial material; dealing with the graphic components of the +pages is extremely important. LESK described the roles of participants +in CORE: 1) ACS provides copyright permission, journals on paper, +journals on microfilm, and some of the definitions of the files; 2) at +Bellcore, LESK chiefly performs the data preparation, while Dennis Egan +performs experiments on the users of chemical abstracts, and supplies the +indexing and numerous magnetic tapes; 3) Cornell provides the site of the +experiment; 4) OCLC develops retrieval software and other user interfaces. +Various manufacturers and publishers have furnished other help. + +Concerning data flow, Bellcore receives microfilm and paper from ACS; the +microfilm is scanned by outside vendors, while the paper is scanned +inhouse on an Improvision scanner, twenty pages per minute at 300 dpi, +which provides sufficient quality for all practical uses. LESK would +prefer to have more gray level, because one of the ACS journals prints on +some colored pages, which creates a problem. + +Bellcore performs all this scanning, creates a page-image file, and also +selects from the pages the graphics, to mix with the text file (which is +discussed later in the Workshop). The user is always searching the ASCII +file, but she or he may see a display based on the ASCII or a display +based on the images. + +LESK illustrated how the program performs page analysis, and the image +interface. (The user types several words, is presented with a list-- +usually of the titles of articles contained in an issue--that derives +from the ASCII, clicks on an icon and receives an image that mirrors an +ACS page.) LESK also illustrated an alternative interface, based on text +on the ASCII, the so-called SuperBook interface from Bellcore. + +LESK next presented the results of an experiment conducted by Dennis Egan +and involving thirty-six students at Cornell, one third of them +undergraduate chemistry majors, one third senior undergraduate chemistry +majors, and one third graduate chemistry students. A third of them +received the paper journals, the traditional paper copies and chemical +abstracts on paper. A third received image displays of the pictures of +the pages, and a third received the text display with pop-up graphics. + +The students were given several questions made up by some chemistry +professors. The questions fell into five classes, ranging from very easy +to very difficult, and included questions designed to simulate browsing +as well as a traditional information retrieval-type task. + +LESK furnished the following results. In the straightforward question +search--the question being, what is the phosphorus oxygen bond distance +and hydroxy phosphate?--the students were told that they could take +fifteen minutes and, then, if they wished, give up. The students with +paper took more than fifteen minutes on average, and yet most of them +gave up. The students with either electronic format, text or image, +received good scores in reasonable time, hardly ever had to give up, and +usually found the right answer. + +In the browsing study, the students were given a list of eight topics, +told to imagine that an issue of the Journal of the American Chemical +Society had just appeared on their desks, and were also told to flip +through it and to find topics mentioned in the issue. The average scores +were about the same. (The students were told to answer yes or no about +whether or not particular topics appeared.) The errors, however, were +quite different. The students with paper rarely said that something +appeared when it had not. But they often failed to find something +actually mentioned in the issue. The computer people found numerous +things, but they also frequently said that a topic was mentioned when it +was not. (The reason, of course, was that they were performing word +searches. They were finding that words were mentioned and they were +concluding that they had accomplished their task.) + +This question also contained a trick to test the issue of serendipity. +The students were given another list of eight topics and instructed, +without taking a second look at the journal, to recall how many of this +new list of eight topics were in this particular issue. This was an +attempt to see if they performed better at remembering what they were not +looking for. They all performed about the same, paper or electronics, +about 62 percent accurate. In short, LESK said, people were not very +good when it came to serendipity, but they were no worse at it with +computers than they were with paper. + +(LESK gave a parenthetical illustration of the learning curve of students +who used SuperBook.) + +The students using the electronic systems started off worse than the ones +using print, but by the third of the three sessions in the series had +caught up to print. As one might expect, electronics provide a much +better means of finding what one wants to read; reading speeds, once the +object of the search has been found, are about the same. + +Almost none of the students could perform the hard task--the analogous +transformation. (It would require the expertise of organic chemists to +complete.) But an interesting result was that the students using the text +search performed terribly, while those using the image system did best. +That the text search system is driven by text offers the explanation. +Everything is focused on the text; to see the pictures, one must press +on an icon. Many students found the right article containing the answer +to the question, but they did not click on the icon to bring up the right +figure and see it. They did not know that they had found the right place, +and thus got it wrong. + +The short answer demonstrated by this experiment was that in the event +one does not know what to read, one needs the electronic systems; the +electronic systems hold no advantage at the moment if one knows what to +read, but neither do they impose a penalty. + +LESK concluded by commenting that, on one hand, the image system was easy +to use. On the other hand, the text display system, which represented +twenty man-years of work in programming and polishing, was not winning, +because the text was not being read, just searched. The much easier +system is highly competitive as well as remarkably effective for the +actual chemists. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ERWAY * Most challenging aspect of working on AM * Assumptions guiding +AM's approach * Testing different types of service bureaus * AM's +requirement for 99.95 percent accuracy * Requirements for text-coding * +Additional factors influencing AM's approach to coding * Results of AM's +experience with rekeying * Other problems in dealing with service bureaus +* Quality control the most time-consuming aspect of contracting out +conversion * Long-term outlook uncertain * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +To Ricky ERWAY, associate coordinator, American Memory, Library of +Congress, the constant variety of conversion projects taking place +simultaneously represented perhaps the most challenging aspect of working +on AM. Thus, the challenge was not to find a solution for text +conversion but a tool kit of solutions to apply to LC's varied +collections that need to be converted. ERWAY limited her remarks to the +process of converting text to machine-readable form, and the variety of +LC's text collections, for example, bound volumes, microfilm, and +handwritten manuscripts. + +Two assumptions have guided AM's approach, ERWAY said: 1) A desire not +to perform the conversion inhouse. Because of the variety of formats and +types of texts, to capitalize the equipment and have the talents and +skills to operate them at LC would be extremely expensive. Further, the +natural inclination to upgrade to newer and better equipment each year +made it reasonable for AM to focus on what it did best and seek external +conversion services. Using service bureaus also allowed AM to have +several types of operations take place at the same time. 2) AM was not a +technology project, but an effort to improve access to library +collections. Hence, whether text was converted using OCR or rekeying +mattered little to AM. What mattered were cost and accuracy of results. + +AM considered different types of service bureaus and selected three to +perform several small tests in order to acquire a sense of the field. +The sample collections with which they worked included handwritten +correspondence, typewritten manuscripts from the 1940s, and +eighteenth-century printed broadsides on microfilm. On none of these +samples was OCR performed; they were all rekeyed. AM had several special +requirements for the three service bureaus it had engaged. For instance, +any errors in the original text were to be retained. Working from bound +volumes or anything that could not be sheet-fed also constituted a factor +eliminating companies that would have performed OCR. + +AM requires 99.95 percent accuracy, which, though it sounds high, often +means one or two errors per page. The initial batch of test samples +contained several handwritten materials for which AM did not require +text-coding. The results, ERWAY reported, were in all cases fairly +comparable: for the most part, all three service bureaus achieved 99.95 +percent accuracy. AM was satisfied with the work but surprised at the cost. + +As AM began converting whole collections, it retained the requirement for +99.95 percent accuracy and added requirements for text-coding. AM needed +to begin performing work more than three years ago before LC requirements +for SGML applications had been established. Since AM's goal was simply +to retain any of the intellectual content represented by the formatting +of the document (which would be lost if one performed a straight ASCII +conversion), AM used "SGML-like" codes. These codes resembled SGML tags +but were used without the benefit of document-type definitions. AM found +that many service bureaus were not yet SGML-proficient. + +Additional factors influencing the approach AM took with respect to +coding included: 1) the inability of any known microcomputer-based +user-retrieval software to take advantage of SGML coding; and 2) the +multiple inconsistencies in format of the older documents, which +confirmed AM in its desire not to attempt to force the different formats +to conform to a single document-type definition (DTD) and thus create the +need for a separate DTD for each document. + +The five text collections that AM has converted or is in the process of +converting include a collection of eighteenth-century broadsides, a +collection of pamphlets, two typescript document collections, and a +collection of 150 books. + +ERWAY next reviewed the results of AM's experience with rekeying, noting +again that because the bulk of AM's materials are historical, the quality +of the text often does not lend itself to OCR. While non-English +speakers are less likely to guess or elaborate or correct typos in the +original text, they are also less able to infer what we would; they also +are nearly incapable of converting handwritten text. Another +disadvantage of working with overseas keyers is that they are much less +likely to telephone with questions, especially on the coding, with the +result that they develop their own rules as they encounter new +situations. + +Government contracting procedures and time frames posed a major challenge +to performing the conversion. Many service bureaus are not accustomed to +retaining the image, even if they perform OCR. Thus, questions of image +format and storage media were somewhat novel to many of them. ERWAY also +remarked other problems in dealing with service bureaus, for example, +their inability to perform text conversion from the kind of microfilm +that LC uses for preservation purposes. + +But quality control, in ERWAY's experience, was the most time-consuming +aspect of contracting out conversion. AM has been attempting to perform +a 10-percent quality review, looking at either every tenth document or +every tenth page to make certain that the service bureaus are maintaining +99.95 percent accuracy. But even if they are complying with the +requirement for accuracy, finding errors produces a desire to correct +them and, in turn, to clean up the whole collection, which defeats the +purpose to some extent. Even a double entry requires a +character-by-character comparison to the original to meet the accuracy +requirement. LC is not accustomed to publish imperfect texts, which +makes attempting to deal with the industry standard an emotionally +fraught issue for AM. As was mentioned in the previous day's discussion, +going from 99.95 to 99.99 percent accuracy usually doubles costs and +means a third keying or another complete run-through of the text. + +Although AM has learned much from its experiences with various collections +and various service bureaus, ERWAY concluded pessimistically that no +breakthrough has been achieved. Incremental improvements have occurred +in some of the OCR technology, some of the processes, and some of the +standards acceptances, which, though they may lead to somewhat lower costs, +do not offer much encouragement to many people who are anxiously awaiting +the day that the entire contents of LC are available on-line. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +ZIDAR * Several answers to why one attempts to perform full-text +conversion * Per page cost of performing OCR * Typical problems +encountered during editing * Editing poor copy OCR vs. rekeying * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Judith ZIDAR, coordinator, National Agricultural Text Digitizing Program +(NATDP), National Agricultural Library (NAL), offered several answers to +the question of why one attempts to perform full-text conversion: 1) +Text in an image can be read by a human but not by a computer, so of +course it is not searchable and there is not much one can do with it. 2) +Some material simply requires word-level access. For instance, the legal +profession insists on full-text access to its material; with taxonomic or +geographic material, which entails numerous names, one virtually requires +word-level access. 3) Full text permits rapid browsing and searching, +something that cannot be achieved in an image with today's technology. +4) Text stored as ASCII and delivered in ASCII is standardized and highly +portable. 5) People just want full-text searching, even those who do not +know how to do it. NAL, for the most part, is performing OCR at an +actual cost per average-size page of approximately $7. NAL scans the +page to create the electronic image and passes it through the OCR device. + +ZIDAR next rehearsed several typical problems encountered during editing. +Praising the celerity of her student workers, ZIDAR observed that editing +requires approximately five to ten minutes per page, assuming that there +are no large tables to audit. Confusion among the three characters I, 1, +and l, constitutes perhaps the most common problem encountered. Zeroes +and O's also are frequently confused. Double M's create a particular +problem, even on clean pages. They are so wide in most fonts that they +touch, and the system simply cannot tell where one letter ends and the +other begins. Complex page formats occasionally fail to columnate +properly, which entails rescanning as though one were working with a +single column, entering the ASCII, and decolumnating for better +searching. With proportionally spaced text, OCR can have difficulty +discerning what is a space and what are merely spaces between letters, as +opposed to spaces between words, and therefore will merge text or break +up words where it should not. + +ZIDAR said that it can often take longer to edit a poor-copy OCR than to +key it from scratch. NAL has also experimented with partial editing of +text, whereby project workers go into and clean up the format, removing +stray characters but not running a spell-check. NAL corrects typos in +the title and authors' names, which provides a foothold for searching and +browsing. Even extremely poor-quality OCR (e.g., 60-percent accuracy) +can still be searched, because numerous words are correct, while the +important words are probably repeated often enough that they are likely +to be found correct somewhere. Librarians, however, cannot tolerate this +situation, though end users seem more willing to use this text for +searching, provided that NAL indicates that it is unedited. ZIDAR +concluded that rekeying of text may be the best route to take, in spite +of numerous problems with quality control and cost. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Modifying an image before performing OCR * NAL's costs per +page *AM's costs per page and experience with Federal Prison Industries * +Elements comprising NATDP's costs per page * OCR and structured markup * +Distinction between the structure of a document and its representation +when put on the screen or printed * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOOTON prefaced the lengthy discussion that followed with several +comments about modifying an image before one reaches the point of +performing OCR. For example, in regard to an application containing a +significant amount of redundant data, such as form-type data, numerous +companies today are working on various kinds of form renewal, prior to +going through a recognition process, by using dropout colors. Thus, +acquiring access to form design or using electronic means are worth +considering. HOOTON also noted that conversion usually makes or breaks +one's imaging system. It is extremely important, extremely costly in +terms of either capital investment or service, and determines the quality +of the remainder of one's system, because it determines the character of +the raw material used by the system. + +Concerning the four projects undertaken by NAL, two inside and two +performed by outside contractors, ZIDAR revealed that an in-house service +bureau executed the first at a cost between $8 and $10 per page for +everything, including building of the database. The project undertaken +by the Consultative Group on International Agricultural Research (CGIAR) +cost approximately $10 per page for the conversion, plus some expenses +for the software and building of the database. The Acid Rain Project--a +two-disk set produced by the University of Vermont, consisting of +Canadian publications on acid rain--cost $6.70 per page for everything, +including keying of the text, which was double keyed, scanning of the +images, and building of the database. The in-house project offered +considerable ease of convenience and greater control of the process. On +the other hand, the service bureaus know their job and perform it +expeditiously, because they have more people. + +As a useful comparison, ERWAY revealed AM's costs as follows: $0.75 +cents to $0.85 cents per thousand characters, with an average page +containing 2,700 characters. Requirements for coding and imaging +increase the costs. Thus, conversion of the text, including the coding, +costs approximately $3 per page. (This figure does not include the +imaging and database-building included in the NAL costs.) AM also +enjoyed a happy experience with Federal Prison Industries, which +precluded the necessity of going through the request-for-proposal process +to award a contract, because it is another government agency. The +prisoners performed AM's rekeying just as well as other service bureaus +and proved handy as well. AM shipped them the books, which they would +photocopy on a book-edge scanner. They would perform the markup on +photocopies, return the books as soon as they were done with them, +perform the keying, and return the material to AM on WORM disks. + +ZIDAR detailed the elements that constitute the previously noted cost of +approximately $7 per page. Most significant is the editing, correction +of errors, and spell-checkings, which though they may sound easy to +perform require, in fact, a great deal of time. Reformatting text also +takes a while, but a significant amount of NAL's expenses are for equipment, +which was extremely expensive when purchased because it was one of the few +systems on the market. The costs of equipment are being amortized over +five years but are still quite high, nearly $2,000 per month. + +HOCKEY raised a general question concerning OCR and the amount of editing +required (substantial in her experience) to generate the kind of +structured markup necessary for manipulating the text on the computer or +loading it into any retrieval system. She wondered if the speakers could +extend the previous question about the cost-benefit of adding or exerting +structured markup. ERWAY noted that several OCR systems retain italics, +bolding, and other spatial formatting. While the material may not be in +the format desired, these systems possess the ability to remove the +original materials quickly from the hands of the people performing the +conversion, as well as to retain that information so that users can work +with it. HOCKEY rejoined that the current thinking on markup is that one +should not say that something is italic or bold so much as why it is that +way. To be sure, one needs to know that something was italicized, but +how can one get from one to the other? One can map from the structure to +the typographic representation. + +FLEISCHHAUER suggested that, given the 100 million items the Library +holds, it may not be possible for LC to do more than report that a thing +was in italics as opposed to why it was italics, although that may be +desirable in some contexts. Promising to talk a bit during the afternoon +session about several experiments OCLC performed on automatic recognition +of document elements, and which they hoped to extend, WEIBEL said that in +fact one can recognize the major elements of a document with a fairly +high degree of reliability, at least as good as OCR. STEVENS drew a +useful distinction between standard, generalized markup (i.e., defining +for a document-type definition the structure of the document), and what +he termed a style sheet, which had to do with italics, bolding, and other +forms of emphasis. Thus, two different components are at work, one being +the structure of the document itself (its logic), and the other being its +representation when it is put on the screen or printed. + + ****** + +SESSION V. APPROACHES TO PREPARING ELECTRONIC TEXTS + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +HOCKEY * Text in ASCII and the representation of electronic text versus +an image * The need to look at ways of using markup to assist retrieval * +The need for an encoding format that will be reusable and multifunctional ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Susan HOCKEY, director, Center for Electronic Texts in the Humanities +(CETH), Rutgers and Princeton Universities, announced that one talk +(WEIBEL's) was moved into this session from the morning and that David +Packard was unable to attend. The session would attempt to focus more on +what one can do with a text in ASCII and the representation of electronic +text rather than just an image, what one can do with a computer that +cannot be done with a book or an image. It would be argued that one can +do much more than just read a text, and from that starting point one can +use markup and methods of preparing the text to take full advantage of +the capability of the computer. That would lead to a discussion of what +the European Community calls REUSABILITY, what may better be termed +DURABILITY, that is, how to prepare or make a text that will last a long +time and that can be used for as many applications as possible, which +would lead to issues of improving intellectual access. + +HOCKEY urged the need to look at ways of using markup to facilitate retrieval, +not just for referencing or to help locate an item that is retrieved, but also to put markup tags in +a text to help retrieve the thing sought either with linguistic tagging or +interpretation. HOCKEY also argued that little advancement had occurred in +the software tools currently available for retrieving and searching text. +She pressed the desideratum of going beyond Boolean searches and performing +more sophisticated searching, which the insertion of more markup in the text +would facilitate. Thinking about electronic texts as opposed to images means +considering material that will never appear in print form, or print will not +be its primary form, that is, material which only appears in electronic form. +HOCKEY alluded to the history and the need for markup and tagging and +electronic text, which was developed through the use of computers in the +humanities; as MICHELSON had observed, Father Busa had started in 1949 +to prepare the first-ever text on the computer. + +HOCKEY remarked several large projects, particularly in Europe, for the +compilation of dictionaries, language studies, and language analysis, in +which people have built up archives of text and have begun to recognize +the need for an encoding format that will be reusable and multifunctional, +that can be used not just to print the text, which may be assumed to be a +byproduct of what one wants to do, but to structure it inside the computer +so that it can be searched, built into a Hypertext system, etc. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +WEIBEL * OCLC's approach to preparing electronic text: retroconversion, +keying of texts, more automated ways of developing data * Project ADAPT +and the CORE Project * Intelligent character recognition does not exist * +Advantages of SGML * Data should be free of procedural markup; +descriptive markup strongly advocated * OCLC's interface illustrated * +Storage requirements and costs for putting a lot of information on line * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Stuart WEIBEL, senior research scientist, Online Computer Library Center, +Inc. (OCLC), described OCLC's approach to preparing electronic text. He +argued that the electronic world into which we are moving must +accommodate not only the future but the past as well, and to some degree +even the present. Thus, starting out at one end with retroconversion and +keying of texts, one would like to move toward much more automated ways +of developing data. + +For example, Project ADAPT had to do with automatically converting +document images into a structured document database with OCR text as +indexing and also a little bit of automatic formatting and tagging of +that text. The CORE project hosted by Cornell University, Bellcore, +OCLC, the American Chemical Society, and Chemical Abstracts, constitutes +WEIBEL's principal concern at the moment. This project is an example of +converting text for which one already has a machine-readable version into +a format more suitable for electronic delivery and database searching. +(Since Michael LESK had previously described CORE, WEIBEL would say +little concerning it.) Borrowing a chemical phrase, de novo synthesis, +WEIBEL cited the Online Journal of Current Clinical Trials as an example +of de novo electronic publishing, that is, a form in which the primary +form of the information is electronic. + +Project ADAPT, then, which OCLC completed a couple of years ago and in +fact is about to resume, is a model in which one takes page images either +in paper or microfilm and converts them automatically to a searchable +electronic database, either on-line or local. The operating assumption +is that accepting some blemishes in the data, especially for +retroconversion of materials, will make it possible to accomplish more. +Not enough money is available to support perfect conversion. + +WEIBEL related several steps taken to perform image preprocessing +(processing on the image before performing optical character +recognition), as well as image postprocessing. He denied the existence +of intelligent character recognition and asserted that what is wanted is +page recognition, which is a long way off. OCLC has experimented with +merging of multiple optical character recognition systems that will +reduce errors from an unacceptable rate of 5 characters out of every +l,000 to an unacceptable rate of 2 characters out of every l,000, but it +is not good enough. It will never be perfect. + +Concerning the CORE Project, WEIBEL observed that Bellcore is taking the +topography files, extracting the page images, and converting those +topography files to SGML markup. LESK hands that data off to OCLC, which +builds that data into a Newton database, the same system that underlies +the on-line system in virtually all of the reference products at OCLC. +The long-term goal is to make the systems interoperable so that not just +Bellcore's system and OCLC's system can access this data, but other +systems can as well, and the key to that is the Z39.50 common command +language and the full-text extension. Z39.50 is fine for MARC records, +but is not enough to do it for full text (that is, make full texts +interoperable). + +WEIBEL next outlined the critical role of SGML for a variety of purposes, +for example, as noted by HOCKEY, in the world of extremely large +databases, using highly structured data to perform field searches. +WEIBEL argued that by building the structure of the data in (i.e., the +structure of the data originally on a printed page), it becomes easy to +look at a journal article even if one cannot read the characters and know +where the title or author is, or what the sections of that document would be. +OCLC wants to make that structure explicit in the database, because it will +be important for retrieval purposes. + +The second big advantage of SGML is that it gives one the ability to +build structure into the database that can be used for display purposes +without contaminating the data with instructions about how to format +things. The distinction lies between procedural markup, which tells one +where to put dots on the page, and descriptive markup, which describes +the elements of a document. + +WEIBEL believes that there should be no procedural markup in the data at +all, that the data should be completely unsullied by information about +italics or boldness. That should be left up to the display device, +whether that display device is a page printer or a screen display device. +By keeping one's database free of that kind of contamination, one can +make decisions down the road, for example, reorganize the data in ways +that are not cramped by built-in notions of what should be italic and +what should be bold. WEIBEL strongly advocated descriptive markup. As +an example, he illustrated the index structure in the CORE data. With +subsequent illustrated examples of markup, WEIBEL acknowledged the common +complaint that SGML is hard to read in its native form, although markup +decreases considerably once one gets into the body. Without the markup, +however, one would not have the structure in the data. One can pass +markup through a LaTeX processor and convert it relatively easily to a +printed version of the document. + +WEIBEL next illustrated an extremely cluttered screen dump of OCLC's +system, in order to show as much as possible the inherent capability on +the screen. (He noted parenthetically that he had become a supporter of +X-Windows as a result of the progress of the CORE Project.) WEIBEL also +illustrated the two major parts of the interface: l) a control box that +allows one to generate lists of items, which resembles a small table of +contents based on key words one wishes to search, and 2) a document +viewer, which is a separate process in and of itself. He demonstrated +how to follow links through the electronic database simply by selecting +the appropriate button and bringing them up. He also noted problems that +remain to be accommodated in the interface (e.g., as pointed out by LESK, +what happens when users do not click on the icon for the figure). + +Given the constraints of time, WEIBEL omitted a large number of ancillary +items in order to say a few words concerning storage requirements and +what will be required to put a lot of things on line. Since it is +extremely expensive to reconvert all of this data, especially if it is +just in paper form (and even if it is in electronic form in typesetting +tapes), he advocated building journals electronically from the start. In +that case, if one only has text graphics and indexing (which is all that +one needs with de novo electronic publishing, because there is no need to +go back and look at bit-maps of pages), one can get 10,000 journals of +full text, or almost 6 million pages per year. These pages can be put in +approximately 135 gigabytes of storage, which is not all that much, +WEIBEL said. For twenty years, something less than three terabytes would +be required. WEIBEL calculated the costs of storing this information as +follows: If a gigabyte costs approximately $1,000, then a terabyte costs +approximately $1 million to buy in terms of hardware. One also needs a +building to put it in and a staff like OCLC to handle that information. +So, to support a terabyte, multiply by five, which gives $5 million per +year for a supported terabyte of data. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Tapes saved by ACS are the typography files originally +supporting publication of the journal * Cost of building tagged text into +the database * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the question-and-answer period that followed WEIBEL's +presentation, these clarifications emerged. The tapes saved by the +American Chemical Society are the typography files that originally +supported the publication of the journal. Although they are not tagged +in SGML, they are tagged in very fine detail. Every single sentence is +marked, all the registry numbers, all the publications issues, dates, and +volumes. No cost figures on tagging material on a per-megabyte basis +were available. Because ACS's typesetting system runs from tagged text, +there is no extra cost per article. It was unknown what it costs ACS to +keyboard the tagged text rather than just keyboard the text in the +cheapest process. In other words, since one intends to publish things +and will need to build tagged text into a typography system in any case, +if one does that in such a way that it can drive not only typography but +an electronic system (which is what ACS intends to do--move to SGML +publishing), the marginal cost is zero. The marginal cost represents the +cost of building tagged text into the database, which is small. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +SPERBERG-McQUEEN * Distinction between texts and computers * Implications +of recognizing that all representation is encoding * Dealing with +complicated representations of text entails the need for a grammar of +documents * Variety of forms of formal grammars * Text as a bit-mapped +image does not represent a serious attempt to represent text in +electronic form * SGML, the TEI, document-type declarations, and the +reusability and longevity of data * TEI conformance explicitly allows +extension or modification of the TEI tag set * Administrative background +of the TEI * Several design goals for the TEI tag set * An absolutely +fixed requirement of the TEI Guidelines * Challenges the TEI has +attempted to face * Good texts not beyond economic feasibility * The +issue of reproducibility or processability * The issue of mages as +simulacra for the text redux * One's model of text determines what one's +software can do with a text and has economic consequences * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Prior to speaking about SGML and markup, Michael SPERBERG-McQUEEN, editor, +Text Encoding Initiative (TEI), University of Illinois-Chicago, first drew +a distinction between texts and computers: Texts are abstract cultural +and linguistic objects while computers are complicated physical devices, +he said. Abstract objects cannot be placed inside physical devices; with +computers one can only represent text and act upon those representations. + +The recognition that all representation is encoding, SPERBERG-McQUEEN +argued, leads to the recognition of two things: 1) The topic description +for this session is slightly misleading, because there can be no discussion +of pros and cons of text-coding unless what one means is pros and cons of +working with text with computers. 2) No text can be represented in a +computer without some sort of encoding; images are one way of encoding text, +ASCII is another, SGML yet another. There is no encoding without some +information loss, that is, there is no perfect reproduction of a text that +allows one to do away with the original. Thus, the question becomes, +What is the most useful representation of text for a serious work? +This depends on what kind of serious work one is talking about. + +The projects demonstrated the previous day all involved highly complex +information and fairly complex manipulation of the textual material. +In order to use that complicated information, one has to calculate it +slowly or manually and store the result. It needs to be stored, therefore, +as part of one's representation of the text. Thus, one needs to store the +structure in the text. To deal with complicated representations of text, +one needs somehow to control the complexity of the representation of a text; +that means one needs a way of finding out whether a document and an +electronic representation of a document is legal or not; and that +means one needs a grammar of documents. + +SPERBERG-McQUEEN discussed the variety of forms of formal grammars, +implicit and explicit, as applied to text, and their capabilities. He +argued that these grammars correspond to different models of text that +different developers have. For example, one implicit model of the text +is that there is no internal structure, but just one thing after another, +a few characters and then perhaps a start-title command, and then a few +more characters and an end-title command. SPERBERG-McQUEEN also +distinguished several kinds of text that have a sort of hierarchical +structure that is not very well defined, which, typically, corresponds +to grammars that are not very well defined, as well as hierarchies that +are very well defined (e.g., the Thesaurus Linguae Graecae) and extremely +complicated things such as SGML, which handle strictly hierarchical data +very nicely. + +SPERBERG-McQUEEN conceded that one other model not illustrated on his two +displays was the model of text as a bit-mapped image, an image of a page, +and confessed to having been converted to a limited extent by the +Workshop to the view that electronic images constitute a promising, +probably superior alternative to microfilming. But he was not convinced +that electronic images represent a serious attempt to represent text in +electronic form. Many of their problems stem from the fact that they are +not direct attempts to represent the text but attempts to represent the +page, thus making them representations of representations. + +In this situation of increasingly complicated textual information and the +need to control that complexity in a useful way (which begs the question +of the need for good textual grammars), one has the introduction of SGML. +With SGML, one can develop specific document-type declarations +for specific text types or, as with the TEI, attempts to generate +general document-type declarations that can handle all sorts of text. +The TEI is an attempt to develop formats for text representation that +will ensure the kind of reusability and longevity of data discussed earlier. +It offers a way to stay alive in the state of permanent technological +revolution. + +It has been a continuing challenge in the TEI to create document grammars +that do some work in controlling the complexity of the textual object but +also allowing one to represent the real text that one will find. +Fundamental to the notion of the TEI is that TEI conformance allows one +the ability to extend or modify the TEI tag set so that it fits the text +that one is attempting to represent. + +SPERBERG-McQUEEN next outlined the administrative background of the TEI. +The TEI is an international project to develop and disseminate guidelines +for the encoding and interchange of machine-readable text. It is +sponsored by the Association for Computers in the Humanities, the +Association for Computational Linguistics, and the Association for +Literary and Linguistic Computing. Representatives of numerous other +professional societies sit on its advisory board. The TEI has a number +of affiliated projects that have provided assistance by testing drafts of +the guidelines. + +Among the design goals for the TEI tag set, the scheme first of all must +meet the needs of research, because the TEI came out of the research +community, which did not feel adequately served by existing tag sets. +The tag set must be extensive as well as compatible with existing and +emerging standards. In 1990, version 1.0 of the Guidelines was released +(SPERBERG-McQUEEN illustrated their contents). + +SPERBERG-McQUEEN noted that one problem besetting electronic text has +been the lack of adequate internal or external documentation for many +existing electronic texts. The TEI guidelines as currently formulated +contain few fixed requirements, but one of them is this: There must +always be a document header, an in-file SGML tag that provides +1) a bibliographic description of the electronic object one is talking +about (that is, who included it, when, what for, and under which title); +and 2) the copy text from which it was derived, if any. If there was +no copy text or if the copy text is unknown, then one states as much. +Version 2.0 of the Guidelines was scheduled to be completed in fall 1992 +and a revised third version is to be presented to the TEI advisory board +for its endorsement this coming winter. The TEI itself exists to provide +a markup language, not a marked-up text. + +Among the challenges the TEI has attempted to face is the need for a +markup language that will work for existing projects, that is, handle the +level of markup that people are using now to tag only chapter, section, +and paragraph divisions and not much else. At the same time, such a +language also will be able to scale up gracefully to handle the highly +detailed markup which many people foresee as the future destination of +much electronic text, and which is not the future destination but the +present home of numerous electronic texts in specialized areas. + +SPERBERG-McQUEEN dismissed the lowest-common-denominator approach as +unable to support the kind of applications that draw people who have +never been in the public library regularly before, and make them come +back. He advocated more interesting text and more intelligent text. +Asserting that it is not beyond economic feasibility to have good texts, +SPERBERG-McQUEEN noted that the TEI Guidelines listing 200-odd tags +contains tags that one is expected to enter every time the relevant +textual feature occurs. It contains all the tags that people need now, +and it is not expected that everyone will tag things in the same way. + +The question of how people will tag the text is in large part a function +of their reaction to what SPERBERG-McQUEEN termed the issue of +reproducibility. What one needs to be able to reproduce are the things +one wants to work with. Perhaps a more useful concept than that of +reproducibility or recoverability is that of processability, that is, +what can one get from an electronic text without reading it again +in the original. He illustrated this contention with a page from +Jan Comenius's bilingual Introduction to Latin. + +SPERBERG-McQUEEN returned at length to the issue of images as simulacra +for the text, in order to reiterate his belief that in the long run more +than images of pages of particular editions of the text are needed, +because just as second-generation photocopies and second-generation +microfilm degenerate, so second-generation representations tend to +degenerate, and one tends to overstress some relatively trivial aspects +of the text such as its layout on the page, which is not always +significant, despite what the text critics might say, and slight other +pieces of information such as the very important lexical ties between the +English and Latin versions of Comenius's bilingual text, for example. +Moreover, in many crucial respects it is easy to fool oneself concerning +what a scanned image of the text will accomplish. For example, in order +to study the transmission of texts, information concerning the text +carrier is necessary, which scanned images simply do not always handle. +Further, even the high-quality materials being produced at Cornell use +much of the information that one would need if studying those books as +physical objects. It is a choice that has been made. It is an arguably +justifiable choice, but one does not know what color those pen strokes in +the margin are or whether there was a stain on the page, because it has +been filtered out. One does not know whether there were rips in the page +because they do not show up, and on a couple of the marginal marks one +loses half of the mark because the pen is very light and the scanner +failed to pick it up, and so what is clearly a checkmark in the margin of +the original becomes a little scoop in the margin of the facsimile. +Standard problems for facsimile editions, not new to electronics, but +also true of light-lens photography, and are remarked here because it is +important that we not fool ourselves that even if we produce a very nice +image of this page with good contrast, we are not replacing the +manuscript any more than microfilm has replaced the manuscript. + +The TEI comes from the research community, where its first allegiance +lies, but it is not just an academic exercise. It has relevance far +beyond those who spend all of their time studying text, because one's +model of text determines what one's software can do with a text. Good +models lead to good software. Bad models lead to bad software. That has +economic consequences, and it is these economic consequences that have +led the European Community to help support the TEI, and that will lead, +SPERBERG-McQUEEN hoped, some software vendors to realize that if they +provide software with a better model of the text they can make a killing. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Implications of different DTDs and tag sets * ODA versus SGML * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +During the discussion that followed, several additional points were made. +Neither AAP (i.e., Association of American Publishers) nor CALS (i.e., +Computer-aided Acquisition and Logistics Support) has a document-type +definition for ancient Greek drama, although the TEI will be able to +handle that. Given this state of affairs and assuming that the +technical-journal producers and the commercial vendors decide to use the +other two types, then an institution like the Library of Congress, which +might receive all of their publications, would have to be able to handle +three different types of document definitions and tag sets and be able to +distinguish among them. + +Office Document Architecture (ODA) has some advantages that flow from its +tight focus on office documents and clear directions for implementation. +Much of the ODA standard is easier to read and clearer at first reading +than the SGML standard, which is extremely general. What that means is +that if one wants to use graphics in TIFF and ODA, one is stuck, because +ODA defines graphics formats while TIFF does not, whereas SGML says the +world is not waiting for this work group to create another graphics format. +What is needed is an ability to use whatever graphics format one wants. + +The TEI provides a socket that allows one to connect the SGML document to +the graphics. The notation that the graphics are in is clearly a choice +that one needs to make based on her or his environment, and that is one +advantage. SGML is less megalomaniacal in attempting to define formats +for all kinds of information, though more megalomaniacal in attempting to +cover all sorts of documents. The other advantage is that the model of +text represented by SGML is simply an order of magnitude richer and more +flexible than the model of text offered by ODA. Both offer hierarchical +structures, but SGML recognizes that the hierarchical model of the text +that one is looking at may not have been in the minds of the designers, +whereas ODA does not. + +ODA is not really aiming for the kind of document that the TEI wants to +encompass. The TEI can handle the kind of material ODA has, as well as a +significantly broader range of material. ODA seems to be very much +focused on office documents, which is what it started out being called-- +office document architecture. + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +CALALUCA * Text-encoding from a publisher's perspective * +Responsibilities of a publisher * Reproduction of Migne's Latin series +whole and complete with SGML tags based on perceived need and expected +use * Particular decisions arising from the general decision to produce +and publish PLD * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +The final speaker in this session, Eric CALALUCA, vice president, +Chadwyck-Healey, Inc., spoke from the perspective of a publisher re +text-encoding, rather than as one qualified to discuss methods of +encoding data, and observed that the presenters sitting in the room, +whether they had chosen to or not, were acting as publishers: making +choices, gathering data, gathering information, and making assessments. +CALALUCA offered the hard-won conviction that in publishing very large +text files (such as PLD), one cannot avoid making personal judgments of +appropriateness and structure. + +In CALALUCA's view, encoding decisions stem from prior judgments. Two +notions have become axioms for him in the consideration of future sources +for electronic publication: 1) electronic text publishing is as personal +as any other kind of publishing, and questions of if and how to encode +the data are simply a consequence of that prior decision; 2) all +personal decisions are open to criticism, which is unavoidable. + +CALALUCA rehearsed his role as a publisher or, better, as an intermediary +between what is viewed as a sound idea and the people who would make use +of it. Finding the specialist to advise in this process is the core of +that function. The publisher must monitor and hug the fine line between +giving users what they want and suggesting what they might need. One +responsibility of a publisher is to represent the desires of scholars and +research librarians as opposed to bullheadedly forcing them into areas +they would not choose to enter. + +CALALUCA likened the questions being raised today about data structure +and standards to the decisions faced by the Abbe Migne himself during +production of the Patrologia series in the mid-nineteenth century. +Chadwyck-Healey's decision to reproduce Migne's Latin series whole and +complete with SGML tags was also based upon a perceived need and an +expected use. In the same way that Migne's work came to be far more than +a simple handbook for clerics, PLD is already far more than a database +for theologians. It is a bedrock source for the study of Western +civilization, CALALUCA asserted. + +In regard to the decision to produce and publish PLD, the editorial board +offered direct judgments on the question of appropriateness of these +texts for conversion, their encoding and their distribution, and +concluded that the best possible project was one that avoided overt +intrusions or exclusions in so important a resource. Thus, the general +decision to transmit the original collection as clearly as possible with +the widest possible avenues for use led to other decisions: 1) To encode +the data or not, SGML or not, TEI or not. Again, the expected user +community asserted the need for normative tagging structures of important +humanities texts, and the TEI seemed the most appropriate structure for +that purpose. Research librarians, who are trained to view the larger +impact of electronic text sources on 80 or 90 or 100 doctoral +disciplines, loudly approved the decision to include tagging. They see +what is coming better than the specialist who is completely focused on +one edition of Ambrose's De Anima, and they also understand that the +potential uses exceed present expectations. 2) What will be tagged and +what will not. Once again, the board realized that one must tag the +obvious. But in no way should one attempt to identify through encoding +schemes every single discrete area of a text that might someday be +searched. That was another decision. Searching by a column number, an +author, a word, a volume, permitting combination searches, and tagging +notations seemed logical choices as core elements. 3) How does one make +the data available? Tying it to a CD-ROM edition creates limitations, +but a magnetic tape file that is very large, is accompanied by the +encoding specifications, and that allows one to make local modifications +also allows one to incorporate any changes one may desire within the +bounds of private research, though exporting tag files from a CD-ROM +could serve just as well. Since no one on the board could possibly +anticipate each and every way in which a scholar might choose to mine +this data bank, it was decided to satisfy the basics and make some +provisions for what might come. 4) Not to encode the database would rob +it of the interchangeability and portability these important texts should +accommodate. For CALALUCA, the extensive options presented by full-text +searching require care in text selection and strongly support encoding of +data to facilitate the widest possible search strategies. Better +software can always be created, but summoning the resources, the people, +and the energy to reconvert the text is another matter. + +PLD is being encoded, captured, and distributed, because to +Chadwyck-Healey and the board it offers the widest possible array of +future research applications that can be seen today. CALALUCA concluded +by urging the encoding of all important text sources in whatever way +seems most appropriate and durable at the time, without blanching at the +thought that one's work may require emendation in the future. (Thus, +Chadwyck-Healey produced a very large humanities text database before the +final release of the TEI Guidelines.) + + ****** + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +DISCUSSION * Creating texts with markup advocated * Trends in encoding * +The TEI and the issue of interchangeability of standards * A +misconception concerning the TEI * Implications for an institution like +LC in the event that a multiplicity of DTDs develops * Producing images +as a first step towards possible conversion to full text through +character recognition * The AAP tag sets as a common starting point and +the need for caution * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +HOCKEY prefaced the discussion that followed with several comments in +favor of creating texts with markup and on trends in encoding. In the +future, when many more texts are available for on-line searching, real +problems in finding what is wanted will develop, if one is faced with +millions of words of data. It therefore becomes important to consider +putting markup in texts to help searchers home in on the actual things +they wish to retrieve. Various approaches to refining retrieval methods +toward this end include building on a computer version of a dictionary +and letting the computer look up words in it to obtain more information +about the semantic structure or semantic field of a word, its grammatical +structure, and syntactic structure. + +HOCKEY commented on the present keen interest in the encoding world +in creating: 1) machine-readable versions of dictionaries that can be +initially tagged in SGML, which gives a structure to the dictionary entry; +these entries can then be converted into a more rigid or otherwise +different database structure inside the computer, which can be treated as +a dynamic tool for searching mechanisms; 2) large bodies of text to study +the language. In order to incorporate more sophisticated mechanisms, +more about how words behave needs to be known, which can be learned in +part from information in dictionaries. However, the last ten years have +seen much interest in studying the structure of printed dictionaries +converted into computer-readable form. The information one derives about +many words from those is only partial, one or two definitions of the +common or the usual meaning of a word, and then numerous definitions of +unusual usages. If the computer is using a dictionary to help retrieve +words in a text, it needs much more information about the common usages, +because those are the ones that occur over and over again. Hence the +current interest in developing large bodies of text in computer-readable +form in order to study the language. Several projects are engaged in +compiling, for example, 100 million words. HOCKEY described one with +which she was associated briefly at Oxford University involving +compilation of 100 million words of British English: about 10 percent of +that will contain detailed linguistic tagging encoded in SGML; it will +have word class taggings, with words identified as nouns, verbs, +adjectives, or other parts of speech. This tagging can then be used by +programs which will begin to learn a bit more about the structure of the +language, and then, can go to tag more text. + +HOCKEY said that the more that is tagged accurately, the more one can +refine the tagging process and thus the bigger body of text one can build +up with linguistic tagging incorporated into it. Hence, the more tagging +or annotation there is in the text, the more one may begin to learn about +language and the more it will help accomplish more intelligent OCR. She +recommended the development of software tools that will help one begin to +understand more about a text, which can then be applied to scanning +images of that text in that format and to using more intelligence to help +one interpret or understand the text. + +HOCKEY posited the need to think about common methods of text-encoding +for a long time to come, because building these large bodies of text is +extremely expensive and will only be done once. + +In the more general discussion on approaches to encoding that followed, +these points were made: + +BESSER identified the underlying problem with standards that all have to +struggle with in adopting a standard, namely, the tension between a very +highly defined standard that is very interchangeable but does not work +for everyone because something is lacking, and a standard that is less +defined, more open, more adaptable, but less interchangeable. Contending +that the way in which people use SGML is not sufficiently defined, BESSER +wondered 1) if people resist the TEI because they think it is too defined +in certain things they do not fit into, and 2) how progress with +interchangeability can be made without frightening people away. + +SPERBERG-McQUEEN replied that the published drafts of the TEI had met +with surprisingly little objection on the grounds that they do not allow +one to handle X or Y or Z. Particular concerns of the affiliated +projects have led, in practice, to discussions of how extensions are to +be made; the primary concern of any project has to be how it can be +represented locally, thus making interchange secondary. The TEI has +received much criticism based on the notion that everything in it is +required or even recommended, which, as it happens, is a misconception +from the beginning, because none of it is required and very little is +actually actively recommended for all cases, except that one document +one's source. + +SPERBERG-McQUEEN agreed with BESSER about this trade-off: all the +projects in a set of twenty TEI-conformant projects will not necessarily +tag the material in the same way. One result of the TEI will be that the +easiest problems will be solved--those dealing with the external form of +the information; but the problem that is hardest in interchange is that +one is not encoding what another wants, and vice versa. Thus, after +the adoption of a common notation, the differences in the underlying +conceptions of what is interesting about texts become more visible. +The success of a standard like the TEI will lie in the ability of +the recipient of interchanged texts to use some of what it contains +and to add the information that was not encoded that one wants, in a +layered way, so that texts can be gradually enriched and one does not +have to put in everything all at once. Hence, having a well-behaved +markup scheme is important. + +STEVENS followed up on the paradoxical analogy that BESSER alluded to in +the example of the MARC records, namely, the formats that are the same +except that they are different. STEVENS drew a parallel between +document-type definitions and MARC records for books and serials and maps, +where one has a tagging structure and there is a text-interchange. +STEVENS opined that the producers of the information will set the terms +for the standard (i.e., develop document-type definitions for the users +of their products), creating a situation that will be problematical for +an institution like the Library of Congress, which will have to deal with +the DTDs in the event that a multiplicity of them develops. Thus, +numerous people are seeking a standard but cannot find the tag set that +will be acceptable to them and their clients. SPERBERG-McQUEEN agreed +with this view, and said that the situation was in a way worse: attempting +to unify arbitrary DTDs resembled attempting to unify a MARC record with a +bibliographic record done according to the Prussian instructions. +According to STEVENS, this situation occurred very early in the process. + +WATERS recalled from early discussions on Project Open Book the concern +of many people that merely by producing images, POB was not really +enhancing intellectual access to the material. Nevertheless, not wishing +to overemphasize the opposition between imaging and full text, WATERS +stated that POB views getting the images as a first step toward possibly +converting to full text through character recognition, if the technology +is appropriate. WATERS also emphasized that encoding is involved even +with a set of images. + +SPERBERG-McQUEEN agreed with WATERS that one can create an SGML document +consisting wholly of images. At first sight, organizing graphic images +with an SGML document may not seem to offer great advantages, but the +advantages of the scheme WATERS described would be precisely that +ability to move into something that is more of a multimedia document: +a combination of transcribed text and page images. WEIBEL concurred in +this judgment, offering evidence from Project ADAPT, where a page is +divided into text elements and graphic elements, and in fact the text +elements are organized by columns and lines. These lines may be used as +the basis for distributing documents in a network environment. As one +develops software intelligent enough to recognize what those elements +are, it makes sense to apply SGML to an image initially, that may, in +fact, ultimately become more and more text, either through OCR or edited +OCR or even just through keying. For WATERS, the labor of composing the +document and saying this set of documents or this set of images belongs +to this document constitutes a significant investment. + +WEIBEL also made the point that the AAP tag sets, while not excessively +prescriptive, offer a common starting point; they do not define the +structure of the documents, though. They have some recommendations about +DTDs one could use as examples, but they do just suggest tag sets. For +example, the CORE project attempts to use the AAP markup as much as +possible, but there are clearly areas where structure must be added. +That in no way contradicts the use of AAP tag sets. + +SPERBERG-McQUEEN noted that the TEI prepared a long working paper early +on about the AAP tag set and what it lacked that the TEI thought it +needed, and a fairly long critique of the naming conventions, which has +led to a very different style of naming in the TEI. He stressed the +importance of the opposition between prescriptive markup, the kind that a +publisher or anybody can do when producing documents de novo, and +descriptive markup, in which one has to take what the text carrier +provides. In these particular tag sets it is easy to overemphasize this +opposition, because the AAP tag set is extremely flexible. Even if one +just used the DTDs, they allow almost anything to appear almost anywhere. + + ****** + +SESSION VI. COPYRIGHT ISSUES + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PETERS * Several cautions concerning copyright in an electronic +environment * Review of copyright law in the United States * The notion +of the public good and the desirability of incentives to promote it * +What copyright protects * Works not protected by copyright * The rights +of copyright holders * Publishers' concerns in today's electronic +environment * Compulsory licenses * The price of copyright in a digital +medium and the need for cooperation * Additional clarifications * Rough +justice oftentimes the outcome in numerous copyright matters * Copyright +in an electronic society * Copyright law always only sets up the +boundaries; anything can be changed by contract * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +Marybeth PETERS, policy planning adviser to the Register of Copyrights, +Library of Congress, made several general comments and then opened the +floor to discussion of subjects of interest to the audience. + +Having attended several sessions in an effort to gain a sense of what +people did and where copyright would affect their lives, PETERS expressed +the following cautions: + + * If one takes and converts materials and puts them in new forms, + then, from a copyright point of view, one is creating something and + will receive some rights. + + * However, if what one is converting already exists, a question + immediately arises about the status of the materials in question. + + * Putting something in the public domain in the United States offers + some freedom from anxiety, but distributing it throughout the world + on a network is another matter, even if one has put it in the public + domain in the United States. Re foreign laws, very frequently a + work can be in the public domain in the United States but protected + in other countries. Thus, one must consider all of the places a + work may reach, lest one unwittingly become liable to being faced + with a suit for copyright infringement, or at least a letter + demanding discussion of what one is doing. + +PETERS reviewed copyright law in the United States. The U.S. +Constitution effectively states that Congress has the power to enact +copyright laws for two purposes: 1) to encourage the creation and +dissemination of intellectual works for the good of society as a whole; +and, significantly, 2) to give creators and those who package and +disseminate materials the economic rewards that are due them. + +Congress strives to strike a balance, which at times can become an +emotional issue. The United States has never accepted the notion of the +natural right of an author so much as it has accepted the notion of the +public good and the desirability of incentives to promote it. This state +of affairs, however, has created strains on the international level and +is the reason for several of the differences in the laws that we have. +Today the United States protects almost every kind of work that can be +called an expression of an author. The standard for gaining copyright +protection is simply originality. This is a low standard and means that +a work is not copied from something else, as well as shows a certain +minimal amount of authorship. One can also acquire copyright protection +for making a new version of preexisting material, provided it manifests +some spark of creativity. + +However, copyright does not protect ideas, methods, systems--only the way +that one expresses those things. Nor does copyright protect anything +that is mechanical, anything that does not involve choice, or criteria +concerning whether or not one should do a thing. For example, the +results of a process called declicking, in which one mechanically removes +impure sounds from old recordings, are not copyrightable. On the other +hand, the choice to record a song digitally and to increase the sound of +violins or to bring up the tympani constitutes the results of conversion +that are copyrightable. Moreover, if a work is protected by copyright in +the United States, one generally needs the permission of the copyright +owner to convert it. Normally, who will own the new--that is, converted- +-material is a matter of contract. In the absence of a contract, the +person who creates the new material is the author and owner. But people +do not generally think about the copyright implications until after the +fact. PETERS stressed the need when dealing with copyrighted works to +think about copyright in advance. One's bargaining power is much greater +up front than it is down the road. + +PETERS next discussed works not protected by copyright, for example, any +work done by a federal employee as part of his or her official duties is +in the public domain in the United States. The issue is not wholly free +of doubt concerning whether or not the work is in the public domain +outside the United States. Other materials in the public domain include: +any works published more than seventy-five years ago, and any work +published in the United States more than twenty-eight years ago, whose +copyright was not renewed. In talking about the new technology and +putting material in a digital form to send all over the world, PETERS +cautioned, one must keep in mind that while the rights may not be an +issue in the United States, they may be in different parts of the world, +where most countries previously employed a copyright term of the life of +the author plus fifty years. + +PETERS next reviewed the economics of copyright holding. Simply, +economic rights are the rights to control the reproduction of a work in +any form. They belong to the author, or in the case of a work made for +hire, the employer. The second right, which is critical to conversion, +is the right to change a work. The right to make new versions is perhaps +one of the most significant rights of authors, particularly in an +electronic world. The third right is the right to publish the work and +the right to disseminate it, something that everyone who deals in an +electronic medium needs to know. The basic rule is if a copy is sold, +all rights of distribution are extinguished with the sale of that copy. +The key is that it must be sold. A number of companies overcome this +obstacle by leasing or renting their product. These companies argue that +if the material is rented or leased and not sold, they control the uses +of a work. The fourth right, and one very important in a digital world, +is a right of public performance, which means the right to show the work +sequentially. For example, copyright owners control the showing of a +CD-ROM product in a public place such as a public library. The reverse +side of public performance is something called the right of public +display. Moral rights also exist, which at the federal level apply only +to very limited visual works of art, but in theory may apply under +contract and other principles. Moral rights may include the right of an +author to have his or her name on a work, the right of attribution, and +the right to object to distortion or mutilation--the right of integrity. + +The way copyright law is worded gives much latitude to activities such as +preservation; to use of material for scholarly and research purposes when +the user does not make multiple copies; and to the generation of +facsimile copies of unpublished works by libraries for themselves and +other libraries. But the law does not allow anyone to become the +distributor of the product for the entire world. In today's electronic +environment, publishers are extremely concerned that the entire world is +networked and can obtain the information desired from a single copy in a +single library. Hence, if there is to be only one sale, which publishers +may choose to live with, they will obtain their money in other ways, for +example, from access and use. Hence, the development of site licenses +and other kinds of agreements to cover what publishers believe they +should be compensated for. Any solution that the United States takes +today has to consider the international arena. + +Noting that the United States is a member of the Berne Convention and +subscribes to its provisions, PETERS described the permissions process. +She also defined compulsory licenses. A compulsory license, of which the +United States has had a few, builds into the law the right to use a work +subject to certain terms and conditions. In the international arena, +however, the ability to use compulsory licenses is extremely limited. +Thus, clearinghouses and other collectives comprise one option that has +succeeded in providing for use of a work. Often overlooked when one +begins to use copyrighted material and put products together is how +expensive the permissions process and managing it is. According to +PETERS, the price of copyright in a digital medium, whatever solution is +worked out, will include managing and assembling the database. She +strongly recommended that publishers and librarians or people with +various backgrounds cooperate to work out administratively feasible +systems, in order to produce better results. + +In the lengthy question-and-answer period that followed PETERS's +presentation, the following points emerged: + + * The Copyright Office maintains that anything mechanical and + totally exhaustive probably is not protected. In the event that + what an individual did in developing potentially copyrightable + material is not understood, the Copyright Office will ask about the + creative choices the applicant chose to make or not to make. As a + practical matter, if one believes she or he has made enough of those + choices, that person has a right to assert a copyright and someone + else must assert that the work is not copyrightable. The more + mechanical, the more automatic, a thing is, the less likely it is to + be copyrightable. + + * Nearly all photographs are deemed to be copyrightable, but no one + worries about them much, because everyone is free to take the same + image. Thus, a photographic copyright represents what is called a + "thin" copyright. The photograph itself must be duplicated, in + order for copyright to be violated. + + * The Copyright Office takes the position that X-rays are not + copyrightable because they are mechanical. It can be argued + whether or not image enhancement in scanning can be protected. One + must exercise care with material created with public funds and + generally in the public domain. An article written by a federal + employee, if written as part of official duties, is not + copyrightable. However, control over a scientific article written + by a National Institutes of Health grantee (i.e., someone who + receives money from the U.S. government), depends on NIH policy. If + the government agency has no policy (and that policy can be + contained in its regulations, the contract, or the grant), the + author retains copyright. If a provision of the contract, grant, or + regulation states that there will be no copyright, then it does not + exist. When a work is created, copyright automatically comes into + existence unless something exists that says it does not. + + * An enhanced electronic copy of a print copy of an older reference + work in the public domain that does not contain copyrightable new + material is a purely mechanical rendition of the original work, and + is not copyrightable. + + * Usually, when a work enters the public domain, nothing can remove + it. For example, Congress recently passed into law the concept of + automatic renewal, which means that copyright on any work published + between l964 and l978 does not have to be renewed in order to + receive a seventy-five-year term. But any work not renewed before + 1964 is in the public domain. + + * Concerning whether or not the United States keeps track of when + authors die, nothing was ever done, nor is anything being done at + the moment by the Copyright Office. + + * Software that drives a mechanical process is itself copyrightable. + If one changes platforms, the software itself has a copyright. The + World Intellectual Property Organization will hold a symposium 28 + March through 2 April l993, at Harvard University, on digital + technology, and will study this entire issue. If one purchases a + computer software package, such as MacPaint, and creates something + new, one receives protection only for that which has been added. + +PETERS added that often in copyright matters, rough justice is the +outcome, for example, in collective licensing, ASCAP (i.e., American +Society of Composers, Authors, and Publishers), and BMI (i.e., Broadcast +Music, Inc.), where it may seem that the big guys receive more than their +due. Of course, people ought not to copy a creative product without +paying for it; there should be some compensation. But the truth of the +world, and it is not a great truth, is that the big guy gets played on +the radio more frequently than the little guy, who has to do much more +until he becomes a big guy. That is true of every author, every +composer, everyone, and, unfortunately, is part of life. + +Copyright always originates with the author, except in cases of works +made for hire. (Most software falls into this category.) When an author +sends his article to a journal, he has not relinquished copyright, though +he retains the right to relinquish it. The author receives absolutely +everything. The less prominent the author, the more leverage the +publisher will have in contract negotiations. In order to transfer the +rights, the author must sign an agreement giving them away. + +In an electronic society, it is important to be able to license a writer +and work out deals. With regard to use of a work, it usually is much +easier when a publisher holds the rights. In an electronic era, a real +problem arises when one is digitizing and making information available. +PETERS referred again to electronic licensing clearinghouses. Copyright +ought to remain with the author, but as one moves forward globally in the +electronic arena, a middleman who can handle the various rights becomes +increasingly necessary. + +The notion of copyright law is that it resides with the individual, but +in an on-line environment, where a work can be adapted and tinkered with +by many individuals, there is concern. If changes are authorized and +there is no agreement to the contrary, the person who changes a work owns +the changes. To put it another way, the person who acquires permission +to change a work technically will become the author and the owner, unless +some agreement to the contrary has been made. It is typical for the +original publisher to try to control all of the versions and all of the +uses. Copyright law always only sets up the boundaries. Anything can be +changed by contract. + + ****** + +SESSION VII. CONCLUSION + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +GENERAL DISCUSSION * Two questions for discussion * Different emphases in +the Workshop * Bringing the text and image partisans together * +Desiderata in planning the long-term development of something * Questions +surrounding the issue of electronic deposit * Discussion of electronic +deposit as an allusion to the issue of standards * Need for a directory +of preservation projects in digital form and for access to their +digitized files * CETH's catalogue of machine-readable texts in the +humanities * What constitutes a publication in the electronic world? * +Need for LC to deal with the concept of on-line publishing * LC's Network +Development Office exploring the limits of MARC as a standard in terms +of handling electronic information * Magnitude of the problem and the +need for distributed responsibility in order to maintain and store +electronic information * Workshop participants to be viewed as a starting +point * Development of a network version of AM urged * A step toward AM's +construction of some sort of apparatus for network access * A delicate +and agonizing policy question for LC * Re the issue of electronic +deposit, LC urged to initiate a catalytic process in terms of distributed +responsibility * Suggestions for cooperative ventures * Commercial +publishers' fears * Strategic questions for getting the image and text +people to think through long-term cooperation * Clarification of the +driving force behind both the Perseus and the Cornell Xerox projects * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +In his role as moderator of the concluding session, GIFFORD raised two +questions he believed would benefit from discussion: 1) Are there enough +commonalities among those of us that have been here for two days so that +we can see courses of action that should be taken in the future? And, if +so, what are they and who might take them? 2) Partly derivative from +that, but obviously very dangerous to LC as host, do you see a role for +the Library of Congress in all this? Of course, the Library of Congress +holds a rather special status in a number of these matters, because it is +not perceived as a player with an economic stake in them, but are there +roles that LC can play that can help advance us toward where we are heading? + +Describing himself as an uninformed observer of the technicalities of the +last two days, GIFFORD detected three different emphases in the Workshop: +1) people who are very deeply committed to text; 2) people who are almost +passionate about images; and 3) a few people who are very committed to +what happens to the networks. In other words, the new networking +dimension, the accessibility of the processability, the portability of +all this across the networks. How do we pull those three together? + +Adding a question that reflected HOCKEY's comment that this was the +fourth workshop she had attended in the previous thirty days, FLEISCHHAUER +wondered to what extent this meeting had reinvented the wheel, or if it +had contributed anything in the way of bringing together a different group +of people from those who normally appear on the workshop circuit. + +HOCKEY confessed to being struck at this meeting and the one the +Electronic Pierce Consortium organized the previous week that this was a +coming together of people working on texts and not images. Attempting to +bring the two together is something we ought to be thinking about for the +future: How one can think about working with image material to begin +with, but structuring it and digitizing it in such a way that at a later +stage it can be interpreted into text, and find a common way of building +text and images together so that they can be used jointly in the future, +with the network support to begin there because that is how people will +want to access it. + +In planning the long-term development of something, which is what is +being done in electronic text, HOCKEY stressed the importance not only +of discussing the technical aspects of how one does it but particularly +of thinking about what the people who use the stuff will want to do. +But conversely, there are numerous things that people start to do with +electronic text or material that nobody ever thought of in the beginning. + +LESK, in response to the question concerning the role of the Library of +Congress, remarked the often suggested desideratum of having electronic +deposit: Since everything is now computer-typeset, an entire decade of +material that was machine-readable exists, but the publishers frequently +did not save it; has LC taken any action to have its copyright deposit +operation start collecting these machine-readable versions? In the +absence of PETERS, GIFFORD replied that the question was being +actively considered but that that was only one dimension of the problem. +Another dimension is the whole question of the integrity of the original +electronic document. It becomes highly important in science to prove +authorship. How will that be done? + +ERWAY explained that, under the old policy, to make a claim for a +copyright for works that were published in electronic form, including +software, one had to submit a paper copy of the first and last twenty +pages of code--something that represented the work but did not include +the entire work itself and had little value to anyone. As a temporary +measure, LC has claimed the right to demand electronic versions of +electronic publications. This measure entails a proactive role for the +Library to say that it wants a particular electronic version. Publishers +then have perhaps a year to submit it. But the real problem for LC is +what to do with all this material in all these different formats. Will +the Library mount it? How will it give people access to it? How does LC +keep track of the appropriate computers, software, and media? The situation +is so hard to control, ERWAY said, that it makes sense for each publishing +house to maintain its own archive. But LC cannot enforce that either. + +GIFFORD acknowledged LESK's suggestion that establishing a priority +offered the solution, albeit a fairly complicated one. But who maintains +that register?, he asked. GRABER noted that LC does attempt to collect a +Macintosh version and the IBM-compatible version of software. It does +not collect other versions. But while true for software, BYRUM observed, +this reply does not speak to materials, that is, all the materials that +were published that were on somebody's microcomputer or driver tapes +at a publishing office across the country. LC does well to acquire +specific machine-readable products selectively that were intended to be +machine-readable. Materials that were in machine-readable form at one time, +BYRUM said, would be beyond LC's capability at the moment, insofar as +attempting to acquire, organize, and preserve them are concerned--and +preservation would be the most important consideration. In this +connection, GIFFORD reiterated the need to work out some sense of +distributive responsibility for a number of these issues, which +inevitably will require significant cooperation and discussion. +Nobody can do it all. + +LESK suggested that some publishers may look with favor on LC beginning +to serve as a depository of tapes in an electronic manuscript standard. +Publishers may view this as a service that they did not have to perform +and they might send in tapes. However, SPERBERG-McQUEEN countered, +although publishers have had equivalent services available to them for a +long time, the electronic text archive has never turned away or been +flooded with tapes and is forever sending feedback to the depositor. +Some publishers do send in tapes. + +ANDRE viewed this discussion as an allusion to the issue of standards. +She recommended that the AAP standard and the TEI, which has already been +somewhat harmonized internationally and which also shares several +compatibilities with the AAP, be harmonized to ensure sufficient +compatibility in the software. She drew the line at saying LC ought to +be the locus or forum for such harmonization. + +Taking the group in a slightly different direction, but one where at +least in the near term LC might play a helpful role, LYNCH remarked the +plans of a number of projects to carry out preservation by creating +digital images that will end up in on-line or near-line storage at some +institution. Presumably, LC will link this material somehow to its +on-line catalog in most cases. Thus, it is in a digital form. LYNCH had +the impression that many of these institutions would be willing to make +those files accessible to other people outside the institution, provided +that there is no copyright problem. This desideratum will require +propagating the knowledge that those digitized files exist, so that they +can end up in other on-line catalogs. Although uncertain about the +mechanism for achieving this result, LYNCH said that it warranted +scrutiny because it seemed to be connected to some of the basic issues of +cataloging and distribution of records. It would be foolish, given the +amount of work that all of us have to do and our meager resources, to +discover multiple institutions digitizing the same work. Re microforms, +LYNCH said, we are in pretty good shape. + +BATTIN called this a big problem and noted that the Cornell people (who +had already departed) were working on it. At issue from the beginning +was to learn how to catalog that information into RLIN and then into +OCLC, so that it would be accessible. That issue remains to be resolved. +LYNCH rejoined that putting it into OCLC or RLIN was helpful insofar as +somebody who is thinking of performing preservation activity on that work +could learn about it. It is not necessarily helpful for institutions to +make that available. BATTIN opined that the idea was that it not only be +for preservation purposes but for the convenience of people looking for +this material. She endorsed LYNCH's dictum that duplication of this +effort was to be avoided by every means. + +HOCKEY informed the Workshop about one major current activity of CETH, +namely a catalogue of machine-readable texts in the humanities. Held on +RLIN at present, the catalogue has been concentrated on ASCII as opposed +to digitized images of text. She is exploring ways to improve the +catalogue and make it more widely available, and welcomed suggestions +about these concerns. CETH owns the records, which are not just +restricted to RLIN, and can distribute them however it wishes. + +Taking up LESK's earlier question, BATTIN inquired whether LC, since it +is accepting electronic files and designing a mechanism for dealing with +that rather than putting books on shelves, would become responsible for +the National Copyright Depository of Electronic Materials. Of course +that could not be accomplished overnight, but it would be something LC +could plan for. GIFFORD acknowledged that much thought was being devoted +to that set of problems and returned the discussion to the issue raised +by LYNCH--whether or not putting the kind of records that both BATTIN and +HOCKEY have been talking about in RLIN is not a satisfactory solution. +It seemed to him that RLIN answered LYNCH's original point concerning +some kind of directory for these kinds of materials. In a situation +where somebody is attempting to decide whether or not to scan this or +film that or to learn whether or not someone has already done so, LYNCH +suggested, RLIN is helpful, but it is not helpful in the case of a local, +on-line catalogue. Further, one would like to have her or his system be +aware that that exists in digital form, so that one can present it to a +patron, even though one did not digitize it, if it is out of copyright. +The only way to make those linkages would be to perform a tremendous +amount of real-time look-up, which would be awkward at best, or +periodically to yank the whole file from RLIN and match it against one's +own stuff, which is a nuisance. + +But where, ERWAY inquired, does one stop including things that are +available with Internet, for instance, in one's local catalogue? +It almost seems that that is LC's means to acquire access to them. +That represents LC's new form of library loan. Perhaps LC's new on-line +catalogue is an amalgamation of all these catalogues on line. LYNCH +conceded that perhaps that was true in the very long term, but was not +applicable to scanning in the short term. In his view, the totals cited +by Yale, 10,000 books over perhaps a four-year period, and 1,000-1,500 +books from Cornell, were not big numbers, while searching all over +creation for relatively rare occurrences will prove to be less efficient. +As GIFFORD wondered if this would not be a separable file on RLIN and +could be requested from them, BATTIN interjected that it was easily +accessible to an institution. SEVERTSON pointed out that that file, cum +enhancements, was available with reference information on CD-ROM, which +makes it a little more available. + +In HOCKEY's view, the real question facing the Workshop is what to put in +this catalogue, because that raises the question of what constitutes a +publication in the electronic world. (WEIBEL interjected that Eric Joule +in OCLC's Office of Research is also wrestling with this particular +problem, while GIFFORD thought it sounded fairly generic.) HOCKEY +contended that a majority of texts in the humanities are in the hands +of either a small number of large research institutions or individuals +and are not generally available for anyone else to access at all. +She wondered if these texts ought to be catalogued. + +After argument proceeded back and forth for several minutes over why +cataloguing might be a necessary service, LEBRON suggested that this +issue involved the responsibility of a publisher. The fact that someone +has created something electronically and keeps it under his or her +control does not constitute publication. Publication implies +dissemination. While it would be important for a scholar to let other +people know that this creation exists, in many respects this is no +different from an unpublished manuscript. That is what is being accessed +in there, except that now one is not looking at it in the hard-copy but +in the electronic environment. + +LEBRON expressed puzzlement at the variety of ways electronic publishing +has been viewed. Much of what has been discussed throughout these two +days has concerned CD-ROM publishing, whereas in the on-line environment +that she confronts, the constraints and challenges are very different. +Sooner or later LC will have to deal with the concept of on-line +publishing. Taking up the comment ERWAY made earlier about storing +copies, LEBRON gave her own journal as an example. How would she deposit +OJCCT for copyright?, she asked, because the journal will exist in the +mainframe at OCLC and people will be able to access it. Here the +situation is different, ownership versus access, and is something that +arises with publication in the on-line environment, faster than is +sometimes realized. Lacking clear answers to all of these questions +herself, LEBRON did not anticipate that LC would be able to take a role +in helping to define some of them for quite a while. + +GREENFIELD observed that LC's Network Development Office is attempting, +among other things, to explore the limits of MARC as a standard in terms +of handling electronic information. GREENFIELD also noted that Rebecca +GUENTHER from that office gave a paper to the American Society for +Information Science (ASIS) summarizing several of the discussion papers +that were coming out of the Network Development Office. GREENFIELD said +he understood that that office had a list-server soliciting just the kind +of feedback received today concerning the difficulties of identifying and +cataloguing electronic information. GREENFIELD hoped that everybody +would be aware of that and somehow contribute to that conversation. + +Noting two of LC's roles, first, to act as a repository of record for +material that is copyrighted in this country, and second, to make +materials it holds available in some limited form to a clientele that +goes beyond Congress, BESSER suggested that it was incumbent on LC to +extend those responsibilities to all the things being published in +electronic form. This would mean eventually accepting electronic +formats. LC could require that at some point they be in a certain +limited set of formats, and then develop mechanisms for allowing people +to access those in the same way that other things are accessed. This +does not imply that they are on the network and available to everyone. +LC does that with most of its bibliographic records, BESSER said, which +end up migrating to the utility (e.g., OCLC) or somewhere else. But just +as most of LC's books are available in some form through interlibrary +loan or some other mechanism, so in the same way electronic formats ought +to be available to others in some format, though with some copyright +considerations. BESSER was not suggesting that these mechanisms be +established tomorrow, only that they seemed to fall within LC's purview, +and that there should be long-range plans to establish them. + +Acknowledging that those from LC in the room agreed with BESSER +concerning the need to confront difficult questions, GIFFORD underscored +the magnitude of the problem of what to keep and what to select. GIFFORD +noted that LC currently receives some 31,000 items per day, not counting +electronic materials, and argued for much more distributed responsibility +in order to maintain and store electronic information. + +BESSER responded that the assembled group could be viewed as a starting +point, whose initial operating premise could be helping to move in this +direction and defining how LC could do so, for example, in areas of +standardization or distribution of responsibility. + +FLEISCHHAUER added that AM was fully engaged, wrestling with some of the +questions that pertain to the conversion of older historical materials, +which would be one thing that the Library of Congress might do. Several +points mentioned by BESSER and several others on this question have a +much greater impact on those who are concerned with cataloguing and the +networking of bibliographic information, as well as preservation itself. + +Speaking directly to AM, which he considered was a largely uncopyrighted +database, LYNCH urged development of a network version of AM, or +consideration of making the data in it available to people interested in +doing network multimedia. On account of the current great shortage of +digital data that is both appealing and unencumbered by complex rights +problems, this course of action could have a significant effect on making +network multimedia a reality. + +In this connection, FLEISCHHAUER reported on a fragmentary prototype in +LC's Office of Information Technology Services that attempts to associate +digital images of photographs with cataloguing information in ways that +work within a local area network--a step, so to say, toward AM's +construction of some sort of apparatus for access. Further, AM has +attempted to use standard data forms in order to help make that +distinction between the access tools and the underlying data, and thus +believes that the database is networkable. + +A delicate and agonizing policy question for LC, however, which comes +back to resources and unfortunately has an impact on this, is to find +some appropriate, honorable, and legal cost-recovery possibilities. A +certain skittishness concerning cost-recovery has made people unsure +exactly what to do. AM would be highly receptive to discussing further +LYNCH's offer to test or demonstrate its database in a network +environment, FLEISCHHAUER said. + +Returning the discussion to what she viewed as the vital issue of +electronic deposit, BATTIN recommended that LC initiate a catalytic +process in terms of distributed responsibility, that is, bring together +the distributed organizations and set up a study group to look at all +these issues and see where we as a nation should move. The broader +issues of how we deal with the management of electronic information will +not disappear, but only grow worse. + +LESK took up this theme and suggested that LC attempt to persuade one +major library in each state to deal with its state equivalent publisher, +which might produce a cooperative project that would be equitably +distributed around the country, and one in which LC would be dealing with +a minimal number of publishers and minimal copyright problems. + +GRABER remarked the recent development in the scientific community of a +willingness to use SGML and either deposit or interchange on a fairly +standardized format. He wondered if a similar movement was taking place +in the humanities. Although the National Library of Medicine found only +a few publishers to cooperate in a like venture two or three years ago, a +new effort might generate a much larger number willing to cooperate. + +KIMBALL recounted his unit's (Machine-Readable Collections Reading Room) +troubles with the commercial publishers of electronic media in acquiring +materials for LC's collections, in particular the publishers' fear that +they would not be able to cover their costs and would lose control of +their products, that LC would give them away or sell them and make +profits from them. He doubted that the publishing industry was prepared +to move into this area at the moment, given its resistance to allowing LC +to use its machine-readable materials as the Library would like. + +The copyright law now addresses compact disk as a medium, and LC can +request one copy of that, or two copies if it is the only version, and +can request copies of software, but that fails to address magazines or +books or anything like that which is in machine-readable form. + +GIFFORD acknowledged the thorny nature of this issue, which he illustrated +with the example of the cumbersome process involved in putting a copy of a +scientific database on a LAN in LC's science reading room. He also +acknowledged that LC needs help and could enlist the energies and talents +of Workshop participants in thinking through a number of these problems. + +GIFFORD returned the discussion to getting the image and text people to +think through together where they want to go in the long term. MYLONAS +conceded that her experience at the Pierce Symposium the previous week at +Georgetown University and this week at LC had forced her to reevaluate +her perspective on the usefulness of text as images. MYLONAS framed the +issues in a series of questions: How do we acquire machine-readable +text? Do we take pictures of it and perform OCR on it later? Is it +important to obtain very high-quality images and text, etc.? +FLEISCHHAUER agreed with MYLONAS's framing of strategic questions, adding +that a large institution such as LC probably has to do all of those +things at different times. Thus, the trick is to exercise judgment. The +Workshop had added to his and AM's considerations in making those +judgments. Concerning future meetings or discussions, MYLONAS suggested +that screening priorities would be helpful. + +WEIBEL opined that the diversity reflected in this group was a sign both +of the health and of the immaturity of the field, and more time would +have to pass before we convince one another concerning standards. + +An exchange between MYLONAS and BATTIN clarified the point that the +driving force behind both the Perseus and the Cornell Xerox projects was +the preservation of knowledge for the future, not simply for particular +research use. In the case of Perseus, MYLONAS said, the assumption was +that the texts would not be entered again into electronically readable +form. SPERBERG-McQUEEN added that a scanned image would not serve as an +archival copy for purposes of preservation in the case of, say, the Bill +of Rights, in the sense that the scanned images are effectively the +archival copies for the Cornell mathematics books. + + + *** *** *** ****** *** *** *** + + + Appendix I: PROGRAM + + + + WORKSHOP + ON + ELECTRONIC + TEXTS + + + + 9-10 June 1992 + + Library of Congress + Washington, D.C. + + + + Supported by a Grant from the David and Lucile Packard Foundation + + +Tuesday, 9 June 1992 + +NATIONAL DEMONSTRATION LAB, ATRIUM, LIBRARY MADISON + +8:30 AM Coffee and Danish, registration + +9:00 AM Welcome + + Prosser Gifford, Director for Scholarly Programs, and Carl + Fleischhauer, Coordinator, American Memory, Library of + Congress + +9:l5 AM Session I. Content in a New Form: Who Will Use It and What + Will They Do? + + Broad description of the range of electronic information. + Characterization of who uses it and how it is or may be used. + In addition to a look at scholarly uses, this session will + include a presentation on use by students (K-12 and college) + and the general public. + + Moderator: James Daly + Avra Michelson, Archival Research and Evaluation Staff, + National Archives and Records Administration (Overview) + Susan H. Veccia, Team Leader, American Memory, User Evaluation, + and + Joanne Freeman, Associate Coordinator, American Memory, Library + of Congress (Beyond the scholar) + +10:30- +11:00 AM Break + +11:00 AM Session II. Show and Tell. + + Each presentation to consist of a fifteen-minute + statement/show; group discussion will follow lunch. + + Moderator: Jacqueline Hess, Director, National Demonstration + Lab + + 1. A classics project, stressing texts and text retrieval + more than multimedia: Perseus Project, Harvard + University + Elli Mylonas, Managing Editor + + 2. Other humanities projects employing the emerging norms of + the Text Encoding Initiative (TEI): Chadwyck-Healey's + The English Poetry Full Text Database and/or Patrologia + Latina Database + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + + 3. American Memory + Carl Fleischhauer, Coordinator, and + Ricky Erway, Associate Coordinator, Library of Congress + + 4. Founding Fathers example from Packard Humanities + Institute: The Papers of George Washington, University + of Virginia + Dorothy Twohig, Managing Editor, and/or + David Woodley Packard + + 5. An electronic medical journal offering graphics and + full-text searchability: The Online Journal of Current + Clinical Trials, American Association for the Advancement + of Science + Maria L. Lebron, Managing Editor + + 6. A project that offers facsimile images of pages but omits + searchable text: Cornell math books + Lynne K. Personius, Assistant Director, Cornell + Information Technologies for Scholarly Information + Sources, Cornell University + +12:30 PM Lunch (Dining Room A, Library Madison 620. Exhibits + available.) + +1:30 PM Session II. Show and Tell (Cont'd.). + +3:00- +3:30 PM Break + +3:30- +5:30 PM Session III. Distribution, Networks, and Networking: Options + for Dissemination. + + Published disks: University presses and public-sector + publishers, private-sector publishers + Computer networks + + Moderator: Robert G. Zich, Special Assistant to the Associate + Librarian for Special Projects, Library of Congress + Clifford A. Lynch, Director, Library Automation, University of + California + Howard Besser, School of Library and Information Science, + University of Pittsburgh + Ronald L. Larsen, Associate Director of Libraries for + Information Technology, University of Maryland at College + Park + Edwin B. Brownrigg, Executive Director, Memex Research + Institute + +6:30 PM Reception (Montpelier Room, Library Madison 619.) + + ****** + +Wednesday, 10 June 1992 + +DINING ROOM A, LIBRARY MADISON 620 + +8:30 AM Coffee and Danish + +9:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats. + + Moderator: William L. Hooton, Vice President of Operations, + I-NET + + A) Principal Methods for Image Capture of Text: + Direct scanning + Use of microform + + Anne R. Kenney, Assistant Director, Department of Preservation + and Conservation, Cornell University + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + Donald J. Waters, Head, Systems Office, Yale University Library + + B) Special Problems: + Bound volumes + Conservation + Reproducing printed halftones + + Carl Fleischhauer, Coordinator, American Memory, Library of + Congress + George Thoma, Chief, Communications Engineering Branch, + National Library of Medicine (NLM) + +10:30- +11:00 AM Break + +11:00 AM Session IV. Image Capture, Text Capture, Overview of Text and + Image Storage Formats (Cont'd.). + + C) Image Standards and Implications for Preservation + + Jean Baronas, Senior Manager, Department of Standards and + Technology, Association for Information and Image Management + (AIIM) + Patricia Battin, President, The Commission on Preservation and + Access (CPA) + + D) Text Conversion: + OCR vs. rekeying + Standards of accuracy and use of imperfect texts + Service bureaus + + Stuart Weibel, Senior Research Specialist, Online Computer + Library Center, Inc. (OCLC) + Michael Lesk, Executive Director, Computer Science Research, + Bellcore + Ricky Erway, Associate Coordinator, American Memory, Library of + Congress + Pamela Q.J. Andre, Associate Director, Automation, and + Judith A. Zidar, Coordinator, National Agricultural Text + Digitizing Program (NATDP), National Agricultural Library + (NAL) + +12:30- +1:30 PM Lunch + +1:30 PM Session V. Approaches to Preparing Electronic Texts. + + Discussion of approaches to structuring text for the computer; + pros and cons of text coding, description of methods in + practice, and comparison of text-coding methods. + + Moderator: Susan Hockey, Director, Center for Electronic Texts + in the Humanities (CETH), Rutgers and Princeton Universities + David Woodley Packard + C.M. Sperberg-McQueen, Editor, Text Encoding Initiative (TEI), + University of Illinois-Chicago + Eric M. Calaluca, Vice President, Chadwyck-Healey, Inc. + +3:30- +4:00 PM Break + +4:00 PM Session VI. Copyright Issues. + + Marybeth Peters, Policy Planning Adviser to the Register of + Copyrights, Library of Congress + +5:00 PM Session VII. Conclusion. + + General discussion. + What topics were omitted or given short shrift that anyone + would like to talk about now? + Is there a "group" here? What should the group do next, if + anything? What should the Library of Congress do next, if + anything? + Moderator: Prosser Gifford, Director for Scholarly Programs, + Library of Congress + +6:00 PM Adjourn + + + *** *** *** ****** *** *** *** + + + Appendix II: ABSTRACTS + + +SESSION I + +Avra MICHELSON Forecasting the Use of Electronic Texts by + Social Sciences and Humanities Scholars + +This presentation explores the ways in which electronic texts are likely +to be used by the non-scientific scholarly community. Many of the +remarks are drawn from a report the speaker coauthored with Jeff +Rothenberg, a computer scientist at The RAND Corporation. + +The speaker assesses 1) current scholarly use of information technology +and 2) the key trends in information technology most relevant to the +research process, in order to predict how social sciences and humanities +scholars are apt to use electronic texts. In introducing the topic, +current use of electronic texts is explored broadly within the context of +scholarly communication. From the perspective of scholarly +communication, the work of humanities and social sciences scholars +involves five processes: 1) identification of sources, 2) communication +with colleagues, 3) interpretation and analysis of data, 4) dissemination +of research findings, and 5) curriculum development and instruction. The +extent to which computation currently permeates aspects of scholarly +communication represents a viable indicator of the prospects for +electronic texts. + +The discussion of current practice is balanced by an analysis of key +trends in the scholarly use of information technology. These include the +trends toward end-user computing and connectivity, which provide a +framework for forecasting the use of electronic texts through this +millennium. The presentation concludes with a summary of the ways in +which the nonscientific scholarly community can be expected to use +electronic texts, and the implications of that use for information +providers. + +Susan VECCIA and Joanne FREEMAN Electronic Archives for the Public: + Use of American Memory in Public and + School Libraries + +This joint discussion focuses on nonscholarly applications of electronic +library materials, specifically addressing use of the Library of Congress +American Memory (AM) program in a small number of public and school +libraries throughout the United States. AM consists of selected Library +of Congress primary archival materials, stored on optical media +(CD-ROM/videodisc), and presented with little or no editing. Many +collections are accompanied by electronic introductions and user's guides +offering background information and historical context. Collections +represent a variety of formats including photographs, graphic arts, +motion pictures, recorded sound, music, broadsides and manuscripts, +books, and pamphlets. + +In 1991, the Library of Congress began a nationwide evaluation of AM in +different types of institutions. Test sites include public libraries, +elementary and secondary school libraries, college and university +libraries, state libraries, and special libraries. Susan VECCIA and +Joanne FREEMAN will discuss their observations on the use of AM by the +nonscholarly community, using evidence gleaned from this ongoing +evaluation effort. + +VECCIA will comment on the overall goals of the evaluation project, and +the types of public and school libraries included in this study. Her +comments on nonscholarly use of AM will focus on the public library as a +cultural and community institution, often bridging the gap between formal +and informal education. FREEMAN will discuss the use of AM in school +libraries. Use by students and teachers has revealed some broad +questions about the use of electronic resources, as well as definite +benefits gained by the "nonscholar." Topics will include the problem of +grasping content and context in an electronic environment, the stumbling +blocks created by "new" technologies, and the unique skills and interests +awakened through use of electronic resources. + +SESSION II + +Elli MYLONAS The Perseus Project: Interactive Sources and + Studies in Classical Greece + +The Perseus Project (5) has just released Perseus 1.0, the first publicly +available version of its hypertextual database of multimedia materials on +classical Greece. Perseus is designed to be used by a wide audience, +comprised of readers at the student and scholar levels. As such, it must +be able to locate information using different strategies, and it must +contain enough detail to serve the different needs of its users. In +addition, it must be delivered so that it is affordable to its target +audience. [These problems and the solutions we chose are described in +Mylonas, "An Interface to Classical Greek Civilization," JASIS 43:2, +March 1992.] + +In order to achieve its objective, the project staff decided to make a +conscious separation between selecting and converting textual, database, +and image data on the one hand, and putting it into a delivery system on +the other. That way, it is possible to create the electronic data +without thinking about the restrictions of the delivery system. We have +made a great effort to choose system-independent formats for our data, +and to put as much thought and work as possible into structuring it so +that the translation from paper to electronic form will enhance the value +of the data. [A discussion of these solutions as of two years ago is in +Elli Mylonas, Gregory Crane, Kenneth Morrell, and D. Neel Smith, "The +Perseus Project: Data in the Electronic Age," in Accessing Antiquity: +The Computerization of Classical Databases, J. Solomon and T. Worthen +(eds.), University of Arizona Press, in press.] + +Much of the work on Perseus is focused on collecting and converting the +data on which the project is based. At the same time, it is necessary to +provide means of access to the information, in order to make it usable, +and them to investigate how it is used. As we learn more about what +students and scholars from different backgrounds do with Perseus, we can +adjust our data collection, and also modify the system to accommodate +them. In creating a delivery system for general use, we have tried to +avoid favoring any one type of use by allowing multiple forms of access +to and navigation through the system. + +The way text is handled exemplifies some of these principles. All text +in Perseus is tagged using SGML, following the guidelines of the Text +Encoding Initiative (TEI). This markup is used to index the text, and +process it so that it can be imported into HyperCard. No SGML markup +remains in the text that reaches the user, because currently it would be +too expensive to create a system that acts on SGML in real time. +However, the regularity provided by SGML is essential for verifying the +content of the texts, and greatly speeds all the processing performed on +them. The fact that the texts exist in SGML ensures that they will be +relatively easy to port to different hardware and software, and so will +outlast the current delivery platform. Finally, the SGML markup +incorporates existing canonical reference systems (chapter, verse, line, +etc.); indexing and navigation are based on these features. This ensures +that the same canonical reference will always resolve to the same point +within a text, and that all versions of our texts, regardless of delivery +platform (even paper printouts) will function the same way. + +In order to provide tools for users, the text is processed by a +morphological analyzer, and the results are stored in a database. +Together with the index, the Greek-English Lexicon, and the index of all +the English words in the definitions of the lexicon, the morphological +analyses comprise a set of linguistic tools that allow users of all +levels to work with the textual information, and to accomplish different +tasks. For example, students who read no Greek may explore a concept as +it appears in Greek texts by using the English-Greek index, and then +looking up works in the texts and translations, or scholars may do +detailed morphological studies of word use by using the morphological +analyses of the texts. Because these tools were not designed for any one +use, the same tools and the same data can be used by both students and +scholars. + +NOTES: + (5) Perseus is based at Harvard University, with collaborators at + several other universities. The project has been funded primarily + by the Annenberg/CPB Project, as well as by Harvard University, + Apple Computer, and others. It is published by Yale University + Press. Perseus runs on Macintosh computers, under the HyperCard + program. + +Eric CALALUCA + +Chadwyck-Healey embarked last year on two distinct yet related full-text +humanities database projects. + +The English Poetry Full-Text Database and the Patrologia Latina Database +represent new approaches to linguistic research resources. The size and +complexity of the projects present problems for electronic publishers, +but surmountable ones if they remain abreast of the latest possibilities +in data capture and retrieval software techniques. + +The issues which required address prior to the commencement of the +projects were legion: + + 1. Editorial selection (or exclusion) of materials in each + database + + 2. Deciding whether or not to incorporate a normative encoding + structure into the databases? + A. If one is selected, should it be SGML? + B. If SGML, then the TEI? + + 3. Deliver as CD-ROM, magnetic tape, or both? + + 4. Can one produce retrieval software advanced enough for the + postdoctoral linguist, yet accessible enough for unattended + general use? Should one try? + + 5. Re fair and liberal networking policies, what are the risks to + an electronic publisher? + + 6. How does the emergence of national and international education + networks affect the use and viability of research projects + requiring high investment? Do the new European Community + directives concerning database protection necessitate two + distinct publishing projects, one for North America and one for + overseas? + +From new notions of "scholarly fair use" to the future of optical media, +virtually every issue related to electronic publishing was aired. The +result is two projects which have been constructed to provide the quality +research resources with the fewest encumbrances to use by teachers and +private scholars. + +Dorothy TWOHIG + +In spring 1988 the editors of the papers of George Washington, John +Adams, Thomas Jefferson, James Madison, and Benjamin Franklin were +approached by classics scholar David Packard on behalf of the Packard +Humanities Foundation with a proposal to produce a CD-ROM edition of the +complete papers of each of the Founding Fathers. This electronic edition +will supplement the published volumes, making the documents widely +available to students and researchers at reasonable cost. We estimate +that our CD-ROM edition of Washington's Papers will be substantially +completed within the next two years and ready for publication. Within +the next ten years or so, similar CD-ROM editions of the Franklin, Adams, +Jefferson, and Madison papers also will be available. At the Library of +Congress's session on technology, I would like to discuss not only the +experience of the Washington Papers in producing the CD-ROM edition, but +the impact technology has had on these major editorial projects. +Already, we are editing our volumes with an eye to the material that will +be readily available in the CD-ROM edition. The completed electronic +edition will provide immense possibilities for the searching of documents +for information in a way never possible before. The kind of technical +innovations that are currently available and on the drawing board will +soon revolutionize historical research and the production of historical +documents. Unfortunately, much of this new technology is not being used +in the planning stages of historical projects, simply because many +historians are aware only in the vaguest way of its existence. At least +two major new historical editing projects are considering microfilm +editions, simply because they are not aware of the possibilities of +electronic alternatives and the advantages of the new technology in terms +of flexibility and research potential compared to microfilm. In fact, +too many of us in history and literature are still at the stage of +struggling with our PCs. There are many historical editorial projects in +progress presently, and an equal number of literary projects. While the +two fields have somewhat different approaches to textual editing, there +are ways in which electronic technology can be of service to both. + +Since few of the editors involved in the Founding Fathers CD-ROM editions +are technical experts in any sense, I hope to point out in my discussion +of our experience how many of these electronic innovations can be used +successfully by scholars who are novices in the world of new technology. +One of the major concerns of the sponsors of the multitude of new +scholarly editions is the limited audience reached by the published +volumes. Most of these editions are being published in small quantities +and the publishers' price for them puts them out of the reach not only of +individual scholars but of most public libraries and all but the largest +educational institutions. However, little attention is being given to +ways in which technology can bypass conventional publication to make +historical and literary documents more widely available. + +What attracted us most to the CD-ROM edition of The Papers of George +Washington was the fact that David Packard's aim was to make a complete +edition of all of the 135,000 documents we have collected available in an +inexpensive format that would be placed in public libraries, small +colleges, and even high schools. This would provide an audience far +beyond our present 1,000-copy, $45 published edition. Since the CD-ROM +edition will carry none of the explanatory annotation that appears in the +published volumes, we also feel that the use of the CD-ROM will lead many +researchers to seek out the published volumes. + +In addition to ignorance of new technical advances, I have found that too +many editors--and historians and literary scholars--are resistant and +even hostile to suggestions that electronic technology may enhance their +work. I intend to discuss some of the arguments traditionalists are +advancing to resist technology, ranging from distrust of the speed with +which it changes (we are already wondering what is out there that is +better than CD-ROM) to suspicion of the technical language used to +describe electronic developments. + +Maria LEBRON + +The Online Journal of Current Clinical Trials, a joint venture of the +American Association for the Advancement of Science (AAAS) and the Online +Computer Library Center, Inc. (OCLC), is the first peer-reviewed journal +to provide full text, tabular material, and line illustrations on line. +This presentation will discuss the genesis and start-up period of the +journal. Topics of discussion will include historical overview, +day-to-day management of the editorial peer review, and manuscript +tagging and publication. A demonstration of the journal and its features +will accompany the presentation. + +Lynne PERSONIUS + +Cornell University Library, Cornell Information Technologies, and Xerox +Corporation, with the support of the Commission on Preservation and +Access, and Sun Microsystems, Inc., have been collaborating in a project +to test a prototype system for recording brittle books as digital images +and producing, on demand, high-quality archival paper replacements. The +project goes beyond that, however, to investigate some of the issues +surrounding scanning, storing, retrieving, and providing access to +digital images in a network environment. + +The Joint Study in Digital Preservation began in January 1990. Xerox +provided the College Library Access and Storage System (CLASS) software, +a prototype 600-dots-per-inch (dpi) scanner, and the hardware necessary +to support network printing on the DocuTech printer housed in Cornell's +Computing and Communications Center (CCC). + +The Cornell staff using the hardware and software became an integral part +of the development and testing process for enhancements to the CLASS +software system. The collaborative nature of this relationship is +resulting in a system that is specifically tailored to the preservation +application. + +A digital library of 1,000 volumes (or approximately 300,000 images) has +been created and is stored on an optical jukebox that resides in CCC. +The library includes a collection of select mathematics monographs that +provides mathematics faculty with an opportunity to use the electronic +library. The remaining volumes were chosen for the library to test the +various capabilities of the scanning system. + +One project objective is to provide users of the Cornell library and the +library staff with the ability to request facsimiles of digitized images +or to retrieve the actual electronic image for browsing. A prototype +viewing workstation has been created by Xerox, with input into the design +by a committee of Cornell librarians and computer professionals. This +will allow us to experiment with patron access to the images that make up +the digital library. The viewing station provides search, retrieval, and +(ultimately) printing functions with enhancements to facilitate +navigation through multiple documents. + +Cornell currently is working to extend access to the digital library to +readers using workstations from their offices. This year is devoted to +the development of a network resident image conversion and delivery +server, and client software that will support readers who use Apple +Macintosh computers, IBM windows platforms, and Sun workstations. +Equipment for this development was provided by Sun Microsystems with +support from the Commission on Preservation and Access. + +During the show-and-tell session of the Workshop on Electronic Texts, a +prototype view station will be demonstrated. In addition, a display of +original library books that have been digitized will be available for +review with associated printed copies for comparison. The fifteen-minute +overview of the project will include a slide presentation that +constitutes a "tour" of the preservation digitizing process. + +The final network-connected version of the viewing station will provide +library users with another mechanism for accessing the digital library, +and will also provide the capability of viewing images directly. This +will not require special software, although a powerful computer with good +graphics will be needed. + +The Joint Study in Digital Preservation has generated a great deal of +interest in the library community. Unfortunately, or perhaps +fortunately, this project serves to raise a vast number of other issues +surrounding the use of digital technology for the preservation and use of +deteriorating library materials, which subsequent projects will need to +examine. Much work remains. + +SESSION III + +Howard BESSER Networking Multimedia Databases + +What do we have to consider in building and distributing databases of +visual materials in a multi-user environment? This presentation examines +a variety of concerns that need to be addressed before a multimedia +database can be set up in a networked environment. + +In the past it has not been feasible to implement databases of visual +materials in shared-user environments because of technological barriers. +Each of the two basic models for multi-user multimedia databases has +posed its own problem. The analog multimedia storage model (represented +by Project Athena's parallel analog and digital networks) has required an +incredibly complex (and expensive) infrastructure. The economies of +scale that make multi-user setups cheaper per user served do not operate +in an environment that requires a computer workstation, videodisc player, +and two display devices for each user. + +The digital multimedia storage model has required vast amounts of storage +space (as much as one gigabyte per thirty still images). In the past the +cost of such a large amount of storage space made this model a +prohibitive choice as well. But plunging storage costs are finally +making this second alternative viable. + +If storage no longer poses such an impediment, what do we need to +consider in building digitally stored multi-user databases of visual +materials? This presentation will examine the networking and +telecommunication constraints that must be overcome before such databases +can become commonplace and useful to a large number of people. + +The key problem is the vast size of multimedia documents, and how this +affects not only storage but telecommunications transmission time. +Anything slower than T-1 speed is impractical for files of 1 megabyte or +larger (which is likely to be small for a multimedia document). For +instance, even on a 56 Kb line it would take three minutes to transfer a +1-megabyte file. And these figures assume ideal circumstances, and do +not take into consideration other users contending for network bandwidth, +disk access time, or the time needed for remote display. Current common +telephone transmission rates would be completely impractical; few users +would be willing to wait the hour necessary to transmit a single image at +2400 baud. + +This necessitates compression, which itself raises a number of other +issues. In order to decrease file sizes significantly, we must employ +lossy compression algorithms. But how much quality can we afford to +lose? To date there has been only one significant study done of +image-quality needs for a particular user group, and this study did not +look at loss resulting from compression. Only after identifying +image-quality needs can we begin to address storage and network bandwidth +needs. + +Experience with X-Windows-based applications (such as Imagequery, the +University of California at Berkeley image database) demonstrates the +utility of a client-server topology, but also points to the limitation of +current software for a distributed environment. For example, +applications like Imagequery can incorporate compression, but current X +implementations do not permit decompression at the end user's +workstation. Such decompression at the host computer alleviates storage +capacity problems while doing nothing to address problems of +telecommunications bandwidth. + +We need to examine the effects on network through-put of moving +multimedia documents around on a network. We need to examine various +topologies that will help us avoid bottlenecks around servers and +gateways. Experience with applications such as these raise still broader +questions. How closely is the multimedia document tied to the software +for viewing it? Can it be accessed and viewed from other applications? +Experience with the MARC format (and more recently with the Z39.50 +protocols) shows how useful it can be to store documents in a form in +which they can be accessed by a variety of application software. + +Finally, from an intellectual-access standpoint, we need to address the +issue of providing access to these multimedia documents in +interdisciplinary environments. We need to examine terminology and +indexing strategies that will allow us to provide access to this material +in a cross-disciplinary way. + +Ronald LARSEN Directions in High-Performance Networking for + Libraries + +The pace at which computing technology has advanced over the past forty +years shows no sign of abating. Roughly speaking, each five-year period +has yielded an order-of-magnitude improvement in price and performance of +computing equipment. No fundamental hurdles are likely to prevent this +pace from continuing for at least the next decade. It is only in the +past five years, though, that computing has become ubiquitous in +libraries, affecting all staff and patrons, directly or indirectly. + +During these same five years, communications rates on the Internet, the +principal academic computing network, have grown from 56 kbps to 1.5 +Mbps, and the NSFNet backbone is now running 45 Mbps. Over the next five +years, communication rates on the backbone are expected to exceed 1 Gbps. +Growth in both the population of network users and the volume of network +traffic has continued to grow geometrically, at rates approaching 15 +percent per month. This flood of capacity and use, likened by some to +"drinking from a firehose," creates immense opportunities and challenges +for libraries. Libraries must anticipate the future implications of this +technology, participate in its development, and deploy it to ensure +access to the world's information resources. + +The infrastructure for the information age is being put in place. +Libraries face strategic decisions about their role in the development, +deployment, and use of this infrastructure. The emerging infrastructure +is much more than computers and communication lines. It is more than the +ability to compute at a remote site, send electronic mail to a peer +across the country, or move a file from one library to another. The next +five years will witness substantial development of the information +infrastructure of the network. + +In order to provide appropriate leadership, library professionals must +have a fundamental understanding of and appreciation for computer +networking, from local area networks to the National Research and +Education Network (NREN). This presentation addresses these +fundamentals, and how they relate to libraries today and in the near +future. + +Edwin BROWNRIGG Electronic Library Visions and Realities + +The electronic library has been a vision desired by many--and rejected by +some--since Vannevar Bush coined the term memex to describe an automated, +intelligent, personal information system. Variations on this vision have +included Ted Nelson's Xanadau, Alan Kay's Dynabook, and Lancaster's +"paperless library," with the most recent incarnation being the +"Knowledge Navigator" described by John Scully of Apple. But the reality +of library service has been less visionary and the leap to the electronic +library has eluded universities, publishers, and information technology +files. + +The Memex Research Institute (MemRI), an independent, nonprofit research +and development organization, has created an Electronic Library Program +of shared research and development in order to make the collective vision +more concrete. The program is working toward the creation of large, +indexed publicly available electronic image collections of published +documents in academic, special, and public libraries. This strategic +plan is the result of the first stage of the program, which has been an +investigation of the information technologies available to support such +an effort, the economic parameters of electronic service compared to +traditional library operations, and the business and political factors +affecting the shift from print distribution to electronic networked +access. + +The strategic plan envisions a combination of publicly searchable access +databases, image (and text) document collections stored on network "file +servers," local and remote network access, and an intellectual property +management-control system. This combination of technology and +information content is defined in this plan as an E-library or E-library +collection. Some participating sponsors are already developing projects +based on MemRI's recommended directions. + +The E-library strategy projected in this plan is a visionary one that can +enable major changes and improvements in academic, public, and special +library service. This vision is, though, one that can be realized with +today's technology. At the same time, it will challenge the political +and social structure within which libraries operate: in academic +libraries, the traditional emphasis on local collections, extending to +accreditation issues; in public libraries, the potential of electronic +branch and central libraries fully available to the public; and for +special libraries, new opportunities for shared collections and networks. + +The environment in which this strategic plan has been developed is, at +the moment, dominated by a sense of library limits. The continued +expansion and rapid growth of local academic library collections is now +clearly at an end. Corporate libraries, and even law libraries, are +faced with operating within a difficult economic climate, as well as with +very active competition from commercial information sources. For +example, public libraries may be seen as a desirable but not critical +municipal service in a time when the budgets of safety and health +agencies are being cut back. + +Further, libraries in general have a very high labor-to-cost ratio in +their budgets, and labor costs are still increasing, notwithstanding +automation investments. It is difficult for libraries to obtain capital, +startup, or seed funding for innovative activities, and those +technology-intensive initiatives that offer the potential of decreased +labor costs can provoke the opposition of library staff. + +However, libraries have achieved some considerable successes in the past +two decades by improving both their service and their credibility within +their organizations--and these positive changes have been accomplished +mostly with judicious use of information technologies. The advances in +computing and information technology have been well-chronicled: the +continuing precipitous drop in computing costs, the growth of the +Internet and private networks, and the explosive increase in publicly +available information databases. + +For example, OCLC has become one of the largest computer network +organizations in the world by creating a cooperative cataloging network +of more than 6,000 libraries worldwide. On-line public access catalogs +now serve millions of users on more than 50,000 dedicated terminals in +the United States alone. The University of California MELVYL on-line +catalog system has now expanded into an index database reference service +and supports more than six million searches a year. And, libraries have +become the largest group of customers of CD-ROM publishing technology; +more than 30,000 optical media publications such as those offered by +InfoTrac and Silver Platter are subscribed to by U.S. libraries. + +This march of technology continues and in the next decade will result in +further innovations that are extremely difficult to predict. What is +clear is that libraries can now go beyond automation of their order files +and catalogs to automation of their collections themselves--and it is +possible to circumvent the fiscal limitations that appear to obtain +today. + +This Electronic Library Strategic Plan recommends a paradigm shift in +library service, and demonstrates the steps necessary to provide improved +library services with limited capacities and operating investments. + +SESSION IV-A + +Anne KENNEY + +The Cornell/Xerox Joint Study in Digital Preservation resulted in the +recording of 1,000 brittle books as 600-dpi digital images and the +production, on demand, of high-quality and archivally sound paper +replacements. The project, which was supported by the Commission on +Preservation and Access, also investigated some of the issues surrounding +scanning, storing, retrieving, and providing access to digital images in +a network environment. + +Anne Kenney will focus on some of the issues surrounding direct scanning +as identified in the Cornell Xerox Project. Among those to be discussed +are: image versus text capture; indexing and access; image-capture +capabilities; a comparison to photocopy and microfilm; production and +cost analysis; storage formats, protocols, and standards; and the use of +this scanning technology for preservation purposes. + +The 600-dpi digital images produced in the Cornell Xerox Project proved +highly acceptable for creating paper replacements of deteriorating +originals. The 1,000 scanned volumes provided an array of image-capture +challenges that are common to nineteenth-century printing techniques and +embrittled material, and that defy the use of text-conversion processes. +These challenges include diminished contrast between text and background, +fragile and deteriorated pages, uneven printing, elaborate type faces, +faint and bold text adjacency, handwritten text and annotations, nonRoman +languages, and a proliferation of illustrated material embedded in text. +The latter category included high-frequency and low-frequency halftones, +continuous tone photographs, intricate mathematical drawings, maps, +etchings, reverse-polarity drawings, and engravings. + +The Xerox prototype scanning system provided a number of important +features for capturing this diverse material. Technicians used multiple +threshold settings, filters, line art and halftone definitions, +autosegmentation, windowing, and software-editing programs to optimize +image capture. At the same time, this project focused on production. +The goal was to make scanning as affordable and acceptable as +photocopying and microfilming for preservation reformatting. A +time-and-cost study conducted during the last three months of this +project confirmed the economic viability of digital scanning, and these +findings will be discussed here. + +From the outset, the Cornell Xerox Project was predicated on the use of +nonproprietary standards and the use of common protocols when standards +did not exist. Digital files were created as TIFF images which were +compressed prior to storage using Group 4 CCITT compression. The Xerox +software is MS DOS based and utilizes off-the shelf programs such as +Microsoft Windows and Wang Image Wizard. The digital library is designed +to be hardware-independent and to provide interchangeability with other +institutions through network connections. Access to the digital files +themselves is two-tiered: Bibliographic records for the computer files +are created in RLIN and Cornell's local system and access into the actual +digital images comprising a book is provided through a document control +structure and a networked image file-server, both of which will be +described. + +The presentation will conclude with a discussion of some of the issues +surrounding the use of this technology as a preservation tool (storage, +refreshing, backup). + +Pamela ANDRE and Judith ZIDAR + +The National Agricultural Library (NAL) has had extensive experience with +raster scanning of printed materials. Since 1987, the Library has +participated in the National Agricultural Text Digitizing Project (NATDP) +a cooperative effort between NAL and forty-five land grant university +libraries. An overview of the project will be presented, giving its +history and NAL's strategy for the future. + +An in-depth discussion of NATDP will follow, including a description of +the scanning process, from the gathering of the printed materials to the +archiving of the electronic pages. The type of equipment required for a +stand-alone scanning workstation and the importance of file management +software will be discussed. Issues concerning the images themselves will +be addressed briefly, such as image format; black and white versus color; +gray scale versus dithering; and resolution. + +Also described will be a study currently in progress by NAL to evaluate +the usefulness of converting microfilm to electronic images in order to +improve access. With the cooperation of Tuskegee University, NAL has +selected three reels of microfilm from a collection of sixty-seven reels +containing the papers, letters, and drawings of George Washington Carver. +The three reels were converted into 3,500 electronic images using a +specialized microfilm scanner. The selection, filming, and indexing of +this material will be discussed. + +Donald WATERS + +Project Open Book, the Yale University Library's effort to convert 10, +000 books from microfilm to digital imagery, is currently in an advanced +state of planning and organization. The Yale Library has selected a +major vendor to serve as a partner in the project and as systems +integrator. In its proposal, the successful vendor helped isolate areas +of risk and uncertainty as well as key issues to be addressed during the +life of the project. The Yale Library is now poised to decide what +material it will convert to digital image form and to seek funding, +initially for the first phase and then for the entire project. + +The proposal that Yale accepted for the implementation of Project Open +Book will provide at the end of three phases a conversion subsystem, +browsing stations distributed on the campus network within the Yale +Library, a subsystem for storing 10,000 books at 200 and 600 dots per +inch, and network access to the image printers. Pricing for the system +implementation assumes the existence of Yale's campus ethernet network +and its high-speed image printers, and includes other requisite hardware +and software, as well as system integration services. Proposed operating +costs include hardware and software maintenance, but do not include +estimates for the facilities management of the storage devices and image +servers. + +Yale selected its vendor partner in a formal process, partly funded by +the Commission for Preservation and Access. Following a request for +proposal, the Yale Library selected two vendors as finalists to work with +Yale staff to generate a detailed analysis of requirements for Project +Open Book. Each vendor used the results of the requirements analysis to +generate and submit a formal proposal for the entire project. This +competitive process not only enabled the Yale Library to select its +primary vendor partner but also revealed much about the state of the +imaging industry, about the varying, corporate commitments to the markets +for imaging technology, and about the varying organizational dynamics +through which major companies are responding to and seeking to develop +these markets. + +Project Open Book is focused specifically on the conversion of images +from microfilm to digital form. The technology for scanning microfilm is +readily available but is changing rapidly. In its project requirements, +the Yale Library emphasized features of the technology that affect the +technical quality of digital image production and the costs of creating +and storing the image library: What levels of digital resolution can be +achieved by scanning microfilm? How does variation in the quality of +microfilm, particularly in film produced to preservation standards, +affect the quality of the digital images? What technologies can an +operator effectively and economically apply when scanning film to +separate two-up images and to control for and correct image +imperfections? How can quality control best be integrated into +digitizing work flow that includes document indexing and storage? + +The actual and expected uses of digital images--storage, browsing, +printing, and OCR--help determine the standards for measuring their +quality. Browsing is especially important, but the facilities available +for readers to browse image documents is perhaps the weakest aspect of +imaging technology and most in need of development. As it defined its +requirements, the Yale Library concentrated on some fundamental aspects +of usability for image documents: Does the system have sufficient +flexibility to handle the full range of document types, including +monographs, multi-part and multivolume sets, and serials, as well as +manuscript collections? What conventions are necessary to identify a +document uniquely for storage and retrieval? Where is the database of +record for storing bibliographic information about the image document? +How are basic internal structures of documents, such as pagination, made +accessible to the reader? How are the image documents physically +presented on the screen to the reader? + +The Yale Library designed Project Open Book on the assumption that +microfilm is more than adequate as a medium for preserving the content of +deteriorated library materials. As planning in the project has advanced, +it is increasingly clear that the challenge of digital image technology +and the key to the success of efforts like Project Open Book is to +provide a means of both preserving and improving access to those +deteriorated materials. + +SESSION IV-B + +George THOMA + +In the use of electronic imaging for document preservation, there are +several issues to consider, such as: ensuring adequate image quality, +maintaining substantial conversion rates (through-put), providing unique +identification for automated access and retrieval, and accommodating +bound volumes and fragile material. + +To maintain high image quality, image processing functions are required +to correct the deficiencies in the scanned image. Some commercially +available systems include these functions, while some do not. The +scanned raw image must be processed to correct contrast deficiencies-- +both poor overall contrast resulting from light print and/or dark +background, and variable contrast resulting from stains and +bleed-through. Furthermore, the scan density must be adequate to allow +legibility of print and sufficient fidelity in the pseudo-halftoned gray +material. Borders or page-edge effects must be removed for both +compactibility and aesthetics. Page skew must be corrected for aesthetic +reasons and to enable accurate character recognition if desired. +Compound images consisting of both two-toned text and gray-scale +illustrations must be processed appropriately to retain the quality of +each. + +SESSION IV-C + +Jean BARONAS + +Standards publications being developed by scientists, engineers, and +business managers in Association for Information and Image Management +(AIIM) standards committees can be applied to electronic image management +(EIM) processes including: document (image) transfer, retrieval and +evaluation; optical disk and document scanning; and document design and +conversion. When combined with EIM system planning and operations, +standards can assist in generating image databases that are +interchangeable among a variety of systems. The applications of +different approaches for image-tagging, indexing, compression, and +transfer often cause uncertainty concerning EIM system compatibility, +calibration, performance, and upward compatibility, until standard +implementation parameters are established. The AIIM standards that are +being developed for these applications can be used to decrease the +uncertainty, successfully integrate imaging processes, and promote "open +systems." AIIM is an accredited American National Standards Institute +(ANSI) standards developer with more than twenty committees comprised of +300 volunteers representing users, vendors, and manufacturers. The +standards publications that are developed in these committees have +national acceptance and provide the basis for international harmonization +in the development of new International Organization for Standardization +(ISO) standards. + +This presentation describes the development of AIIM's EIM standards and a +new effort at AIIM, a database on standards projects in a wide framework +of imaging industries including capture, recording, processing, +duplication, distribution, display, evaluation, and preservation. The +AIIM Imagery Database will cover imaging standards being developed by +many organizations in many different countries. It will contain +standards publications' dates, origins, related national and +international projects, status, key words, and abstracts. The ANSI Image +Technology Standards Board requested that such a database be established, +as did the ISO/International Electrotechnical Commission Joint Task Force +on Imagery. AIIM will take on the leadership role for the database and +coordinate its development with several standards developers. + +Patricia BATTIN + + Characteristics of standards for digital imagery: + + * Nature of digital technology implies continuing volatility. + + * Precipitous standard-setting not possible and probably not + desirable. + + * Standards are a complex issue involving the medium, the + hardware, the software, and the technical capacity for + reproductive fidelity and clarity. + + * The prognosis for reliable archival standards (as defined by + librarians) in the foreseeable future is poor. + + Significant potential and attractiveness of digital technology as a + preservation medium and access mechanism. + + Productive use of digital imagery for preservation requires a + reconceptualizing of preservation principles in a volatile, + standardless world. + + Concept of managing continuing access in the digital environment + rather than focusing on the permanence of the medium and long-term + archival standards developed for the analog world. + + Transition period: How long and what to do? + + * Redefine "archival." + + * Remove the burden of "archival copy" from paper artifacts. + + * Use digital technology for storage, develop management + strategies for refreshing medium, hardware and software. + + * Create acid-free paper copies for transition period backup + until we develop reliable procedures for ensuring continuing + access to digital files. + +SESSION IV-D + +Stuart WEIBEL The Role of SGML Markup in the CORE Project (6) + +The emergence of high-speed telecommunications networks as a basic +feature of the scholarly workplace is driving the demand for electronic +document delivery. Three distinct categories of electronic +publishing/republishing are necessary to support access demands in this +emerging environment: + + 1.) Conversion of paper or microfilm archives to electronic format + 2.) Conversion of electronic files to formats tailored to + electronic retrieval and display + 3.) Primary electronic publishing (materials for which the + electronic version is the primary format) + +OCLC has experimental or product development activities in each of these +areas. Among the challenges that lie ahead is the integration of these +three types of information stores in coherent distributed systems. + +The CORE (Chemistry Online Retrieval Experiment) Project is a model for +the conversion of large text and graphics collections for which +electronic typesetting files are available (category 2). The American +Chemical Society has made available computer typography files dating from +1980 for its twenty journals. This collection of some 250 journal-years +is being converted to an electronic format that will be accessible +through several end-user applications. + +The use of Standard Generalized Markup Language (SGML) offers the means +to capture the structural richness of the original articles in a way that +will support a variety of retrieval, navigation, and display options +necessary to navigate effectively in very large text databases. + +An SGML document consists of text that is marked up with descriptive tags +that specify the function of a given element within the document. As a +formal language construct, an SGML document can be parsed against a +document-type definition (DTD) that unambiguously defines what elements +are allowed and where in the document they can (or must) occur. This +formalized map of article structure allows the user interface design to +be uncoupled from the underlying database system, an important step +toward interoperability. Demonstration of this separability is a part of +the CORE project, wherein user interface designs born of very different +philosophies will access the same database. + +NOTES: + (6) The CORE project is a collaboration among Cornell University's + Mann Library, Bell Communications Research (Bellcore), the American + Chemical Society (ACS), the Chemical Abstracts Service (CAS), and + OCLC. + +Michael LESK The CORE Electronic Chemistry Library + +A major on-line file of chemical journal literature complete with +graphics is being developed to test the usability of fully electronic +access to documents, as a joint project of Cornell University, the +American Chemical Society, the Chemical Abstracts Service, OCLC, and +Bellcore (with additional support from Sun Microsystems, Springer-Verlag, +DigitaI Equipment Corporation, Sony Corporation of America, and Apple +Computers). Our file contains the American Chemical Society's on-line +journals, supplemented with the graphics from the paper publication. The +indexing of the articles from Chemical Abstracts Documents is available +in both image and text format, and several different interfaces can be +used. Our goals are (1) to assess the effectiveness and acceptability of +electronic access to primary journals as compared with paper, and (2) to +identify the most desirable functions of the user interface to an +electronic system of journals, including in particular a comparison of +page-image display with ASCII display interfaces. Early experiments with +chemistry students on a variety of tasks suggest that searching tasks are +completed much faster with any electronic system than with paper, but +that for reading all versions of the articles are roughly equivalent. + +Pamela ANDRE and Judith ZIDAR + +Text conversion is far more expensive and time-consuming than image +capture alone. NAL's experience with optical character recognition (OCR) +will be related and compared with the experience of having text rekeyed. +What factors affect OCR accuracy? How accurate does full text have to be +in order to be useful? How do different users react to imperfect text? +These are questions that will be explored. For many, a service bureau +may be a better solution than performing the work inhouse; this will also +be discussed. + +SESSION VI + +Marybeth PETERS + +Copyright law protects creative works. Protection granted by the law to +authors and disseminators of works includes the right to do or authorize +the following: reproduce the work, prepare derivative works, distribute +the work to the public, and publicly perform or display the work. In +addition, copyright owners of sound recordings and computer programs have +the right to control rental of their works. These rights are not +unlimited; there are a number of exceptions and limitations. + +An electronic environment places strains on the copyright system. +Copyright owners want to control uses of their work and be paid for any +use; the public wants quick and easy access at little or no cost. The +marketplace is working in this area. Contracts, guidelines on electronic +use, and collective licensing are in use and being refined. + +Issues concerning the ability to change works without detection are more +difficult to deal with. Questions concerning the integrity of the work +and the status of the changed version under the copyright law are to be +addressed. These are public policy issues which require informed +dialogue. + + + *** *** *** ****** *** *** *** + + + Appendix III: DIRECTORY OF PARTICIPANTS + + +PRESENTERS: + + Pamela Q.J. Andre + Associate Director, Automation + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 + Fax: (301) 504-7473 + E-mail: INTERNET: PANDRE@ASRR.ARSUSDA.GOV + + Jean Baronas, Senior Manager + Department of Standards and Technology + Association for Information and Image Management (AIIM) + 1100 Wayne Avenue, Suite 1100 + Silver Spring, MD 20910 + Phone: (301) 587-8202 + Fax: (301) 587-2711 + + Patricia Battin, President + The Commission on Preservation and Access + 1400 16th Street, N.W. + Suite 740 + Washington, DC 20036-2217 + Phone: (202) 939-3400 + Fax: (202) 939-3407 + E-mail: CPA@GWUVM.BITNET + + Howard Besser + Centre Canadien d'Architecture + (Canadian Center for Architecture) + 1920, rue Baile + Montreal, Quebec H3H 2S6 + CANADA + Phone: (514) 939-7001 + Fax: (514) 939-7020 + E-mail: howard@lis.pitt.edu + + Edwin B. Brownrigg, Executive Director + Memex Research Institute + 422 Bonita Avenue + Roseville, CA 95678 + Phone: (916) 784-2298 + Fax: (916) 786-7559 + E-mail: BITNET: MEMEX@CALSTATE.2 + + Eric M. Calaluca, Vice President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + James Daly + 4015 Deepwood Road + Baltimore, MD 21218-1404 + Phone: (410) 235-0763 + + Ricky Erway, Associate Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Carl Fleischhauer, Coordinator + American Memory + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + + Joanne Freeman + 2000 Jefferson Park Avenue, No. 7 + Charlottesville, VA 22903 + + Prosser Gifford + Director for Scholarly Programs + Library of Congress + Phone: (202) 707-1517 + Fax: (202) 707-9898 + E-mail: pgif@seq1.loc.gov + + Jacqueline Hess, Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Susan Hockey, Director + Center for Electronic Texts in the Humanities (CETH) + Alexander Library + Rutgers University + 169 College Avenue + New Brunswick, NJ 08903 + Phone: (908) 932-1384 + Fax: (908) 932-1386 + E-mail: hockey@zodiac.rutgers.edu + + William L. Hooton, Vice President + Business & Technical Development + Imaging & Information Systems Group + I-NET + 6430 Rockledge Drive, Suite 400 + Bethesda, MD 208l7 + Phone: (301) 564-6750 + Fax: (513) 564-6867 + + Anne R. Kenney, Associate Director + Department of Preservation and Conservation + 701 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-6875 + Fax: (607) 255-9346 + E-mail: LYDY@CORNELLA.BITNET + + Ronald L. Larsen + Associate Director for Information Technology + University of Maryland at College Park + Room B0224, McKeldin Library + College Park, MD 20742-7011 + Phone: (301) 405-9194 + Fax: (301) 314-9865 + E-mail: rlarsen@libr.umd.edu + + Maria L. Lebron, Managing Editor + The Online Journal of Current Clinical Trials + l333 H Street, N.W. + Washington, DC 20005 + Phone: (202) 326-6735 + Fax: (202) 842-2868 + E-mail: PUBSAAAS@GWUVM.BITNET + + Michael Lesk, Executive Director + Computer Science Research + Bell Communications Research, Inc. + Rm 2A-385 + 445 South Street + Morristown, NJ 07960-l9l0 + Phone: (201) 829-4070 + Fax: (201) 829-5981 + E-mail: lesk@bellcore.com (Internet) or bellcore!lesk (uucp) + + Clifford A. Lynch + Director, Library Automation + University of California, + Office of the President + 300 Lakeside Drive, 8th Floor + Oakland, CA 94612-3350 + Phone: (510) 987-0522 + Fax: (510) 839-3573 + E-mail: calur@uccmvsa + + Avra Michelson + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, D.C. 20408 + Phone: (202) 501-5544 + Fax: (202) 501-5533 + E-mail: tmi@cu.nih.gov + + Elli Mylonas, Managing Editor + Perseus Project + Department of the Classics + Harvard University + 319 Boylston Hall + Cambridge, MA 02138 + Phone: (617) 495-9025, (617) 495-0456 (direct) + Fax: (617) 496-8886 + E-mail: Elli@IKAROS.Harvard.EDU or elli@wjh12.harvard.edu + + David Woodley Packard + Packard Humanities Institute + 300 Second Street, Suite 201 + Los Altos, CA 94002 + Phone: (415) 948-0150 (PHI) + Fax: (415) 948-5793 + + Lynne K. Personius, Assistant Director + Cornell Information Technologies for + Scholarly Information Sources + 502 Olin Library + Cornell University + Ithaca, NY 14853 + Phone: (607) 255-3393 + Fax: (607) 255-9346 + E-mail: JRN@CORNELLC.BITNET + + Marybeth Peters + Policy Planning Adviser to the + Register of Copyrights + Library of Congress + Office LM 403 + Phone: (202) 707-8350 + Fax: (202) 707-8366 + + C. Michael Sperberg-McQueen + Editor, Text Encoding Initiative + Computer Center (M/C 135) + University of Illinois at Chicago + Box 6998 + Chicago, IL 60680 + Phone: (312) 413-0317 + Fax: (312) 996-6834 + E-mail: u35395@uicvm..cc.uic.edu or u35395@uicvm.bitnet + + George R. Thoma, Chief + Communications Engineering Branch + National Library of Medicine + 8600 Rockville Pike + Bethesda, MD 20894 + Phone: (301) 496-4496 + Fax: (301) 402-0341 + E-mail: thoma@lhc.nlm.nih.gov + + Dorothy Twohig, Editor + The Papers of George Washington + 504 Alderman Library + University of Virginia + Charlottesville, VA 22903-2498 + Phone: (804) 924-0523 + Fax: (804) 924-4337 + + Susan H. Veccia, Team leader + American Memory, User Evaluation + Library of Congress + American Memory Evaluation Project + Phone: (202) 707-9104 + Fax: (202) 707-3764 + E-mail: svec@seq1.loc.gov + + Donald J. Waters, Head + Systems Office + Yale University Library + New Haven, CT 06520 + Phone: (203) 432-4889 + Fax: (203) 432-7231 + E-mail: DWATERS@YALEVM.BITNET or DWATERS@YALEVM.YCC.YALE.EDU + + Stuart Weibel, Senior Research Scientist + OCLC + 6565 Frantz Road + Dublin, OH 43017 + Phone: (614) 764-608l + Fax: (614) 764-2344 + E-mail: INTERNET: Stu@rsch.oclc.org + + Robert G. Zich + Special Assistant to the Associate Librarian + for Special Projects + Library of Congress + Phone: (202) 707-6233 + Fax: (202) 707-3764 + E-mail: rzic@seq1.loc.gov + + Judith A. Zidar, Coordinator + National Agricultural Text Digitizing Program + Information Systems Division + National Agricultural Library + 10301 Baltimore Boulevard + Beltsville, MD 20705-2351 + Phone: (301) 504-6813 or 504-5853 + Fax: (301) 504-7473 + E-mail: INTERNET: JZIDAR@ASRR.ARSUSDA.GOV + + +OBSERVERS: + + Helen Aguera, Program Officer + Division of Research + Room 318 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, D.C. 20506 + Phone: (202) 786-0358 + Fax: (202) 786-0243 + + M. Ellyn Blanton, Deputy Director + National Demonstration Laboratory + for Interactive Information Technologies + Library of Congress + Phone: (202) 707-4157 + Fax: (202) 707-2829 + + Charles M. Dollar + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5532 + Fax: (202) 501-5512 + + Jeffrey Field, Deputy to the Director + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0570 + Fax: (202) 786-0243 + + Lorrin Garson + American Chemical Society + Research and Development Department + 1155 16th Street, N.W. + Washington, D.C. 20036 + Phone: (202) 872-4541 + Fax: E-mail: INTERNET: LRG96@ACS.ORG + + William M. Holmes, Jr. + National Archives and Records Administration + NSZ Rm. 14N + 7th & Pennsylvania, N.W. + Washington, DC 20408 + Phone: (202) 501-5540 + Fax: (202) 501-5512 + E-mail: WHOLMES@AMERICAN.EDU + + Sperling Martin + Information Resource Management + 20030 Doolittle Street + Gaithersburg, MD 20879 + Phone: (301) 924-1803 + + Michael Neuman, Director + The Center for Text and Technology + Academic Computing Center + 238 Reiss Science Building + Georgetown University + Washington, DC 20057 + Phone: (202) 687-6096 + Fax: (202) 687-6003 + E-mail: neuman@guvax.bitnet, neuman@guvax.georgetown.edu + + Barbara Paulson, Program Officer + Division of Preservation and Access + Room 802 + National Endowment for the Humanities + 1100 Pennsylvania Avenue, N.W. + Washington, DC 20506 + Phone: (202) 786-0577 + Fax: (202) 786-0243 + + Allen H. Renear + Senior Academic Planning Analyst + Brown University Computing and Information Services + 115 Waterman Street + Campus Box 1885 + Providence, R.I. 02912 + Phone: (401) 863-7312 + Fax: (401) 863-7329 + E-mail: BITNET: Allen@BROWNVM or + INTERNET: Allen@brownvm.brown.edu + + Susan M. Severtson, President + Chadwyck-Healey, Inc. + 1101 King Street + Alexandria, VA 223l4 + Phone: (800) 752-05l5 + Fax: (703) 683-7589 + + Frank Withrow + U.S. Department of Education + 555 New Jersey Avenue, N.W. + Washington, DC 20208-5644 + Phone: (202) 219-2200 + Fax: (202) 219-2106 + + +(LC STAFF) + + Linda L. Arret + Machine-Readable Collections Reading Room LJ 132 + (202) 707-1490 + + John D. Byrum, Jr. + Descriptive Cataloging Division LM 540 + (202) 707-5194 + + Mary Jane Cavallo + Science and Technology Division LA 5210 + (202) 707-1219 + + Susan Thea David + Congressional Research Service LM 226 + (202) 707-7169 + + Robert Dierker + Senior Adviser for Multimedia Activities LM 608 + (202) 707-6151 + + William W. Ellis + Associate Librarian for Science and Technology LM 611 + (202) 707-6928 + + Ronald Gephart + Manuscript Division LM 102 + (202) 707-5097 + + James Graber + Information Technology Services LM G51 + (202) 707-9628 + + Rich Greenfield + American Memory LM 603 + (202) 707-6233 + + Rebecca Guenther + Network Development LM 639 + (202) 707-5092 + + Kenneth E. Harris + Preservation LM G21 + (202) 707-5213 + + Staley Hitchcock + Manuscript Division LM 102 + (202) 707-5383 + + Bohdan Kantor + Office of Special Projects LM 612 + (202) 707-0180 + + John W. Kimball, Jr + Machine-Readable Collections Reading Room LJ 132 + (202) 707-6560 + + Basil Manns + Information Technology Services LM G51 + (202) 707-8345 + + Sally Hart McCallum + Network Development LM 639 + (202) 707-6237 + + Dana J. Pratt + Publishing Office LM 602 + (202) 707-6027 + + Jane Riefenhauser + American Memory LM 603 + (202) 707-6233 + + William Z. Schenck + Collections Development LM 650 + (202) 707-7706 + + Chandru J. Shahani + Preservation Research and Testing Office (R&T) LM G38 + (202) 707-5607 + + William J. Sittig + Collections Development LM 650 + (202) 707-7050 + + Paul Smith + Manuscript Division LM 102 + (202) 707-5097 + + James L. Stevens + Information Technology Services LM G51 + (202) 707-9688 + + Karen Stuart + Manuscript Division LM 130 + (202) 707-5389 + + Tamara Swora + Preservation Microfilming Office LM G05 + (202) 707-6293 + + Sarah Thomas + Collections Cataloging LM 642 + (202) 707-5333 + + + END + ************************************************************* + +Note: This file has been edited for use on computer networks. This +editing required the removal of diacritics, underlining, and fonts such +as italics and bold. + +kde 11/92 + +[A few of the italics (when used for emphasis) were replaced by CAPS mh] + +*End of The Project Gutenberg Etext of LOC WORKSHOP ON ELECTRONIC ETEXTS + diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/data/paper-100k.pdf b/internal-complibs/zlib-ng-2.1.0-beta1/test/data/paper-100k.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b3325e4a2bb578419d6c7fa412aaa78d493ff274 GIT binary patch literal 102400 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 f+ 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 +#include +#include + +#include "test_shared_ng.h" + +#define TESTFILE "foo.gz" + +static const char dictionary[] = "hello"; +static unsigned long dictId = 0; /* Adler32 value of the dictionary */ + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + + +void test_compress (unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen); +void test_gzio (const char *fname, unsigned char *uncompr, z_size_t uncomprLen); +void test_deflate (unsigned char *compr, size_t comprLen); +void test_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_large_deflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params); +void test_large_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_flush (unsigned char *compr, z_uintmax_t *comprLen); +void test_sync (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +void test_dict_deflate (unsigned char *compr, size_t comprLen); +void test_dict_inflate (unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen); +int main (int argc, char *argv[]); + + +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *format, ...) { + va_list va; + + va_start(va, format); + vfprintf(stderr, format, va); + va_end(va); + + exit(1); +} + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) \ + error("%s error: %d\n", msg, err); \ +} + +/* =========================================================================== + * Test compress() and uncompress() + */ +void test_compress(unsigned char *compr, z_uintmax_t comprLen, unsigned char *uncompr, z_uintmax_t uncomprLen) { + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + err = PREFIX(compress)(compr, &comprLen, (const unsigned char*)hello, len); + CHECK_ERR(err, "compress"); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + CHECK_ERR(err, "uncompress"); + + if (strcmp((char*)uncompr, hello)) + error("bad uncompress\n"); + else + printf("uncompress(): %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test read/write of .gz files + */ +void test_gzio(const char *fname, unsigned char *uncompr, z_size_t uncomprLen) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); +#else + int err; + size_t read; + size_t len = strlen(hello)+1; + gzFile file; + z_off64_t pos; + z_off64_t comprLen; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(fname, "wb"); + if (file == NULL) + error("gzopen error\n"); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + if (PREFIX(gzputs)(file, "ello") != 4) + error("gzputs err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzprintf)(file, ", %s!", "hello") != 8) + error("gzprintf err: %s\n", PREFIX(gzerror)(file, &err)); + /* Write string null-teriminator using gzseek */ + if (PREFIX(gzseek)(file, 1L, SEEK_CUR) < 0) + error("gzseek error, gztell=%ld\n", (long)PREFIX(gztell)(file)); + /* Write hello, hello! using gzfwrite using best compression level */ + if (PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY) != Z_OK) + error("gzsetparams err: %s\n", PREFIX(gzerror)(file, &err)); + if (PREFIX(gzfwrite)(hello, len, 1, file) == 0) + error("gzfwrite err: %s\n", PREFIX(gzerror)(file, &err)); + /* Flush compressed bytes to file */ + if (PREFIX(gzflush)(file, Z_SYNC_FLUSH) != Z_OK) + error("gzflush err: %s\n", PREFIX(gzerror)(file, &err)); + comprLen = PREFIX(gzoffset)(file); + if (comprLen <= 0) + error("gzoffset err: %s\n", PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(fname, "rb"); + if (file == NULL) + error("gzopen error\n"); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + if (PREFIX(gzread)(file, uncompr, (unsigned)uncomprLen) != (int)(len + len)) + error("gzread err: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello)) + error("bad gzread: %s\n", (char*)uncompr); + else + printf("gzread(): %s\n", (char*)uncompr); + /* Check position at the end of the gz file */ + if (PREFIX(gzeof)(file) != 1) + error("gzeof err: not reporting end of stream\n"); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + if (pos != 6 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + if (PREFIX(gzgetc)(file) != ' ') + error("gzgetc error\n"); + if (PREFIX(gzungetc)(' ', file) != ' ') + error("gzungetc error\n"); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncomprLen); + if (strlen((char*)uncompr) != 7) /* " hello!" */ + error("gzgets err after gzseek: %s\n", PREFIX(gzerror)(file, &err)); + if (strcmp((char*)uncompr, hello + 6)) + error("bad gzgets after gzseek\n"); + else + printf("gzgets() after gzseek: %s\n", (char*)uncompr); + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + if (pos != 14 || PREFIX(gztell)(file) != pos) + error("gzseek error, pos=%ld, gztell=%ld\n", (long)pos, (long)PREFIX(gztell)(file)); + /* Check position not at end of file */ + if (PREFIX(gzeof)(file) != 0) + error("gzeof err: reporting end of stream\n"); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncomprLen, 1, file); + if (strcmp((const char *)uncompr, hello) != 0) + error("bad gzgets\n"); + else + printf("gzgets(): %s\n", (char*)uncompr); + pos = PREFIX(gzoffset)(file); + if (pos < 0 || pos != (comprLen + 10)) + error("gzoffset err: wrong offset at end\n"); + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + if (err == 0) + error("gzerror err: no error returned\n"); + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + if (err != 0) + error("gzclearerr err: not zero %d\n", err); + + PREFIX(gzclose)(file); + + if (PREFIX(gzclose)(NULL) != Z_STREAM_ERROR) + error("gzclose unexpected return when handle null\n"); + Z_UNUSED(read); +#endif +} + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((char*)uncompr, hello)) + error("bad inflate\n"); + else + printf("inflate(): %s\n", (char *)uncompr); +} + +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen, int zng_params) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + if (c_stream.avail_in != 0) + error("deflate not greedy\n"); + + /* Feed in already compressed data and switch to no compression: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_BEST_SPEED) + error("Expected compression level Z_BEST_SPEED, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + } + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + /* Switch back to compressing mode: */ + if (zng_params) { +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + if (level != Z_NO_COMPRESSION) + error("Expected compression level Z_NO_COMPRESSION, got %d\n", level); + if (strategy != Z_DEFAULT_STRATEGY) + error("Expected compression strategy Z_DEFAULT_STRATEGY, got %d\n", strategy); + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + error("test_large_deflate() called with zng_params=1 in compat mode\n"); +#endif + } else { + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + } + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2*uncomprLen + diff) + error("bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + else + printf("large_inflate(): OK\n"); +} + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_uintmax_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +#ifdef ZLIBNG_ENABLE_TESTS +/* =========================================================================== + * Test inflateSync() + * We expect a certain compressed block layout, so skip this with the original zlib. + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen-2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("inflate should report Z_STREAM_END\n"); + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + printf("after inflateSync(): hel%s\n", (char *)uncompr); +} +#endif + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + c_stream.adler = 0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char*)dictionary, (int)sizeof(dictionary)); + CHECK_ERR(err, "deflateSetDictionary"); + + dictId = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + uint8_t check_dictionary[MAX_DICTIONARY_SIZE]; + uint32_t check_dictionary_len = 0; + PREFIX3(stream) d_stream; /* decompression stream */ + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + d_stream.adler = 0; + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) + error("unexpected dictionary"); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (int)sizeof(dictionary)); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (check_dictionary_len < sizeof(dictionary)) + error("bad dictionary length\n"); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dictionary, &check_dictionary_len); + CHECK_ERR(err, "inflateGetDictionary"); +#ifndef S390_DFLTCC_INFLATE + if (memcmp(dictionary, check_dictionary, sizeof(dictionary)) != 0) + error("bad dictionary\n"); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strncmp((char*)uncompr, hello, sizeof(hello))) + error("bad inflate with dict\n"); + else + printf("inflate with dictionary: %s\n", (char *)uncompr); +} + +/* =========================================================================== + * Test deflateBound() with small buffers + */ +void test_deflate_bound(void) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)strlen(hello)+1; + int estimateLen = 0; + unsigned char *outBuf = NULL; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + c_stream.avail_in = len; + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_out = 0; + c_stream.next_out = outBuf; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + /* calculate actual output length and update structure */ + estimateLen = PREFIX(deflateBound)(&c_stream, len); + outBuf = malloc(estimateLen); + + if (outBuf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimateLen; + c_stream.next_out = outBuf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) { + printf("deflateBound(): OK\n"); + } else { + CHECK_ERR(err, "deflate"); + } + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(outBuf); +} + +/* =========================================================================== + * Test deflateCopy() with small buffers + */ +void test_deflate_copy(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream, c_stream_copy; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + CHECK_ERR(err, "deflate_copy"); + + if (c_stream.state->status == c_stream_copy.state->status) { + printf("deflate_copy(): OK\n"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd original"); + + err = PREFIX(deflateEnd)(&c_stream_copy); + CHECK_ERR(err, "deflateEnd copy"); +} + +/* =========================================================================== + * Test deflateGetDictionary() with small buffers + */ +void test_deflate_get_dict(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned char *dictNew = NULL; + unsigned int *dictLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (uInt)comprLen; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (unsigned int)strlen(hello)+1; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + + if (err != Z_STREAM_END) + error("deflate should report Z_STREAM_END\n"); + + dictNew = calloc(256, 1); + dictLen = (unsigned int *)calloc(4, 1); + err = PREFIX(deflateGetDictionary)(&c_stream, dictNew, dictLen); + + CHECK_ERR(err, "deflateGetDictionary"); + if (err == Z_OK) { + printf("deflateGetDictionary(): %s\n", dictNew); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(dictNew); + free(dictLen); +} + +/* =========================================================================== + * Test deflatePending() with small buffers + */ +void test_deflate_pending(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int *bits = calloc(256, 1); + unsigned *ped = calloc(256, 1); + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + CHECK_ERR(err, "deflatePending"); + + if (*bits >= 0 && *bits <= 7) { + printf("deflatePending(): OK\n"); + } else { + printf("deflatePending(): error\n"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(bits); + free(ped); +} + +/* =========================================================================== + * Test deflatePrime() wrapping gzip around deflate stream + */ +void test_deflate_prime(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + PREFIX3(stream) d_stream; /* decompression stream */ + int err; + size_t len = strlen(hello)+1; + uint32_t crc = 0; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + CHECK_ERR(err, "deflatePrime"); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + CHECK_ERR(err, "deflatePrime"); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + CHECK_ERR(err, "deflatePrime"); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + CHECK_ERR(err, "deflatePrime"); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + CHECK_ERR(err, "deflatePrime"); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)comprLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) + CHECK_ERR(err, "deflate"); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)len); + err = deflate_prime_32(&c_stream, crc); + CHECK_ERR(err, "deflatePrime"); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)len); + CHECK_ERR(err, "deflatePrime"); + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncomprLen; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + CHECK_ERR(err, "inflateInit"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_BUF_ERROR) { + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (strcmp((const char *)uncompr, hello) != 0) + error("bad deflatePrime\n"); + if (err == Z_OK) + printf("deflatePrime(): OK\n"); +} + +/* =========================================================================== + * Test deflateSetHeader() with small buffers + */ +void test_deflate_set_header(unsigned char *compr, size_t comprLen) { + PREFIX(gz_header) *head = calloc(1, sizeof(PREFIX(gz_header))); + PREFIX3(stream) c_stream; /* compression stream */ + int err; + size_t len = strlen(hello)+1; + + + if (head == NULL) + error("out of memory\n"); + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + CHECK_ERR(err, "deflateInit2"); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + CHECK_ERR(err, "deflateSetHeader"); + if (err == Z_OK) { + printf("deflateSetHeader(): OK\n"); + } + PREFIX(deflateBound)(&c_stream, (unsigned long)comprLen); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(head); +} + +/* =========================================================================== + * Test deflateTune() with small buffers + */ +void test_deflate_tune(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + size_t len = strlen(hello)+1; + + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (voidpf)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateTune)(&c_stream,(uInt)good_length,(uInt)max_lazy,nice_length,(uInt)max_chain); + CHECK_ERR(err, "deflateTune"); + if (err == Z_OK) { + printf("deflateTune(): OK\n"); + } + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate"); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Usage: example [output.gz [input.gz]] + */ +int main(int argc, char *argv[]) { + unsigned char *compr, *uncompr; + z_uintmax_t comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */ + z_uintmax_t uncomprLen = comprLen; + static const char* myVersion = PREFIX2(VERSION); + + if (zVersion()[0] != myVersion[0]) { + fprintf(stderr, "incompatible zlib version\n"); + exit(1); + + } else if (strcmp(zVersion(), PREFIX2(VERSION)) != 0) { + fprintf(stderr, "warning: different zlib version linked: %s\n", zVersion()); + } + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); + + compr = (unsigned char*)calloc((unsigned int)comprLen, 1); + uncompr = (unsigned char*)calloc((unsigned int)uncomprLen, 1); + /* compr and uncompr are cleared to avoid reading uninitialized + * data and to ensure that uncompr compresses well. + */ + if (compr == NULL || uncompr == NULL) + error("out of memory\n"); + + test_compress(compr, comprLen, uncompr, uncomprLen); + + test_gzio((argc > 1 ? argv[1] : TESTFILE), + uncompr, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 0); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + +#ifndef ZLIB_COMPAT + test_large_deflate(compr, comprLen, uncompr, uncomprLen, 1); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); +#endif + + test_flush(compr, &comprLen); +#ifdef ZLIBNG_ENABLE_TESTS + test_sync(compr, comprLen, uncompr, uncomprLen); +#endif + comprLen = uncomprLen; + + test_dict_deflate(compr, comprLen); + test_dict_inflate(compr, comprLen, uncompr, uncomprLen); + + test_deflate_bound(); + test_deflate_copy(compr, comprLen); + test_deflate_get_dict(compr, comprLen); + test_deflate_set_header(compr, comprLen); + test_deflate_tune(compr, comprLen); + test_deflate_pending(compr, comprLen); + test_deflate_prime(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/CMakeLists.txt new file mode 100644 index 000000000..27a04c0e7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.5.1) + +if(CMAKE_C_COMPILER_ID MATCHES "Clang") + enable_language(CXX) + + if(DEFINED ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE $ENV{LIB_FUZZING_ENGINE}) + set(FUZZING_ENGINE_FOUND ON) + else() + find_library(FUZZING_ENGINE "FuzzingEngine") + endif() +endif() + +set(FUZZERS + fuzzer_checksum + fuzzer_compress + fuzzer_example_small + fuzzer_example_large + fuzzer_example_flush + fuzzer_example_dict + ) + +if(WITH_GZFILEOP) + list(APPEND FUZZERS fuzzer_minigzip) +endif() + +foreach(FUZZER ${FUZZERS}) + add_executable(${FUZZER} ${FUZZER}.c) + + if(NOT FUZZING_ENGINE_FOUND) + target_sources(${FUZZER} PRIVATE standalone_fuzz_target_runner.c) + endif() + + if(NOT DEFINED BUILD_SHARED_LIBS) + target_link_libraries(${FUZZER} zlibstatic) + else() + target_link_libraries(${FUZZER} zlib) + endif() + + if(FUZZING_ENGINE_FOUND) + target_link_libraries(${FUZZER} ${FUZZING_ENGINE}) + endif() + + if(ZLIB_ENABLE_TESTS) + file(GLOB FUZZER_TEST_FILES ${PROJECT_SOURCE_DIR}/*) + set(FUZZER_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ ${FUZZER_TEST_FILES}) + add_test(NAME ${FUZZER} COMMAND ${FUZZER_COMMAND}) + endif() +endforeach() diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_checksum.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_checksum.c new file mode 100644 index 000000000..cedd284db --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_checksum.c @@ -0,0 +1,81 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + uint32_t crc0 = PREFIX(crc32)(0L, NULL, 0); + uint32_t crc1 = crc0; + uint32_t crc2 = crc0; + uint32_t adler0 = PREFIX(adler32)(0L, NULL, 0); + uint32_t adler1 = adler0; + uint32_t adler2 = adler0; + uint32_t combine1, combine2; + /* Checksum with a buffer of size equal to the first byte in the input. */ + uint32_t buffSize = data[0]; + uint32_t offset = 0; + uint32_t op; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + /* Make sure the buffer has at least a byte. */ + if (buffSize == 0) + ++buffSize; + + /* CRC32 */ + op = PREFIX(crc32_combine_gen)(buffSize); + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) { + uint32_t crc3 = PREFIX(crc32_z)(crc0, data + offset, buffSize); + uint32_t crc4 = PREFIX(crc32_combine_op)(crc1, crc3, op); + crc1 = PREFIX(crc32_z)(crc1, data + offset, buffSize); + assert(crc1 == crc4); + Z_UNUSED(crc1); + Z_UNUSED(crc4); + } + crc1 = PREFIX(crc32_z)(crc1, data + offset, dataLen % buffSize); + + crc2 = PREFIX(crc32_z)(crc2, data, dataLen); + + assert(crc1 == crc2); + Z_UNUSED(crc1); + Z_UNUSED(crc2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine)(crc1, crc1, (z_off_t)dataLen); + assert(combine1 == combine2); + + /* Fast CRC32 combine. */ + op = PREFIX(crc32_combine_gen)((z_off_t)dataLen); + combine1 = PREFIX(crc32_combine_op)(crc1, crc2, op); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + combine1 = PREFIX(crc32_combine)(crc1, crc2, (z_off_t)dataLen); + combine2 = PREFIX(crc32_combine_op)(crc2, crc1, op); + assert(combine1 == combine2); + + /* Adler32 */ + for (offset = 0; offset + buffSize <= dataLen; offset += buffSize) + adler1 = PREFIX(adler32_z)(adler1, data + offset, buffSize); + adler1 = PREFIX(adler32_z)(adler1, data + offset, dataLen % buffSize); + + adler2 = PREFIX(adler32_z)(adler2, data, dataLen); + + assert(adler1 == adler2); + Z_UNUSED(adler1); + Z_UNUSED(adler2); + combine1 = PREFIX(adler32_combine)(adler1, adler2, (z_off_t)dataLen); + combine2 = PREFIX(adler32_combine)(adler1, adler1, (z_off_t)dataLen); + assert(combine1 == combine2); + Z_UNUSED(combine1); + Z_UNUSED(combine2); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_compress.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_compress.c new file mode 100644 index 000000000..71cdf99ec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_compress.c @@ -0,0 +1,82 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +static const uint8_t *data; +static size_t dataLen; + +static void check_compress_level(uint8_t *compr, z_size_t comprLen, + uint8_t *uncompr, z_size_t uncomprLen, + int level) { + PREFIX(compress2)(compr, &comprLen, data, dataLen, level); + PREFIX(uncompress)(uncompr, &uncomprLen, compr, comprLen); + + /* Make sure compress + uncompress gives back the input data. */ + assert(dataLen == uncomprLen); + assert(0 == memcmp(data, uncompr, dataLen)); +} + +#define put_byte(s, i, c) {s[i] = (unsigned char)(c);} + +static void write_zlib_header(uint8_t *s) { + unsigned level_flags = 0; /* compression level (0..3) */ + unsigned w_bits = 8; /* window size log2(w_size) (8..16) */ + unsigned int header = (Z_DEFLATED + ((w_bits-8)<<4)) << 8; + header |= (level_flags << 6); + + header += 31 - (header % 31); + + /* s is guaranteed to be longer than 2 bytes. */ + put_byte(s, 0, (header >> 8)); + put_byte(s, 1, (header & 0xff)); +} + +static void check_decompress(uint8_t *compr, size_t comprLen) { + /* We need to write a valid zlib header of size two bytes. Copy the input data + in a larger buffer. Do not modify the input data to avoid libFuzzer error: + fuzz target overwrites its const input. */ + size_t copyLen = dataLen + 2; + uint8_t *copy = (uint8_t *)malloc(copyLen); + memcpy(copy + 2, data, dataLen); + write_zlib_header(copy); + + PREFIX(uncompress)(compr, &comprLen, copy, copyLen); + free(copy); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + /* compressBound does not provide enough space for low compression levels. */ + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + check_compress_level(compr, comprLen, uncompr, uncomprLen, 1); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 3); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 6); + check_compress_level(compr, comprLen, uncompr, uncomprLen, 7); + + check_decompress(compr, comprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_dict.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_dict.c new file mode 100644 index 000000000..053a3e101 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_dict.c @@ -0,0 +1,164 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int dictionaryLen = 0; +static unsigned long dictId; /* Adler32 value of the dictionary */ + +/* =========================================================================== + * Test deflate() with preset dictionary + */ +void test_dict_deflate(unsigned char **compr, size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + int level = data[0] % 11 - 1; /* [-1..9] + compression levels + #define Z_NO_COMPRESSION 0 + #define Z_BEST_SPEED 1 + #define Z_BEST_COMPRESSION 9 + #define Z_DEFAULT_COMPRESSION (-1) */ + + int method = Z_DEFLATED; /* The deflate compression method (the only one + supported in this version) */ + int windowBits = 8 + data[(dataLen > 1) ? 1:0] % 8; /* The windowBits parameter is the base + two logarithm of the window size (the size of the history buffer). It + should be in the range 8..15 for this version of the library. */ + int memLevel = 1 + data[(dataLen > 2) ? 2:0] % 9; /* memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. */ + int strategy = data[(dataLen > 3) ? 3:0] % 5; /* [0..4] + #define Z_FILTERED 1 + #define Z_HUFFMAN_ONLY 2 + #define Z_RLE 3 + #define Z_FIXED 4 + #define Z_DEFAULT_STRATEGY 0 */ + + /* deflate would fail for no-compression or for speed levels. */ + if (level == 0 || level == 1) + level = -1; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit2)(&c_stream, level, method, windowBits, memLevel, + strategy); + CHECK_ERR(err, "deflateInit"); + + err = PREFIX(deflateSetDictionary)( + &c_stream, (const unsigned char *)data, dictionaryLen); + CHECK_ERR(err, "deflateSetDictionary"); + + /* deflateBound does not provide enough space for low compression levels. */ + *comprLen = 100 + 2 * PREFIX(deflateBound)(&c_stream, (unsigned long)dataLen); + *compr = (uint8_t *)calloc(1, *comprLen); + + dictId = c_stream.adler; + c_stream.next_out = *compr; + c_stream.avail_out = (unsigned int)(*comprLen); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.avail_in = (uint32_t)dataLen; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate dict should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with a preset dictionary + */ +void test_dict_inflate(unsigned char *compr, size_t comprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + unsigned char *uncompr; + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + uncompr = (uint8_t *)calloc(1, dataLen); + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)dataLen; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + if (d_stream.adler != dictId) { + fprintf(stderr, "unexpected dictionary"); + exit(1); + } + err = PREFIX(inflateSetDictionary)( + &d_stream, (const unsigned char *)data, dictionaryLen); + } + CHECK_ERR(err, "inflate with dict"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate with dict\n"); + exit(1); + } + + free(uncompr); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 0; + uint8_t *compr; + + /* Discard inputs larger than 100Kb. */ + static size_t kMaxSize = 100 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + + /* Set up the contents of the dictionary. The size of the dictionary is + intentionally selected to be of unusual size. To help cover more corner + cases, the size of the dictionary is read from the input data. */ + dictionaryLen = data[0]; + if (dictionaryLen > dataLen) + dictionaryLen = (unsigned int)dataLen; + + test_dict_deflate(&compr, &comprLen); + test_dict_inflate(compr, comprLen); + + free(compr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_flush.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_flush.c new file mode 100644 index 000000000..baa6988e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_flush.c @@ -0,0 +1,119 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with full flush + */ +void test_flush(unsigned char *compr, z_size_t *comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned int len = (unsigned int)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (unsigned int)*comprLen; + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + CHECK_ERR(err, "deflate flush 1"); + + compr[3]++; /* force an error in first compressed block */ + c_stream.avail_in = len - 3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + CHECK_ERR(err, "deflate flush 2"); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + *comprLen = (z_size_t)c_stream.total_out; +} + +/* =========================================================================== + * Test inflateSync() + */ +void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 2; /* just read the zlib header */ + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncomprLen; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + CHECK_ERR(err, "inflate"); + + d_stream.avail_in = (unsigned int)comprLen - 2; /* read all compressed data */ + err = PREFIX(inflateSync)(&d_stream); /* but skip the damaged part */ + CHECK_ERR(err, "inflateSync"); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "inflate should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + z_size_t comprLen = 100 + 2 * PREFIX(compressBound)(size); + z_size_t uncomprLen = (z_size_t)size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + // This test requires at least 3 bytes of input data. + if (size <= 3 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_flush(compr, &comprLen); + test_sync(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_large.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_large.c new file mode 100644 index 000000000..411459721 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_large.c @@ -0,0 +1,137 @@ +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; +static unsigned int diff; + +/* =========================================================================== + * Test deflate() with large buffers and dynamic change of compression level + */ +void test_large_deflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_out = compr; + c_stream.avail_out = (unsigned int)comprLen; + + /* At this point, uncompr is still mostly zeroes, so it should compress + * very well: + */ + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 1"); + if (c_stream.avail_in != 0) { + fprintf(stderr, "deflate not greedy\n"); + exit(1); + } + + /* Feed in already compressed data and switch to no compression: */ + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 2"); + + /* Switch back to compressing mode: */ + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncomprLen; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate large 3"); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err != Z_STREAM_END) { + fprintf(stderr, "deflate large should report Z_STREAM_END\n"); + exit(1); + } + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with large buffers + */ +void test_large_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)comprLen; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = (unsigned int)uncomprLen; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "large inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (d_stream.total_out != 2 * uncomprLen + diff) { + fprintf(stderr, "bad large inflate: %" PRIu64 "\n", (uint64_t)d_stream.total_out); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = 100 + 3 * size; + size_t uncomprLen = comprLen; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 512Kb. */ + static size_t kMaxSize = 512 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_large_deflate(compr, comprLen, uncompr, uncomprLen); + test_large_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_small.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_small.c new file mode 100644 index 000000000..e59c72083 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_example_small.c @@ -0,0 +1,118 @@ +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +static const uint8_t *data; +static size_t dataLen; +static alloc_func zalloc = NULL; +static free_func zfree = NULL; + +/* =========================================================================== + * Test deflate() with small buffers + */ +void test_deflate(unsigned char *compr, size_t comprLen) { + PREFIX3(stream) c_stream; /* compression stream */ + int err; + unsigned long len = (unsigned long)dataLen; + + c_stream.zalloc = zalloc; + c_stream.zfree = zfree; + c_stream.opaque = (void *)0; + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + CHECK_ERR(err, "deflateInit"); + + c_stream.next_in = (z_const unsigned char *)data; + c_stream.next_out = compr; + + while (c_stream.total_in != len && c_stream.total_out < comprLen) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + CHECK_ERR(err, "deflate small 1"); + } + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "deflate small 2"); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); +} + +/* =========================================================================== + * Test inflate() with small buffers + */ +void test_inflate(unsigned char *compr, size_t comprLen, unsigned char *uncompr, size_t uncomprLen) { + int err; + PREFIX3(stream) d_stream; /* decompression stream */ + + d_stream.zalloc = zalloc; + d_stream.zfree = zfree; + d_stream.opaque = (void *)0; + + d_stream.next_in = compr; + d_stream.avail_in = 0; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + CHECK_ERR(err, "inflateInit"); + + while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + CHECK_ERR(err, "inflate"); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + if (memcmp(uncompr, data, dataLen)) { + fprintf(stderr, "bad inflate\n"); + exit(1); + } +} + +int LLVMFuzzerTestOneInput(const uint8_t *d, size_t size) { + size_t comprLen = PREFIX(compressBound)(size); + size_t uncomprLen = size; + uint8_t *compr, *uncompr; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + + if (size < 1 || size > kMaxSize) + return 0; + + data = d; + dataLen = size; + compr = (uint8_t *)calloc(1, comprLen); + uncompr = (uint8_t *)calloc(1, uncomprLen); + + test_deflate(compr, comprLen); + test_inflate(compr, comprLen, uncompr, uncomprLen); + + free(compr); + free(uncompr); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_minigzip.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_minigzip.c new file mode 100644 index 000000000..819148d2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/fuzzer_minigzip.c @@ -0,0 +1,325 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#define BUFLEN 16384 /* read buffer size */ +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static const char *prog = "minigzip_fuzzer"; + +void error (const char *msg); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode); +void file_uncompress (char *file); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char buf[BUFLEN]; + int len; + int err; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + /* Clear out the contents of buf before reading from the file to avoid + MemorySanitizer: use-of-uninitialized-value warnings. */ + memset(buf, 0, sizeof(buf)); + for (;;) { + len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) error(PREFIX(gzerror)(out, &err)); + } + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int err; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, (char *)buf, (unsigned)buf_len); + + if (len != (int)buf_len) error(PREFIX(gzerror)(out, &err)); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char buf[BUFLENW]; + int len; + int err; + + for (;;) { + len = PREFIX(gzread)(in, buf, sizeof(buf)); + if (len < 0) error (PREFIX(gzerror)(in, &err)); + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + error("failed fwrite"); + } + } + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + unlink(infile); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataLen) { + char *inFileName = "minigzip_fuzzer.out"; + char *outFileName = "minigzip_fuzzer.out.gz"; + char outmode[20]; + FILE *in; + char buf[BUFLEN]; + uint32_t offset = 0; + + /* Discard inputs larger than 1Mb. */ + static size_t kMaxSize = 1024 * 1024; + if (dataLen < 1 || dataLen > kMaxSize) + return 0; + + in = fopen(inFileName, "wb"); + if (fwrite(data, 1, (unsigned)dataLen, in) != dataLen) + error("failed fwrite"); + if (fclose(in)) + error("failed fclose"); + + memset(outmode, 0, sizeof(outmode)); + snprintf(outmode, sizeof(outmode), "%s", "wb"); + + /* Compression level: [0..9]. */ + outmode[2] = '0' + (data[0] % 10); + + switch (data[dataLen-1] % 6) { + default: + case 0: + outmode[3] = 0; + break; + case 1: + /* compress with Z_FILTERED */ + outmode[3] = 'f'; + break; + case 2: + /* compress with Z_HUFFMAN_ONLY */ + outmode[3] = 'h'; + break; + case 3: + /* compress with Z_RLE */ + outmode[3] = 'R'; + break; + case 4: + /* compress with Z_FIXED */ + outmode[3] = 'F'; + break; + case 5: + /* direct */ + outmode[3] = 'T'; + break; + } + + file_compress(inFileName, outmode); + + /* gzopen does not support reading in direct mode */ + if (outmode[3] == 'T') + inFileName = outFileName; + else + file_uncompress(outFileName); + + /* Check that the uncompressed file matches the input data. */ + in = fopen(inFileName, "rb"); + if (in == NULL) { + perror(inFileName); + exit(1); + } + + memset(buf, 0, sizeof(buf)); + for (;;) { + int len = (int)fread(buf, 1, sizeof(buf), in); + if (ferror(in)) { + perror("fread"); + exit(1); + } + if (len == 0) + break; + assert(0 == memcmp(data + offset, buf, len)); + offset += len; + } + + if (fclose(in)) + error("failed fclose"); + + /* This function must return 0. */ + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/standalone_fuzz_target_runner.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/standalone_fuzz_target_runner.c new file mode 100644 index 000000000..810a56072 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/fuzz/standalone_fuzz_target_runner.c @@ -0,0 +1,37 @@ +#include +#include + +#include "zbuild.h" + +extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size); + +int main(int argc, char **argv) { + int i; + fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1); + + for (i = 1; i < argc; i++) { + size_t len, n_read, err; + unsigned char *buf; + FILE *f = fopen(argv[i], "rb+"); + if (!f) { + /* Failed to open this file: it may be a directory. */ + fprintf(stderr, "Skipping: %s\n", argv[i]); + continue; + } + fprintf(stderr, "Running: %s %s\n", argv[0], argv[i]); + fseek(f, 0, SEEK_END); + len = ftell(f); + fseek(f, 0, SEEK_SET); + buf = (unsigned char *)malloc(len); + n_read = fread(buf, 1, len, f); + assert(n_read == len); + LLVMFuzzerTestOneInput(buf, len); + free(buf); + err = fclose(f); + assert(err == 0); + Z_UNUSED(err); + fprintf(stderr, "Done: %s: (%d bytes)\n", argv[i], (int)n_read); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/gh1235.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/gh1235.c new file mode 100644 index 000000000..7bf8738f3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/gh1235.c @@ -0,0 +1,39 @@ +#include +#include +#include +#include "zutil.h" + +int main(void) { + unsigned char plain[32]; + unsigned char compressed[130]; + PREFIX3(stream) strm; + z_size_t bound; + z_size_t bytes; + + for (int i = 0; i <= 32; i++) { + memset(plain, 6, i); + memset(&strm, 0, sizeof(strm)); + PREFIX(deflateInit2)(&strm, 0, 8, 31, 1, Z_DEFAULT_STRATEGY); + bound = PREFIX(deflateBound)(&strm, i); + strm.next_in = plain; + strm.next_out = compressed; + strm.avail_in = i; + strm.avail_out = sizeof(compressed); + if (PREFIX(deflate)(&strm, Z_FINISH) != Z_STREAM_END) return -1; + if (strm.avail_in != 0) return -1; + printf("bytes = %2i, deflateBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)strm.total_out); + if (bound < strm.total_out) return -1; + if (PREFIX(deflateEnd)(&strm) != Z_OK) return -1; + } + for (int i = 0; i <= 32; i++) { + bytes = sizeof(compressed); + for (int j = 0; j < i; j++) { + plain[j] = j; + } + bound = PREFIX(compressBound)(i); + if (PREFIX(compress2)(compressed, &bytes, plain, i, 1) != Z_OK) return -1; + printf("bytes = %2i, compressBound = %2zi, total_out = %2zi\n", i, (size_t)bound, (size_t)bytes); + if (bytes > bound) return -1; + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/infcover.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/infcover.c new file mode 100644 index 000000000..6606d222a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/infcover.c @@ -0,0 +1,686 @@ +/* infcover.c -- test zlib's inflate routines with full code coverage + * Copyright (C) 2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* to use, do: ./configure --cover && make cover */ + +#include +#include +#include +#undef NDEBUG +#include +#include + +/* get definition of internal structure so we can mess with it (see pull()), + and so we can call inflate_trees() (see cover5()) */ +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +/* -- memory tracking routines -- */ + +/* + These memory tracking routines are provided to zlib and track all of zlib's + allocations and deallocations, check for LIFO operations, keep a current + and high water mark of total bytes requested, optionally set a limit on the + total memory that can be allocated, and when done check for memory leaks. + + They are used as follows: + + PREFIX3(stream) strm; + mem_setup(&strm) initializes the memory tracking and sets the + zalloc, zfree, and opaque members of strm to use + memory tracking for all zlib operations on strm + mem_limit(&strm, limit) sets a limit on the total bytes requested -- a + request that exceeds this limit will result in an + allocation failure (returns NULL) -- setting the + limit to zero means no limit, which is the default + after mem_setup() + mem_used(&strm, "msg") prints to stderr "msg" and the total bytes used + mem_high(&strm, "msg") prints to stderr "msg" and the high water mark + mem_done(&strm, "msg") ends memory tracking, releases all allocations + for the tracking as well as leaked zlib blocks, if + any. If there was anything unusual, such as leaked + blocks, non-FIFO frees, or frees of addresses not + allocated, then "msg" and information about the + problem is printed to stderr. If everything is + normal, nothing is printed. mem_done resets the + strm members to NULL to use the default memory + allocation routines on the next zlib initialization + using strm. + */ + +/* these items are strung together in a linked list, one for each allocation */ +struct mem_item { + void *ptr; /* pointer to allocated memory */ + size_t size; /* requested size of allocation */ + struct mem_item *next; /* pointer to next item in list, or NULL */ +}; + +/* this structure is at the root of the linked list, and tracks statistics */ +struct mem_zone { + struct mem_item *first; /* pointer to first item in list, or NULL */ + size_t total, highwater; /* total allocations, and largest total */ + size_t limit; /* memory allocation limit, or 0 if no limit */ + int notlifo, rogue; /* counts of non-LIFO frees and rogue frees */ +}; + +/* memory allocation routine to pass to zlib */ +static void *mem_alloc(void *mem, unsigned count, unsigned size) { + void *ptr; + struct mem_item *item; + struct mem_zone *zone = mem; + size_t len = count * (size_t)size; + + /* induced allocation failure */ + if (zone == NULL || (zone->limit && zone->total + len > zone->limit)) + return NULL; + + /* perform allocation using the standard library, fill memory with a + non-zero value to make sure that the code isn't depending on zeros */ + ptr = malloc(len); + if (ptr == NULL) + return NULL; + memset(ptr, 0xa5, len); + + /* create a new item for the list */ + item = malloc(sizeof(struct mem_item)); + if (item == NULL) { + free(ptr); + return NULL; + } + item->ptr = ptr; + item->size = len; + + /* insert item at the beginning of the list */ + item->next = zone->first; + zone->first = item; + + /* update the statistics */ + zone->total += item->size; + if (zone->total > zone->highwater) + zone->highwater = zone->total; + + /* return the allocated memory */ + return ptr; +} + +/* memory free routine to pass to zlib */ +static void mem_free(void *mem, void *ptr) { + struct mem_item *item, *next; + struct mem_zone *zone = mem; + + /* if no zone, just do a free */ + if (zone == NULL) { + free(ptr); + return; + } + + /* point next to the item that matches ptr, or NULL if not found -- remove + the item from the linked list if found */ + next = zone->first; + if (next) { + if (next->ptr == ptr) + zone->first = next->next; /* first one is it, remove from list */ + else { + do { /* search the linked list */ + item = next; + next = item->next; + } while (next != NULL && next->ptr != ptr); + if (next) { /* if found, remove from linked list */ + item->next = next->next; + zone->notlifo++; /* not a LIFO free */ + } + + } + } + + /* if found, update the statistics and free the item */ + if (next) { + zone->total -= next->size; + free(next); + } + + /* if not found, update the rogue count */ + else + zone->rogue++; + + /* in any case, do the requested free with the standard library function */ + free(ptr); +} + +/* set up a controlled memory allocation space for monitoring, set the stream + parameters to the controlled routines, with opaque pointing to the space */ +static void mem_setup(PREFIX3(stream) *strm) { + struct mem_zone *zone; + + zone = malloc(sizeof(struct mem_zone)); + assert(zone != NULL); + zone->first = NULL; + zone->total = 0; + zone->highwater = 0; + zone->limit = 0; + zone->notlifo = 0; + zone->rogue = 0; + strm->opaque = zone; + strm->zalloc = mem_alloc; + strm->zfree = mem_free; +} + +/* set a limit on the total memory allocation, or 0 to remove the limit */ +static void mem_limit(PREFIX3(stream) *strm, size_t limit) { + struct mem_zone *zone = strm->opaque; + + zone->limit = limit; +} + +/* show the current total requested allocations in bytes */ +static void mem_used(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " allocated\n", prefix, (uint64_t)zone->total); +} + +/* show the high water allocation in bytes */ +static void mem_high(PREFIX3(stream) *strm, char *prefix) { + struct mem_zone *zone = strm->opaque; + + fprintf(stderr, "%s: %" PRIu64 " high water mark\n", prefix, (uint64_t)zone->highwater); +} + +/* release the memory allocation zone -- if there are any surprises, notify */ +static void mem_done(PREFIX3(stream) *strm, char *prefix) { + int count = 0; + struct mem_item *item, *next; + struct mem_zone *zone = strm->opaque; + + /* show high water mark */ + mem_high(strm, prefix); + + /* free leftover allocations and item structures, if any */ + item = zone->first; + while (item != NULL) { + free(item->ptr); + next = item->next; + free(item); + item = next; + count++; + } + + /* issue alerts about anything unexpected */ + if (count || zone->total) + fprintf(stderr, "** %s: %" PRIu64 " bytes in %d blocks not freed\n", + prefix, (uint64_t)zone->total, count); + if (zone->notlifo) + fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo); + if (zone->rogue) + fprintf(stderr, "** %s: %d frees not recognized\n", + prefix, zone->rogue); + + /* free the zone and delete from the stream */ + free(zone); + strm->opaque = NULL; + strm->zalloc = NULL; + strm->zfree = NULL; +} + +/* -- inflate test routines -- */ + +/* Decode a hexadecimal string, set *len to length, in[] to the bytes. This + decodes liberally, in that hex digits can be adjacent, in which case two in + a row writes a byte. Or they can be delimited by any non-hex character, + where the delimiters are ignored except when a single hex digit is followed + by a delimiter, where that single digit writes a byte. The returned data is + allocated and must eventually be freed. NULL is returned if out of memory. + If the length is not needed, then len can be NULL. */ +static unsigned char *h2b(const char *hex, unsigned *len) { + unsigned char *in, *re; + unsigned next, val; + size_t inlen; + + inlen = (strlen(hex) + 1) >> 1; + assert(inlen != 0); /* tell static analyzer we won't call malloc(0) */ + in = malloc(inlen); + if (in == NULL) + return NULL; + next = 0; + val = 1; + do { + if (*hex >= '0' && *hex <= '9') + val = (val << 4) + *hex - '0'; + else if (*hex >= 'A' && *hex <= 'F') + val = (val << 4) + *hex - 'A' + 10; + else if (*hex >= 'a' && *hex <= 'f') + val = (val << 4) + *hex - 'a' + 10; + else if (val != 1 && val < 32) /* one digit followed by delimiter */ + val += 240; /* make it look like two digits */ + if (val > 255) { /* have two digits */ + in[next++] = val & 0xff; /* save the decoded byte */ + val = 1; /* start over */ + } + } while (*hex++); /* go through the loop with the terminating null */ + if (len != NULL) + *len = next; + assert(next != 0); /* tell static analyzer we won't call realloc(in, 0) */ + re = realloc(in, next); + return re == NULL ? in : re; +} + +/* generic inflate() run, where hex is the hexadecimal input data, what is the + text to include in an error message, step is how much input data to feed + inflate() on each call, or zero to feed it all, win is the window bits + parameter to inflateInit2(), len is the size of the output buffer, and err + is the error code expected from the first inflate() call (the second + inflate() call is expected to return Z_STREAM_END). If win is 47, then + header information is collected with inflateGetHeader(). If a zlib stream + is looking for a dictionary, then an empty dictionary is provided. + inflate() is run until all of the input data is consumed. */ +static void inf(char *hex, char *what, unsigned step, int win, unsigned len, int err) { + int ret; + unsigned have; + unsigned char *in, *out; + PREFIX3(stream) strm, copy; + PREFIX(gz_header) head; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, win); + if (ret != Z_OK) { + mem_done(&strm, what); + return; + } + out = malloc(len); assert(out != NULL); + if (win == 47) { + head.extra = out; + head.extra_max = len; + head.name = out; + head.name_max = len; + head.comment = out; + head.comm_max = len; + ret = PREFIX(inflateGetHeader)(&strm, &head); + assert(ret == Z_OK); + } + in = h2b(hex, &have); assert(in != NULL); + if (step == 0 || step > have) + step = have; + strm.avail_in = step; + have -= step; + strm.next_in = in; + do { + strm.avail_out = len; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(err == 9 || ret == err); + if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT) + break; + if (ret == Z_NEED_DICT) { + ret = PREFIX(inflateSetDictionary)(&strm, in, 1); + assert(ret == Z_DATA_ERROR); + mem_limit(&strm, 1); + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ((struct inflate_state *)strm.state)->mode = DICT; + ret = PREFIX(inflateSetDictionary)(&strm, out, 0); + assert(ret == Z_OK); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); + assert(ret == Z_BUF_ERROR); + } + ret = PREFIX(inflateCopy)(©, &strm); + assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(©); assert(ret == Z_OK); + err = 9; /* don't care next time around */ + have += strm.avail_in; + strm.avail_in = step > have ? have : step; + have -= strm.avail_in; + } while (strm.avail_in); + free(in); + free(out); + ret = PREFIX(inflateReset2)(&strm, -8); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, what); + Z_UNUSED(err); +} + +/* cover all of the lines in inflate.c up to inflate() */ +static void cover_support(void) { + int ret; + PREFIX3(stream) strm; + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + mem_used(&strm, "inflate init"); + ret = PREFIX(inflatePrime)(&strm, 5, 31); assert(ret == Z_OK); + ret = PREFIX(inflatePrime)(&strm, -1, 0); assert(ret == Z_OK); + ret = PREFIX(inflateSetDictionary)(&strm, NULL, 0); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "prime"); + + inf("63 0", "force window allocation", 0, -15, 1, Z_OK); + inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK); + inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK); + inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END); + inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR); + +#ifdef ZLIB_COMPAT + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit_)(&strm, &PREFIX2(VERSION)[1], (int)sizeof(PREFIX3(stream))); + assert(ret == Z_VERSION_ERROR); + mem_done(&strm, "wrong version"); +#endif + + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit)(&strm); assert(ret == Z_OK); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + fputs("inflate built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* cover all inflate() header and trailer cases and code after inflate() */ +static void cover_wrap(void) { + int ret; + PREFIX3(stream) strm, copy; + unsigned char dict[257]; + + ret = PREFIX(inflate)(NULL, 0); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateEnd)(NULL); assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateCopy)(NULL, NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflate bad parameters\n", stderr); + + inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR); + inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR); + inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR); + inf("8 99", "set window size from header", 0, 0, 0, Z_OK); + inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR); + inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END); + inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1, + Z_DATA_ERROR); + inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length", + 0, 47, 0, Z_STREAM_END); + inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR); + inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT); + inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK); + + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, -8); + strm.avail_in = 2; + strm.next_in = (void *)"\x63"; + strm.avail_out = 1; + strm.next_out = (void *)&ret; + mem_limit(&strm, 1); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + memset(dict, 0, 257); + ret = PREFIX(inflateSetDictionary)(&strm, dict, 257); + assert(ret == Z_OK); + mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256); + ret = PREFIX(inflatePrime)(&strm, 16, 0); assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x80"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_DATA_ERROR); + ret = PREFIX(inflate)(&strm, Z_NO_FLUSH); assert(ret == Z_STREAM_ERROR); + strm.avail_in = 4; + strm.next_in = (void *)"\0\0\xff\xff"; + ret = PREFIX(inflateSync)(&strm); assert(ret == Z_OK); + (void)PREFIX(inflateSyncPoint)(&strm); + ret = PREFIX(inflateCopy)(©, &strm); assert(ret == Z_MEM_ERROR); + mem_limit(&strm, 0); + ret = PREFIX(inflateUndermine)(&strm, 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + assert(ret == Z_OK); +#else + assert(ret == Z_DATA_ERROR); +#endif + (void)PREFIX(inflateMark)(&strm); + ret = PREFIX(inflateEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "miscellaneous, force memory errors"); +} + +/* input and output functions for inflateBack() */ +static unsigned pull(void *desc, z_const unsigned char **buf) { + static unsigned int next = 0; + static unsigned char dat[] = {0x63, 0, 2, 0}; + struct inflate_state *state; + + if (desc == NULL) { + next = 0; + return 0; /* no input (already provided at next_in) */ + } + state = (void *)((PREFIX3(stream) *)desc)->state; + if (state != NULL) + state->mode = SYNC; /* force an otherwise impossible situation */ + return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0; +} + +static int push(void *desc, unsigned char *buf, unsigned len) { + buf += len; + Z_UNUSED(buf); + return desc != NULL; /* force error if desc not null */ +} + +/* cover inflateBack() up to common deflate data cases and after those */ +static void cover_back(void) { + int ret; + PREFIX3(stream) strm; + unsigned char win[32768]; + +#ifdef ZLIB_COMPAT + ret = PREFIX(inflateBackInit_)(NULL, 0, win, 0, 0); + assert(ret == Z_VERSION_ERROR); +#endif + + ret = PREFIX(inflateBackInit)(NULL, 0, win); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBack)(NULL, NULL, NULL, NULL, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(NULL); assert(ret == Z_STREAM_ERROR); + fputs("inflateBack bad parameters\n", stderr); + + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = 2; + strm.next_in = (void *)"\x03"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret == Z_STREAM_END); + /* force output error */ + strm.avail_in = 3; + strm.next_in = (void *)"\x63\x00"; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, &strm); + assert(ret == Z_BUF_ERROR); + /* force mode error by mucking with state */ + ret = PREFIX(inflateBack)(&strm, pull, &strm, push, NULL); + assert(ret == Z_STREAM_ERROR); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + mem_done(&strm, "inflateBack bad state"); + + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + ret = PREFIX(inflateBackEnd)(&strm); assert(ret == Z_OK); + fputs("inflateBack built-in memory routines\n", stderr); + Z_UNUSED(ret); +} + +/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */ +static int try(char *hex, char *id, int err) { + int ret; + unsigned len, size; + unsigned char *in, *out, *win; + char *prefix; + PREFIX3(stream) strm; + + /* convert to hex */ + in = h2b(hex, &len); + assert(in != NULL); + + /* allocate work areas */ + size = len << 3; + out = malloc(size); + assert(out != NULL); + win = malloc(32768); + assert(win != NULL); + prefix = malloc(strlen(id) + 6); + assert(prefix != NULL); + + /* first with inflate */ + strcpy(prefix, id); + strcat(prefix, "-late"); + mem_setup(&strm); + strm.avail_in = 0; + strm.next_in = NULL; + ret = PREFIX(inflateInit2)(&strm, err < 0 ? 47 : -15); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + do { + strm.avail_out = size; + strm.next_out = out; + ret = PREFIX(inflate)(&strm, Z_TREES); + assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR); + if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT) + break; + } while (strm.avail_in || strm.avail_out == 0); + if (err) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateEnd)(&strm); + mem_done(&strm, prefix); + + /* then with inflateBack */ + if (err >= 0) { + strcpy(prefix, id); + strcat(prefix, "-back"); + mem_setup(&strm); + ret = PREFIX(inflateBackInit)(&strm, 15, win); + assert(ret == Z_OK); + strm.avail_in = len; + strm.next_in = in; + ret = PREFIX(inflateBack)(&strm, pull, NULL, push, NULL); + assert(ret != Z_STREAM_ERROR); + if (err && ret != Z_BUF_ERROR) { + assert(ret == Z_DATA_ERROR); + assert(strcmp(id, strm.msg) == 0); + } + PREFIX(inflateBackEnd)(&strm); + mem_done(&strm, prefix); + } + + /* clean up */ + free(prefix); + free(win); + free(out); + free(in); + return ret; +} + +/* cover deflate data cases in both inflate() and inflateBack() */ +static void cover_inflate(void) { + try("0 0 0 0 0", "invalid stored block lengths", 1); + try("3 0", "fixed", 0); + try("6", "invalid block type", 1); + try("1 1 0 fe ff 0", "stored", 0); + try("fc 0 0", "too many length or distance symbols", 1); + try("4 0 fe ff", "invalid code lengths set", 1); + try("4 0 24 49 0", "invalid bit length repeat", 1); + try("4 0 24 e9 ff ff", "invalid bit length repeat", 1); + try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1); + try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0", + "invalid literal/lengths set", 1); + try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1); + try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1); + try("2 7e ff ff", "invalid distance code", 1); +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 0); +#else + try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1); +#endif + + /* also trailer mismatch just in inflate() */ + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1); + try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1", + "incorrect length check", -1); + try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0); + try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f", + "long code", 0); + try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0); + try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c", + "long distance and extra", 0); + try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " + "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 6", "window end", 0); + inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258, + Z_STREAM_END); + inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK); +} + +/* cover remaining lines in inftrees.c */ +static void cover_trees(void) { + int ret; + unsigned bits; + uint16_t lens[16], work[16]; + code *next, table[ENOUGH_DISTS]; + + /* we need to call inflate_table() directly in order to manifest not- + enough errors, since zlib insures that enough is always enough */ + for (bits = 0; bits < 15; bits++) + lens[bits] = (uint16_t)(bits + 1); + lens[15] = 15; + next = table; + bits = 15; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + next = table; + bits = 1; + ret = zng_inflate_table(DISTS, lens, 16, &next, &bits, work); + assert(ret == 1); + fputs("inflate_table not enough errors\n", stderr); + Z_UNUSED(ret); +} + +/* cover remaining inffast.c decoding and window copying */ +static void cover_fast(void) { + inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68" + " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR); + inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49" + " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258, + Z_DATA_ERROR); + inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258, + Z_DATA_ERROR); + inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258, + Z_DATA_ERROR); + inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0", + "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR); + inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK); + inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0", + "contiguous and wrap around window", 6, -8, 259, Z_OK); + inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259, + Z_STREAM_END); +} + +static void cover_cve_2022_37434(void) { + inf("1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51 1f 8b 08 04 61 62 63 64 61 62 52 51", "wtf", 13, 47, 12, Z_OK); +} + +int main(void) { + fprintf(stderr, "%s\n", zVersion()); + cover_support(); + cover_wrap(); + cover_back(); + cover_inflate(); + cover_trees(); + cover_fast(); + cover_cve_2022_37434(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/minideflate.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/minideflate.c new file mode 100644 index 000000000..987e6121b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/minideflate.c @@ -0,0 +1,359 @@ +/* minideflate.c -- test deflate/inflate under specific conditions + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#include +#include + +#include "zutil.h" + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +# ifdef _MSC_VER +# define strcasecmp _stricmp +# endif +#else +# include +# define SET_BINARY_MODE(file) +#endif + +#define CHECK_ERR(err, msg) { \ + if (err != Z_OK) { \ + fprintf(stderr, "%s error: %d\n", msg, err); \ + exit(1); \ + } \ +} + +/* Default read/write i/o buffer size based on GZBUFSIZE */ +#define BUFSIZE 131072 + +/* =========================================================================== + * deflate() using specialized parameters + */ +void deflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t level, + int32_t window_bits, int32_t mem_level, int32_t strategy, int32_t flush) { + PREFIX3(stream) c_stream; /* compression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + c_stream.zalloc = NULL; + c_stream.zfree = NULL; + c_stream.opaque = (void *)0; + c_stream.total_in = 0; + c_stream.total_out = 0; + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + + err = PREFIX(deflateInit2)(&c_stream, level, Z_DEFLATED, window_bits, mem_level, strategy); + CHECK_ERR(err, "deflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + c_stream.next_in = (z_const uint8_t *)read_buf; + c_stream.avail_in = read; + + do { + err = PREFIX(deflate)(&c_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + } while (c_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + c_stream.avail_in = 0; + do { + if (c_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + c_stream.next_out = write_buf; + c_stream.avail_out = write_buf_size; + } + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "deflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (c_stream.next_out != write_buf) { + fwrite(write_buf, 1, c_stream.next_out - write_buf, fout); + } + + err = PREFIX(deflateEnd)(&c_stream); + CHECK_ERR(err, "deflateEnd"); + + free(read_buf); + free(write_buf); +} + +/* =========================================================================== + * inflate() using specialized parameters + */ +void inflate_params(FILE *fin, FILE *fout, int32_t read_buf_size, int32_t write_buf_size, int32_t window_bits, + int32_t flush) { + PREFIX3(stream) d_stream; /* decompression stream */ + uint8_t *read_buf; + uint8_t *write_buf; + int32_t read; + int err; + + + read_buf = (uint8_t *)malloc(read_buf_size); + if (read_buf == NULL) { + fprintf(stderr, "failed to create read buffer (%d)\n", read_buf_size); + return; + } + write_buf = (uint8_t *)malloc(write_buf_size); + if (write_buf == NULL) { + fprintf(stderr, "failed to create write buffer (%d)\n", write_buf_size); + free(read_buf); + return; + } + + d_stream.zalloc = NULL; + d_stream.zfree = NULL; + d_stream.opaque = (void *)0; + d_stream.total_in = 0; + d_stream.total_out = 0; + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + + err = PREFIX(inflateInit2)(&d_stream, window_bits); + CHECK_ERR(err, "inflateInit2"); + + /* Process input using our read buffer and flush type, + * output to stdout only once write buffer is full */ + do { + read = (int32_t)fread(read_buf, 1, read_buf_size, fin); + if (read <= 0) + break; + + d_stream.next_in = (z_const uint8_t *)read_buf; + d_stream.avail_in = read; + + do { + err = PREFIX(inflate)(&d_stream, flush); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + } while (d_stream.next_in < read_buf + read); + } while (err == Z_OK); + + /* Finish the stream if necessary */ + if (flush != Z_FINISH) { + d_stream.avail_in = 0; + do { + if (d_stream.next_out == write_buf + write_buf_size) { + fwrite(write_buf, 1, write_buf_size, fout); + d_stream.next_out = write_buf; + d_stream.avail_out = write_buf_size; + } + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + CHECK_ERR(err, "inflate"); + } while (1); + } + + /* Output remaining data in write buffer */ + if (d_stream.next_out != write_buf) { + fwrite(write_buf, 1, d_stream.next_out - write_buf, fout); + } + + err = PREFIX(inflateEnd)(&d_stream); + CHECK_ERR(err, "inflateEnd"); + + free(read_buf); + free(write_buf); +} + +void show_help(void) { + printf("Usage: minideflate [-c][-d][-k] [-f|-h|-R|-F] [-m level] [-r/-t size] [-s flush] [-w bits] [-0 to -9] [input file]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input file\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -m : memory level (1 to 8)\n" \ + " -w : window bits..\n" \ + " : -1 to -15 for raw deflate\n" + " : 0 to 15 for deflate (adler32)\n" + " : 16 to 31 for gzip (crc32)\n" + " -s : flush type (0 to 5)\n" \ + " -r : read buffer size\n" \ + " -t : write buffer size\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char **argv) { + int32_t i; + int32_t mem_level = DEF_MEM_LEVEL; + int32_t window_bits = INT32_MAX; + int32_t strategy = Z_DEFAULT_STRATEGY; + int32_t level = Z_DEFAULT_COMPRESSION; + int32_t read_buf_size = BUFSIZE; + int32_t write_buf_size = BUFSIZE; + int32_t flush = Z_NO_FLUSH; + uint8_t copyout = 0; + uint8_t uncompr = 0; + uint8_t keep = 0; + FILE *fin = stdin; + FILE *fout = stdout; + + + if (argc == 1) { + show_help(); + return 64; /* EX_USAGE */ + } + + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-m") == 0) && (i + 1 < argc)) + mem_level = atoi(argv[++i]); + else if ((strcmp(argv[i], "-w") == 0) && (i + 1 < argc)) + window_bits = atoi(argv[++i]); + else if ((strcmp(argv[i], "-r") == 0) && (i + 1 < argc)) + read_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-t") == 0) && (i + 1 < argc)) + write_buf_size = atoi(argv[++i]); + else if ((strcmp(argv[i], "-s") == 0) && (i + 1 < argc)) + flush = atoi(argv[++i]); + else if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-f") == 0) + strategy = Z_FILTERED; + else if (strcmp(argv[i], "-F") == 0) + strategy = Z_FIXED; + else if (strcmp(argv[i], "-h") == 0) + strategy = Z_HUFFMAN_ONLY; + else if (strcmp(argv[i], "-R") == 0) + strategy = Z_RLE; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i][1] - '0'; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else + break; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + if (i != argc) { + fin = fopen(argv[i], "rb+"); + if (fin == NULL) { + fprintf(stderr, "Failed to open file: %s\n", argv[i]); + exit(1); + } + if (!copyout) { + char *out_file = (char *)calloc(1, strlen(argv[i]) + 6); + if (out_file == NULL) { + fprintf(stderr, "Not enough memory\n"); + exit(1); + } + strcat(out_file, argv[i]); + if (!uncompr) { + if (window_bits < 0) { + strcat(out_file, ".zraw"); + } else if (window_bits > MAX_WBITS) { + strcat(out_file, ".gz"); + } else { + strcat(out_file, ".z"); + } + } else { + char *out_ext = strrchr(out_file, '.'); + if (out_ext != NULL) { + if (strcasecmp(out_ext, ".zraw") == 0 && window_bits == INT32_MAX) { + fprintf(stderr, "Must specify window bits for raw deflate stream\n"); + exit(1); + } + *out_ext = 0; + } + } + fout = fopen(out_file, "wb"); + if (fout == NULL) { + fprintf(stderr, "Failed to open file: %s\n", out_file); + exit(1); + } + free(out_file); + } + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (window_bits == INT32_MAX) { + window_bits = MAX_WBITS; + /* Auto-detect wrapper for inflateInit */ + if (uncompr) + window_bits += 32; + } + + if (uncompr) { + inflate_params(fin, fout, read_buf_size, write_buf_size, window_bits, flush); + } else { + deflate_params(fin, fout, read_buf_size, write_buf_size, level, window_bits, mem_level, strategy, flush); + } + + if (fin != stdin) { + fclose(fin); + if (!copyout && !keep) { + unlink(argv[i]); + } + } + if (fout != stdout) { + fclose(fout); + } + + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/minigzip.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/minigzip.c new file mode 100644 index 000000000..d55f5086b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/minigzip.c @@ -0,0 +1,378 @@ +/* minigzip.c -- simulate gzip using the zlib compression library + * Copyright (C) 1995-2006, 2010, 2011, 2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * minigzip is a minimal implementation of the gzip utility. This is + * only an example of using zlib and isn't meant to replace the + * full-featured gzip. No attempt is made to deal with file systems + * limiting names to 14 or 8+3 characters, etc... Error checking is + * very limited. So use minigzip only for testing; use gzip for the + * real thing. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif +#include + +#include +#include + +#ifdef USE_MMAP +# include +# include +# include +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1900 +# define snprintf _snprintf +#endif + +#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE) +#ifndef _WIN32 /* unlink already in stdio.h for Win32 */ +extern int unlink (const char *); +#endif +#endif + +#ifndef GZ_SUFFIX +# define GZ_SUFFIX ".gz" +#endif +#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1) + +#ifndef BUFLEN +# define BUFLEN 16384 /* read buffer size */ +#endif +#define BUFLENW (BUFLEN * 3) /* write buffer size */ +#define MAX_NAME_LEN 1024 + +static char *prog; + +void error (const char *msg); +void gz_fatal (gzFile file); +void gz_compress (FILE *in, gzFile out); +#ifdef USE_MMAP +int gz_compress_mmap (FILE *in, gzFile out); +#endif +void gz_uncompress (gzFile in, FILE *out); +void file_compress (char *file, char *mode, int keep); +void file_uncompress (char *file, int keep); +int main (int argc, char *argv[]); + +/* =========================================================================== + * Display error message and exit + */ +void error(const char *msg) { + fprintf(stderr, "%s: %s\n", prog, msg); + exit(1); +} + +/* =========================================================================== + * Display last error message of gzFile, close it and exit + */ + +void gz_fatal(gzFile file) { + int err; + fprintf(stderr, "%s: %s\n", prog, PREFIX(gzerror)(file, &err)); + PREFIX(gzclose)(file); + exit(1); +} + +/* =========================================================================== + * Compress input to output then close both files. + */ + +void gz_compress(FILE *in, gzFile out) { + char *buf; + int len; + +#ifdef USE_MMAP + /* Try first compressing with mmap. If mmap fails (minigzip used in a + * pipe), use the normal fread loop. + */ + if (gz_compress_mmap(in, out) == Z_OK) return; +#endif + buf = (char *)calloc(BUFLEN, 1); + if (buf == NULL) { + perror("out of memory"); + exit(1); + } + + for (;;) { + len = (int)fread(buf, 1, BUFLEN, in); + if (ferror(in)) { + free(buf); + perror("fread"); + exit(1); + } + if (len == 0) break; + + if (PREFIX(gzwrite)(out, buf, (unsigned)len) != len) gz_fatal(out); + } + free(buf); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); +} + +#ifdef USE_MMAP /* MMAP version, Miguel Albrecht */ + +/* Try compressing the input file at once using mmap. Return Z_OK if + * if success, Z_ERRNO otherwise. + */ +int gz_compress_mmap(FILE *in, gzFile out) { + int len; + int ifd = fileno(in); + char *buf; /* mmap'ed buffer for the entire input file */ + off_t buf_len; /* length of the input file */ + struct stat sb; + + /* Determine the size of the file, needed for mmap: */ + if (fstat(ifd, &sb) < 0) return Z_ERRNO; + buf_len = sb.st_size; + if (buf_len <= 0) return Z_ERRNO; + + /* Now do the actual mmap: */ + buf = mmap((void *)0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); + if (buf == (char *)(-1)) return Z_ERRNO; + + /* Compress the whole file at once: */ + len = PREFIX(gzwrite)(out, buf, (unsigned)buf_len); + + if (len != (int)buf_len) gz_fatal(out); + + munmap(buf, buf_len); + fclose(in); + if (PREFIX(gzclose)(out) != Z_OK) error("failed gzclose"); + return Z_OK; +} +#endif /* USE_MMAP */ + +/* =========================================================================== + * Uncompress input to output then close both files. + */ +void gz_uncompress(gzFile in, FILE *out) { + char *buf = (char *)malloc(BUFLENW); + int len; + + if (buf == NULL) error("out of memory"); + + for (;;) { + len = PREFIX(gzread)(in, buf, BUFLENW); + if (len < 0) { + free(buf); + gz_fatal(in); + } + if (len == 0) break; + + if ((int)fwrite(buf, 1, (unsigned)len, out) != len) { + free(buf); + error("failed fwrite"); + } + } + free(buf); + if (fclose(out)) error("failed fclose"); + + if (PREFIX(gzclose)(in) != Z_OK) error("failed gzclose"); +} + + +/* =========================================================================== + * Compress the given file: create a corresponding .gz file and remove the + * original. + */ +void file_compress(char *file, char *mode, int keep) { + char outfile[MAX_NAME_LEN]; + FILE *in; + gzFile out; + + if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX); + + in = fopen(file, "rb"); + if (in == NULL) { + perror(file); + exit(1); + } + out = PREFIX(gzopen)(outfile, mode); + if (out == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile); + exit(1); + } + gz_compress(in, out); + + if (!keep) + unlink(file); +} + + +/* =========================================================================== + * Uncompress the given file and remove the original. + */ +void file_uncompress(char *file, int keep) { + char buf[MAX_NAME_LEN]; + char *infile, *outfile; + FILE *out; + gzFile in; + size_t len = strlen(file); + + if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) { + fprintf(stderr, "%s: filename too long\n", prog); + exit(1); + } + + snprintf(buf, sizeof(buf), "%s", file); + + if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) { + infile = file; + outfile = buf; + outfile[len-3] = '\0'; + } else { + outfile = file; + infile = buf; + snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX); + } + in = PREFIX(gzopen)(infile, "rb"); + if (in == NULL) { + fprintf(stderr, "%s: can't gzopen %s\n", prog, infile); + exit(1); + } + out = fopen(outfile, "wb"); + if (out == NULL) { + perror(file); + exit(1); + } + + gz_uncompress(in, out); + + if (!keep) + unlink(infile); +} + +void show_help(void) { + printf("Usage: minigzip [-c] [-d] [-k] [-f|-h|-R|-F|-T] [-A] [-0 to -9] [files...]\n\n" \ + " -c : write to standard output\n" \ + " -d : decompress\n" \ + " -k : keep input files\n" \ + " -f : compress with Z_FILTERED\n" \ + " -h : compress with Z_HUFFMAN_ONLY\n" \ + " -R : compress with Z_RLE\n" \ + " -F : compress with Z_FIXED\n" \ + " -T : stored raw\n" \ + " -A : auto detect type\n" \ + " -0 to -9 : compression level\n\n"); +} + +int main(int argc, char *argv[]) { + int copyout = 0; + int uncompr = 0; + int keep = 0; + int i = 0; + gzFile file; + char *bname, outmode[20]; + char *strategy = ""; + char *level = "6"; + char *type = "b"; + + prog = argv[i]; + bname = strrchr(argv[i], '/'); + if (bname) + bname++; + else + bname = argv[i]; + + if (!strcmp(bname, "gunzip")) + uncompr = 1; + else if (!strcmp(bname, "zcat")) + copyout = uncompr = 1; + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-c") == 0) + copyout = 1; + else if (strcmp(argv[i], "-d") == 0) + uncompr = 1; + else if (strcmp(argv[i], "-k") == 0) + keep = 1; + else if (strcmp(argv[i], "-A") == 0) + type = ""; + else if (argv[i][0] == '-' && (argv[i][1] == 'f' || argv[i][1] == 'h' || + argv[i][1] == 'R' || argv[i][1] == 'F' || argv[i][1] == 'T') && argv[i][2] == 0) + strategy = argv[i] + 1; + else if (argv[i][0] == '-' && argv[i][1] >= '0' && argv[i][1] <= '9' && argv[i][2] == 0) + level = argv[i] + 1; + else if (strcmp(argv[i], "--help") == 0) { + show_help(); + return 0; + } else if (argv[i][0] == '-') { + show_help(); + return 64; /* EX_USAGE */ + } else { + break; + } + } + + snprintf(outmode, sizeof(outmode), "w%s%s%s", type, strategy, level); + + if (i == argc) { + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + if (uncompr) { + file = PREFIX(gzdopen)(fileno(stdin), "rb"); + if (file == NULL) error("can't gzdopen stdin"); + gz_uncompress(file, stdout); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + gz_compress(stdin, file); + } + } else { + if (copyout) { + SET_BINARY_MODE(stdout); + } + do { + if (uncompr) { + if (copyout) { + file = PREFIX(gzopen)(argv[i], "rb"); + if (file == NULL) + fprintf(stderr, "%s: can't gzopen %s\n", prog, argv[i]); + else + gz_uncompress(file, stdout); + } else { + file_uncompress(argv[i], keep); + } + } else { + if (copyout) { + FILE * in = fopen(argv[i], "rb"); + + if (in == NULL) { + perror(argv[i]); + } else { + file = PREFIX(gzdopen)(fileno(stdout), outmode); + if (file == NULL) error("can't gzdopen stdout"); + + gz_compress(in, file); + } + + } else { + file_compress(argv[i], outmode, keep); + } + } + } while (++i < argc); + } + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/pigz/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.0-beta1/test/pigz/CMakeLists.txt new file mode 100644 index 000000000..bc6830ae2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/pigz/CMakeLists.txt @@ -0,0 +1,211 @@ +# CMakeLists.txt -- Build madler/pigz against zlib variant + +# Copyright (C) 2021 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# By default pigz will be linked against the system zlib and +# pthread libraries if installed. + +# For compilation on Windows download and use shim: +# https://github.com/zlib-ng/pigzbench/tree/master/pigz/win + +# Optional Variables +# WITH_CODE_COVERAGE - Enable code coverage reporting +# WITH_THREADS - Enable threading support +# PIGZ_ENABLE_TESTS - Enable adding unit tests +# PIGZ_VERSION - Set the version of pigz to build +# ZLIB_ROOT - Path to the zlib source directory +# PTHREADS4W_ROOT - Path to pthreads4w source directory on Windows. +# If not specified then threading will be disabled. + +cmake_minimum_required(VERSION 3.11) + +include(CheckCCompilerFlag) +include(FeatureSummary) +include(FetchContent) + +include(../../cmake/detect-coverage.cmake) + +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_THREADS "Enable threading support" ON) +option(PIGZ_ENABLE_TESTS "Build unit tests" ON) +option(PIGZ_VERSION "Set the version of pigz to build" "") + +project(pigz LANGUAGES C) + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Compiler definitions +if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + add_definitions(-fno-caret-diagnostics) +elseif(CMAKE_C_COMPILER_ID STREQUAL "GNU") + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.5.0) + add_definitions(-Wno-unused-result) + endif() + if(NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.8.0) + add_definitions(-fno-diagnostics-show-caret) + endif() +elseif(WIN32) + add_definitions(-D_TIMESPEC_DEFINED) + if(MSVC) + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + endif() +endif() + +# Fetch pigz source code from official repository +if(PIGZ_VERSION STREQUAL "") + set(PIGZ_TAG master) +else() + set(PIGZ_TAG ${PIGZ_VERSION}) +endif() +FetchContent_Declare(pigz + GIT_REPOSITORY https://github.com/madler/pigz.git + GIT_TAG ${PIGZ_TAG}) + +FetchContent_GetProperties(pigz) +if(NOT pigz_POPULATED) + FetchContent_Populate(pigz) +endif() + +set(PIGZ_SRCS + ${pigz_SOURCE_DIR}/pigz.c + ${pigz_SOURCE_DIR}/try.c) + +set(PIGZ_HDRS + ${pigz_SOURCE_DIR}/try.h) + +add_executable(${PROJECT_NAME} ${PIGZ_SRCS} ${PIGZ_HDRS}) +add_definitions(-DNOZOPFLI) +if(WIN32) + target_include_directories(${PROJECT_NAME} PRIVATE win) +endif() + +# Find and link against pthreads or pthreads4w +if(WITH_THREADS) + if(WIN32) + if(DEFINED PTHREADS4W_ROOT) + set(CLEANUP_STYLE VC) + set(PTHREADS4W_VERSION 3) + + add_subdirectory(${PTHREADS4W_ROOT} ${PTHREADS4W_ROOT} EXCLUDE_FROM_ALL) + target_link_libraries(${PROJECT_NAME} pthreadVC3) + target_include_directories(${PROJECT_NAME} PRIVATE ${PTHREADS4W_ROOT}) + else() + message(WARNING "Missing pthreads4w root directory") + set(WITH_THREADS OFF) + endif() + else() + find_package(Threads REQUIRED) + target_link_libraries(${PROJECT_NAME} Threads::Threads) + if(NOT APPLE) + target_link_libraries(${PROJECT_NAME} m) + endif() + endif() +endif() + +# Disable threading support +if(NOT WITH_THREADS) + add_definitions(-DNOTHREAD) +else() + set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY SOURCES + ${pigz_SOURCE_DIR}/yarn.c + ${pigz_SOURCE_DIR}/yarn.h) +endif() + +# Find and link against zlib +if(NOT DEFINED ZLIB_ROOT) + find_package(Zlib REQUIRED) +endif() + +set(ZLIB_COMPAT ON) +set(ZLIB_ENABLE_TESTS OFF) + +add_subdirectory(${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib EXCLUDE_FROM_ALL) + +if(NOT DEFINED BUILD_SHARED_LIBS OR NOT BUILD_SHARED_LIBS) + set(ZLIB_TARGET zlibstatic) +else() + set(ZLIB_TARGET zlib) +endif() + +target_include_directories(${PROJECT_NAME} PRIVATE ${ZLIB_ROOT} ${CMAKE_CURRENT_BINARY_DIR}/zlib) +target_link_libraries(${PROJECT_NAME} ${ZLIB_TARGET}) + +if(NOT SKIP_INSTALL_BINARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${PROJECT_NAME} DESTINATION "bin") +endif() + +# Add unit tests +if(PIGZ_ENABLE_TESTS) + enable_testing() + + set(PIGZ_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $) + + macro(test_pigz name path) + # Construct compression arguments for pigz + set(compress_args -k -c) + foreach(extra_arg IN ITEMS "${ARGN}") + list(APPEND compress_args ${extra_arg}) + endforeach() + + # Create unique friendly string for test + string(REPLACE ";" "" arg_list "${ARGN}") + string(REPLACE " " "" arg_list "${arg_list}") + string(REPLACE "-" "" arg_list "${arg_list}") + + set(test_id pigz-${name}-${arg_list}) + + if(NOT TEST ${test_id}) + add_test(NAME ${test_id} + COMMAND ${CMAKE_COMMAND} + "-DTARGET=${PIGZ_COMMAND}" + "-DCOMPRESS_ARGS=${compress_args}" + "-DDECOMPRESS_ARGS=-d;-c" + -DINPUT=${CMAKE_CURRENT_SOURCE_DIR}/${path} + -DTEST_NAME=${test_id} + -P ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/compress-and-verify.cmake) + endif() + endmacro() + + set(TEST_CONFIGS + -U # RLE compression + #-H # Z_HUFFMAN_ONLY (broken in 2.6) + -0 # No compression + -1 # Deflate quick + -4 # Deflate medium (lazy matches) + -6 # Deflate medium + -9 # Deflate slow + ) + + file(GLOB_RECURSE TEST_FILE_PATHS + LIST_DIRECTORIES false + RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../data/*) + + foreach(TEST_FILE_PATH ${TEST_FILE_PATHS}) + if("${TEST_FILE_PATH}" MATCHES ".gz$" OR "${TEST_FILE_PATH}" MATCHES ".out$" OR + "${TEST_FILE_PATH}" MATCHES "/.git/" OR "${TEST_FILE_PATH}" MATCHES ".md$") + continue() + endif() + foreach(TEST_CONFIG ${TEST_CONFIGS}) + get_filename_component(TEST_NAME ${TEST_FILE_PATH} NAME) + if (TEST_NAME STREQUAL "") + continue() + endif() + test_pigz(${TEST_NAME} ${TEST_FILE_PATH} ${TEST_CONFIG}) + endforeach() + endforeach() + + set(GH979_COMMAND ${CMAKE_CROSSCOMPILING_EMULATOR} $ + -d -k -f ${CMAKE_CURRENT_SOURCE_DIR}/../GH-979/pigz-2.6.tar.gz) + add_test(NAME GH-979 COMMAND ${GH979_COMMAND}) +endif() + +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_THREADS WITH_THREADS "Enable threading support") +add_feature_info(PIGZ_ENABLE_TESTS PIGZ_ENABLE_TESTS "Build unit tests") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/pkgcheck.sh b/internal-complibs/zlib-ng-2.1.0-beta1/test/pkgcheck.sh new file mode 100644 index 000000000..87a4e61ef --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/pkgcheck.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +usage() { + cat <<"_EOF_" +Usage: sh test/pkgcheck.sh [--zlib-compat] + +Verifies that the various build systems produce identical results on a Unixlike system. +If --zlib-compat, tests with zlib compatible builds. + +To build the 32 bit version for the current 64 bit arch: + +$ sudo apt install ninja-build diffoscope gcc-multilib +$ export CMAKE_ARGS="-DCMAKE_C_FLAGS=-m32" CFLAGS=-m32 LDFLAGS=-m32 +$ sh test/pkgcheck.sh + +To cross-build, install the appropriate qemu and gcc packages, +and set the environment variables used by configure or cmake. +On Ubuntu, for example (values taken from .github/workflows/pkgconf.yml): + +arm HF: +$ sudo apt install ninja-build diffoscope qemu gcc-arm-linux-gnueabihf libc6-dev-armhf-cross +$ export CHOST=arm-linux-gnueabihf +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +aarch64: +$ sudo apt install ninja-build diffoscope qemu gcc-aarch64-linux-gnu libc6-dev-arm64-cross +$ export CHOST=aarch64-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DCMAKE_C_COMPILER_TARGET=${CHOST}" + +ppc (32 bit big endian): +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc-linux-gnu libc6-dev-powerpc-cross +$ export CHOST=powerpc-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake" + +ppc64le: +$ sudo apt install ninja-build diffoscope qemu gcc-powerpc64le-linux-gnu libc6-dev-ppc64el-cross +$ export CHOST=powerpc64le-linux-gnu +$ export CMAKE_ARGS="-DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake" + +then: +$ export CC=${CHOST}-gcc +$ sh test/pkgcheck.sh [--zlib-compat] + +Note: on Mac, you may also need to do 'sudo xcode-select -r' to get cmake to match configure/make's behavior (i.e. omit -isysroot). +_EOF_ +} + +set -ex + +# Caller can also set CMAKE_ARGS or CONFIGURE_ARGS if desired +CMAKE_ARGS="-DCMAKE_INSTALL_LIBDIR=lib ${CMAKE_ARGS}" +CONFIGURE_ARGS=${CONFIGURE_ARGS} + +case "$1" in +--zlib-compat) + suffix="" + CMAKE_ARGS="$CMAKE_ARGS -DZLIB_COMPAT=ON" + CONFIGURE_ARGS="$CONFIGURE_ARGS --zlib-compat" + ;; +"") + suffix="-ng" + ;; +*) + echo "Unknown arg '$1'" + usage + exit 1 + ;; +esac + +if ! test -f "configure" +then + echo "Please run from top of source tree" + exit 1 +fi + +# Tell GNU's ld etc. to use Jan 1 1970 when embedding timestamps +# Probably only needed on older systems (ubuntu 14.04, BSD?) +export SOURCE_DATE_EPOCH=0 +case $(uname) in +Darwin) + # Tell Apple's ar etc. to use zero timestamps + export ZERO_AR_DATE=1 + # What CPU are we running on, exactly? + sysctl -n machdep.cpu.brand_string + sysctl -n machdep.cpu.features + sysctl -n machdep.cpu.leaf7_features + sysctl -n machdep.cpu.extfeatures + ;; +esac + +# Use same compiler for make and cmake builds +if test "$CC"x = ""x +then + if clang --version + then + export CC=clang + elif gcc --version + then + export CC=gcc + fi +fi + +# New build system +# Happens to delete top-level zconf.h +# (which itself is a bug, https://github.com/madler/zlib/issues/162 ) +# which triggers another bug later in configure, +# https://github.com/madler/zlib/issues/499 +rm -rf btmp2 pkgtmp2 +mkdir btmp2 pkgtmp2 +export DESTDIR=$(pwd)/pkgtmp2 +cd btmp2 + cmake -G Ninja ${CMAKE_ARGS} .. + ninja -v + ninja install +cd .. + +# Original build system +rm -rf btmp1 pkgtmp1 +mkdir btmp1 pkgtmp1 +export DESTDIR=$(pwd)/pkgtmp1 +cd btmp1 + case $(uname) in + Darwin) + export LDFLAGS="-Wl,-headerpad_max_install_names" + ;; + esac + ../configure $CONFIGURE_ARGS + make -j2 + make install +cd .. + +repack_ar() { + if ! cmp --silent pkgtmp1/usr/local/lib/libz$suffix.a pkgtmp2/usr/local/lib/libz$suffix.a + then + echo "libz$suffix.a does not match. Probably filenames differ (.o vs .c.o). Unpacking and renaming..." + # Note: %% is posix shell syntax meaning "Remove Largest Suffix Pattern", see + # https://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02 + cd pkgtmp1; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; cd .. + cd pkgtmp2; ar x usr/local/lib/libz$suffix.a; rm usr/local/lib/libz$suffix.a; for a in *.c.o; do mv $a ${a%%.c.o}.o; done; cd .. + # Also, remove __.SYMDEF SORTED if present, as it has those funky .c.o names embedded in it. + rm -f pkgtmp[12]/__.SYMDEF\ SORTED + fi +} + +case $(uname) in +Darwin) + # Remove the build uuid. + dylib1=$(find pkgtmp1 -type f -name '*.dylib*') + dylib2=$(find pkgtmp2 -type f -name '*.dylib*') + strip -x -no_uuid "$dylib1" + strip -x -no_uuid "$dylib2" + ;; +esac + +# The ar on newer systems defaults to -D (i.e. deterministic), +# but FreeBSD 12.1, Debian 8, and Ubuntu 14.04 seem to not do that. +# I had trouble passing -D safely to the ar inside CMakeLists.txt, +# so punt and unpack the archive if needed before comparing. +# Also, cmake uses different .o suffix anyway... +repack_ar + +if diff -Nur pkgtmp1 pkgtmp2 +then + echo pkgcheck-cmake-bits-identical PASS +else + echo pkgcheck-cmake-bits-identical FAIL + dylib1=$(find pkgtmp1 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + dylib2=$(find pkgtmp2 -type f -name '*.dylib*' -print -o -type f -name '*.so.*' -print) + diffoscope $dylib1 $dylib2 | cat + exit 1 +fi + +rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +# any failure would have caused an early exit already +echo "pkgcheck: PASS" diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/switchlevels.c b/internal-complibs/zlib-ng-2.1.0-beta1/test/switchlevels.c new file mode 100644 index 000000000..a065dbcff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/switchlevels.c @@ -0,0 +1,167 @@ +/* Compresses a user-specified number of chunks from stdin into stdout as a single gzip stream. + * Each chunk is compressed with a user-specified level. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if defined(_WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif + +static int read_all(unsigned char *buf, size_t size) { + size_t total_read = 0; + while (total_read < size) { + size_t n_read = fread(buf + total_read, 1, size - total_read, stdin); + if (ferror(stdin)) { + perror("fread\n"); + return 1; + } + if (n_read == 0) { + fprintf(stderr, "Premature EOF\n"); + return 1; + } + total_read += n_read; + } + return 0; +} + +static int write_all(unsigned char *buf, size_t size) { + size_t total_written = 0; + while (total_written < size) { + size_t n_written = fwrite(buf + total_written, 1, size - total_written, stdout); + if (ferror(stdout)) { + perror("fwrite\n"); + return 1; + } + total_written += n_written; + } + return 0; +} + +static int compress_chunk(PREFIX3(stream) *strm, int level, int size, int last) { + int ret = 1; + int err = 0; + unsigned long compsize; + unsigned char *buf; + + if (size <= 0) { + fprintf(stderr, "compress_chunk() invalid size %d\n", size); + goto done; + } + if (level < 0 || level > 9) { + fprintf(stderr, "compress_chunk() invalid level %d\n", level); + goto done; + } + + compsize = PREFIX(deflateBound)(strm, size); + buf = malloc(size + compsize); + if (buf == NULL) { + fprintf(stderr, "Out of memory\n"); + goto done; + } + if (read_all(buf, size) != 0) { + goto free_buf; + } + + /* Provide only output buffer to deflateParams(). It might need some space to flush the leftovers from the last + * deflate(), but we don't want it to compress anything new. */ + strm->next_in = NULL; + strm->avail_in = 0; + strm->next_out = buf + size; + strm->avail_out = compsize; + err = PREFIX(deflateParams)(strm, level, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateParams() failed with code %d\n", err); + goto free_buf; + } + + /* Provide input buffer to deflate(). */ + strm->next_in = buf; + strm->avail_in = size; + err = PREFIX(deflate)(strm, last ? Z_FINISH : Z_SYNC_FLUSH); + if ((!last && err != Z_OK) || (last && err != Z_STREAM_END)) { + fprintf(stderr, "deflate() failed with code %d\n", err); + goto free_buf; + } + if (strm->avail_in != 0) { + fprintf(stderr, "deflate() did not consume %d bytes of input\n", strm->avail_in); + goto free_buf; + } + if (write_all(buf + size, compsize - strm->avail_out) != 0) { + goto free_buf; + } + ret = 0; + +free_buf: + free(buf); +done: + return ret; +} + +void show_help(void) +{ + printf("Usage: switchlevels [-w bits] level1 size1 [level2 size2 ...]\n\n" \ + " -w : window bits (8 to 15 for gzip, -8 to -15 for zlib)\n\n"); +} + +int main(int argc, char **argv) { + int ret = EXIT_FAILURE; + int err = 0; + int size = 0; + int level = Z_DEFAULT_COMPRESSION; + int level_arg = 1; + int window_bits = MAX_WBITS + 16; + PREFIX3(stream) strm; + + + if ((argc == 1) || (argc == 2 && strcmp(argv[1], "--help") == 0)) { + show_help(); + return 0; + } + + SET_BINARY_MODE(stdin); + SET_BINARY_MODE(stdout); + + memset(&strm, 0, sizeof(strm)); + + for (int i = 1; i < argc - 1; i++) { + if (strcmp(argv[i], "-w") == 0 && i+1 < argc) { + window_bits = atoi(argv[++i]); + } else { + level_arg = i; + level = atoi(argv[i]); + break; + } + } + + err = PREFIX(deflateInit2)(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); + if (err != Z_OK) { + fprintf(stderr, "deflateInit() failed with code %d\n", err); + goto done; + } + + for (int i = level_arg; i < argc - 1; i += 2) { + level = atoi(argv[i]); + size = atoi(argv[i + 1]); + if (compress_chunk(&strm, level, size, i + 2 >= argc - 1) != 0) { + goto deflate_end; + } + } + ret = EXIT_SUCCESS; + +deflate_end: + PREFIX(deflateEnd)(&strm); +done: + return ret; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_adler32.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_adler32.cc new file mode 100644 index 000000000..4dfe63f20 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_adler32.cc @@ -0,0 +1,386 @@ +/* test_adler32.c -- unit test for adler32 in the zlib compression library + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + uint32_t adler; + const uint8_t *buf; + uint32_t len; + uint32_t expect; +} adler32_test; + +static const uint8_t long_string[5552] = { + 'q','j','d','w','q','4','8','m','B','u','k','J','V','U','z','V','V','f','M','j','i','q','S','W','L','5','G','n','F','S','P','Q', + 'Q','D','i','6','m','E','9','Z','a','A','P','h','9','d','r','b','5','t','X','U','U','L','w','q','e','k','E','H','6','W','7','k', + 'A','x','N','Q','R','k','d','V','5','y','n','U','N','W','Q','Y','i','W','5','9','R','p','D','C','x','p','u','h','C','a','m','r', + 'z','n','z','A','d','J','6','u','N','e','r','x','7','Q','3','v','V','h','H','S','H','S','f','K','f','e','E','T','9','J','f','K', + 'w','t','x','J','2','y','7','B','x','X','X','p','G','b','T','g','3','k','U','6','E','Z','M','t','J','q','v','n','S','T','6','x', + '5','x','4','P','z','p','M','F','V','b','d','m','f','G','n','J','m','w','z','K','8','a','q','E','D','e','b','3','h','B','V','g', + 'y','3','P','L','5','8','r','z','X','b','Q','g','H','7','L','c','Z','B','3','C','4','y','t','u','k','z','h','v','C','Y','p','p', + '8','H','v','5','X','w','4','L','R','V','V','4','U','C','8','4','T','E','a','N','Z','S','7','U','u','z','f','H','p','P','J','u', + 'Y','Z','h','T','6','e','v','z','V','F','h','u','y','H','b','k','J','M','f','3','6','g','y','L','E','W','t','B','B','d','d','9', + 'u','M','Z','k','F','G','f','h','q','k','5','k','f','r','M','7','c','M','7','y','n','u','8','b','d','7','Q','f','E','m','F','K', + 'x','W','f','B','2','F','8','5','q','z','y','3','R','i','U','m','X','k','h','N','J','y','B','C','h','u','x','4','f','k','J','5', + '6','X','T','W','h','8','J','4','m','K','p','N','3','g','C','g','A','E','e','Z','x','A','P','2','E','4','t','Q','5','X','Y','j', + '6','m','b','h','G','a','v','6','t','v','6','C','M','G','P','u','B','C','A','V','b','2','9','d','2','c','5','a','b','X','w','V', + 'G','6','a','7','c','8','G','6','K','U','Q','m','w','P','V','5','N','x','b','v','x','E','N','C','A','N','t','v','N','B','z','X', + 'B','R','q','U','n','i','A','Q','d','m','a','D','7','Y','f','3','J','8','Y','m','w','Z','b','w','r','H','q','E','j','c','u','E', + 'i','i','S','b','n','G','P','a','F','j','c','R','D','D','G','F','v','i','a','i','M','7','B','e','w','m','L','E','F','2','Y','4', + '4','7','Y','C','t','y','q','7','2','V','G','m','m','E','e','V','u','m','L','p','R','X','W','z','V','K','E','k','p','V','r','J', + 'd','N','3','t','i','u','S','V','w','2','w','U','Q','3','F','q','4','h','q','k','B','7','R','X','B','F','Q','Z','b','b','4','E', + 'K','v','T','B','w','k','V','C','x','d','K','g','N','S','u','k','p','9','z','w','c','y','U','M','V','E','2','Y','P','F','h','9', + 'T','y','h','w','b','9','P','w','G','c','W','W','k','j','J','Q','N','B','U','G','6','9','U','b','v','a','N','9','N','C','G','n', + 'x','R','6','9','Q','C','h','e','j','P','U','h','U','R','i','4','T','B','W','5','w','m','J','p','e','7','r','9','t','c','9','Z', + 'j','p','r','F','C','e','U','P','x','T','A','N','7','6','a','i','y','e','w','F','C','X','H','Y','G','C','q','q','m','A','t','7', + 'z','u','D','S','L','U','C','f','7','e','t','G','V','F','u','c','x','5','M','7','N','i','M','6','h','2','n','H','S','h','K','M', + 'd','T','z','X','d','x','x','4','q','z','d','D','a','2','X','r','p','r','R','m','U','U','y','S','H','c','a','F','e','Z','a','U', + 'P','9','V','J','e','q','j','Y','M','x','e','v','K','7','M','P','N','2','b','6','f','P','h','H','4','U','X','k','n','f','Q','M', + '9','9','a','J','N','e','w','y','f','F','P','p','a','F','Y','a','M','L','W','i','T','M','B','3','U','v','X','v','G','p','7','a', + 'f','u','4','S','y','X','9','g','g','b','B','G','c','i','M','U','n','m','a','7','q','f','9','n','Q','2','V','L','6','e','T','R', + '2','4','9','d','6','Q','B','Y','q','2','4','9','G','Q','E','b','Y','5','u','2','T','Q','G','L','5','n','4','Y','2','y','G','F', + 'j','c','8','M','G','L','e','3','a','N','v','A','A','W','t','R','S','2','i','D','R','8','j','d','Q','3','6','C','V','M','e','w', + 'j','U','Z','w','M','4','b','m','8','J','P','Q','L','P','R','c','r','b','V','C','3','N','8','K','4','d','W','D','N','U','A','A', + '2','J','p','b','D','d','p','j','N','C','k','A','j','B','a','c','u','v','L','X','U','B','4','U','X','W','e','C','b','C','u','d', + 'A','v','U','z','P','t','D','e','5','y','Y','c','x','K','4','7','j','e','e','D','M','5','K','B','Q','6','d','p','T','T','R','j', + 'M','E','E','M','r','N','6','8','7','q','x','F','S','x','E','U','4','d','B','6','5','W','C','e','m','J','e','5','j','w','V','J', + 'w','v','d','7','v','f','K','u','m','8','h','W','T','e','Q','j','M','8','R','Y','d','B','R','2','r','F','j','7','d','E','q','V', + 'k','e','j','P','9','3','X','R','p','R','b','A','v','7','4','A','M','2','k','r','E','7','X','3','7','k','5','c','B','7','W','5', + 'u','J','B','Q','R','2','V','7','h','Q','h','9','g','G','y','c','c','x','M','z','7','G','2','J','w','v','j','5','9','E','b','k', + 'z','W','T','C','b','4','K','R','X','T','k','V','S','G','2','j','d','6','y','E','4','P','H','K','w','a','m','F','Z','x','9','j', + 'i','2','d','X','u','a','4','a','M','z','8','p','p','z','g','t','H','5','Y','L','Q','c','R','F','m','E','n','G','X','d','f','7', + 'x','8','j','g','J','z','D','S','a','S','h','y','5','h','Y','N','p','w','Y','W','h','E','N','v','8','Q','D','W','Z','k','f','e', + 'r','Z','D','7','R','D','T','2','H','X','z','G','X','f','v','E','z','P','v','U','H','e','4','R','W','U','x','t','t','4','w','p', + 'r','z','K','9','f','g','h','P','r','f','v','k','h','c','e','5','8','a','L','F','J','M','G','R','a','N','q','S','g','W','e','7', + 'R','K','R','A','B','z','6','v','S','p','w','n','e','x','k','E','r','j','f','Y','x','8','9','z','e','T','6','E','G','v','9','f', + 'D','A','N','v','y','U','7','D','M','2','E','5','W','G','6','b','9','q','g','Y','F','f','k','q','Q','E','x','Y','C','R','G','6', + 'R','h','4','J','d','U','D','b','9','b','8','r','f','V','d','g','b','2','z','Z','d','m','X','v','j','Y','d','w','K','8','G','r', + 'v','j','N','y','c','h','u','5','z','g','J','H','a','Z','b','z','G','C','r','P','f','y','P','6','F','P','h','7','9','w','7','y', + 'R','3','n','E','h','G','D','4','m','Y','E','q','k','a','f','a','R','B','q','t','W','E','T','p','H','7','k','X','2','d','X','6', + 'W','n','H','m','w','M','i','Y','M','E','F','5','R','p','p','y','c','b','q','R','9','Y','t','T','7','w','u','K','M','Q','z','n', + 'P','7','g','x','6','R','4','x','N','v','w','M','6','j','K','v','7','a','Y','4','a','M','6','n','z','3','E','2','V','N','4','i', + 'E','f','u','W','J','W','e','8','3','Q','e','a','F','P','c','3','P','k','i','z','d','q','m','q','M','a','d','8','D','3','F','M', + 'e','d','E','j','z','V','e','d','z','H','D','J','8','X','g','E','i','u','c','7','A','w','S','J','2','A','e','8','r','q','C','m', + '9','9','a','g','2','y','y','P','M','e','8','3','T','r','m','8','j','v','r','p','M','Z','Y','g','a','9','2','d','H','B','m','9', + '4','6','a','Z','V','u','S','H','g','3','X','h','i','N','3','B','S','E','k','9','k','2','9','R','A','i','3','L','X','M','B','S', + '4','S','F','F','F','w','u','d','M','T','9','K','B','7','R','U','R','8','D','8','T','5','U','t','E','R','x','n','x','h','v','k', + 'B','N','k','E','U','T','t','p','r','u','Z','h','t','E','4','i','P','z','f','z','q','M','p','f','A','K','2','D','t','j','f','c', + 'Y','E','N','M','x','k','g','7','T','U','2','c','d','V','g','2','z','L','i','j','Y','q','b','T','A','y','v','a','t','N','5','t', + 'Z','5','n','D','a','y','G','n','P','x','V','k','M','8','t','J','Z','G','g','5','9','R','h','P','P','J','N','X','p','G','J','p', + '2','y','A','v','d','G','U','z','3','V','M','y','q','U','N','M','Y','p','B','Z','U','h','j','q','z','q','x','w','7','d','J','Q', + 'u','F','q','3','m','9','c','Q','W','d','6','7','b','V','M','7','P','j','r','k','9','h','R','z','m','b','i','B','u','E','L','9', + 'k','v','h','h','W','2','K','e','M','U','Q','p','A','Q','Y','J','G','E','T','U','L','f','q','G','4','z','K','K','y','a','U','W', + 'K','D','P','c','N','D','V','S','Y','6','T','p','R','y','y','J','a','T','J','W','Q','9','p','F','P','X','y','k','9','z','z','4', + 'G','d','a','z','X','n','h','4','J','P','W','V','D','r','U','m','a','8','a','b','X','F','J','X','L','4','S','X','5','W','p','W', + 'h','y','x','B','f','d','C','X','w','7','r','g','V','T','H','a','i','4','N','v','c','w','n','2','3','A','i','A','J','9','N','c', + 'z','7','n','n','3','n','h','n','i','R','i','b','E','h','k','U','c','c','U','6','f','x','q','N','y','H','M','e','J','B','U','B', + 'r','g','a','8','V','a','G','V','y','u','c','c','v','C','H','W','y','g','z','Q','2','4','k','S','m','f','e','G','H','v','Q','3', + 'P','e','f','S','V','P','c','U','e','3','P','x','d','c','7','c','f','g','D','w','2','t','q','y','g','2','Q','V','4','K','a','Q', + 'g','B','b','L','x','9','m','a','K','4','i','x','g','Q','M','9','W','N','2','w','p','v','2','k','B','y','9','k','A','c','f','Z', + 'D','R','A','S','d','v','w','f','f','q','t','K','3','j','x','D','G','P','n','u','r','v','U','k','A','2','d','R','N','T','G','4', + 'B','g','k','t','h','7','J','k','F','A','C','g','W','g','J','F','z','S','Q','c','v','M','b','D','e','H','Q','S','j','v','G','E', + 'R','k','f','i','P','E','F','N','6','y','p','b','t','M','c','Q','B','7','g','w','J','7','3','d','V','E','m','z','6','6','P','P', + 'd','i','r','J','H','D','H','J','r','b','n','v','z','W','e','u','g','B','u','Z','2','m','D','5','h','F','X','B','2','r','6','w', + 'u','Y','4','N','X','K','a','v','V','3','j','B','r','r','C','c','w','R','g','S','8','V','b','F','2','N','M','c','K','8','Y','E', + 'E','N','K','X','K','V','B','x','n','Q','p','a','q','f','k','t','z','Y','E','P','Z','y','n','a','c','B','V','a','x','b','d','X', + 'r','d','8','P','H','F','v','r','V','5','g','J','w','6','i','h','d','d','p','J','c','c','Y','S','q','W','m','U','5','G','b','H', + 'N','z','E','Z','K','E','y','M','c','G','i','d','w','Z','D','N','N','w','S','t','g','y','a','Y','b','H','e','M','N','f','Y','Y', + '7','a','9','b','M','U','k','a','V','k','C','n','a','k','U','H','A','M','i','v','k','t','a','d','i','3','F','d','5','2','A','p', + 'U','c','J','U','R','h','G','d','A','Y','v','q','X','c','w','r','x','4','j','3','4','b','F','d','a','L','N','J','3','Z','g','6', + 'W','Q','R','u','P','t','M','A','3','F','6','y','K','Y','G','2','t','v','u','p','w','b','G','S','K','5','p','4','d','E','w','6', + 'g','t','V','4','b','2','n','b','Z','3','3','f','m','d','2','c','a','m','j','X','U','E','D','6','6','F','w','H','9','7','Z','Y', + 'd','X','C','K','i','g','p','F','Y','n','2','b','F','4','R','u','V','k','f','d','J','i','a','b','X','H','7','v','K','a','Q','i', + 'W','M','j','M','i','a','i','n','F','h','r','q','4','w','x','m','4','q','y','F','8','w','i','4','D','B','A','L','B','U','u','K', + 'v','K','n','a','Q','i','e','k','v','Q','U','5','w','Q','c','r','A','6','M','w','y','g','n','e','v','K','7','W','u','2','y','f', + 'Q','u','e','r','y','a','w','V','p','f','Q','z','C','u','i','i','9','S','P','q','L','r','C','H','S','3','E','p','8','S','m','Q', + 'S','K','r','V','b','J','R','m','w','c','n','Q','N','Q','4','M','u','f','X','S','f','U','Z','x','U','4','j','K','4','G','z','X', + '7','Q','j','R','h','i','G','m','q','c','V','T','x','U','a','E','b','Q','q','E','i','F','K','7','K','i','R','J','5','Y','F','V', + 'B','7','R','8','M','i','f','j','Z','w','j','b','B','u','p','N','Y','r','S','r','f','h','E','J','T','B','P','R','D','V','K','A', + 'Z','A','R','j','z','f','B','i','Y','L','F','G','V','Y','w','R','C','P','G','m','9','7','C','5','e','y','w','N','K','N','a','Q', + 'j','a','W','3','2','f','G','w','n','M','6','F','u','K','8','g','8','M','G','r','e','9','Z','z','y','2','G','U','k','G','6','m', + 'A','D','4','n','b','8','a','q','S','m','S','6','5','R','5','D','5','S','B','g','X','T','8','Q','V','d','A','n','g','y','8','a', + 'h','7','K','9','H','D','J','F','w','G','4','w','T','J','F','f','i','8','X','e','B','J','K','H','7','V','y','X','7','E','8','S', + 'A','d','b','w','S','8','Y','a','J','d','j','E','V','J','T','E','U','R','5','7','V','M','E','v','D','3','z','5','r','k','z','v', + 'e','m','A','7','P','8','j','X','E','f','Q','q','8','D','g','y','8','j','A','e','B','c','c','M','z','k','2','c','q','v','v','y', + 'Q','y','h','g','p','v','M','m','m','C','G','D','k','8','u','T','n','Q','H','G','H','f','b','J','j','5','X','c','i','7','7','q', + 'b','R','8','b','b','z','f','f','h','Y','Q','7','u','B','X','e','i','j','M','q','C','T','M','v','t','J','J','w','b','F','v','J', + 'm','e','2','u','e','8','L','V','G','q','A','j','m','7','m','g','m','5','i','r','p','p','U','y','F','6','f','b','u','6','q','L', + 'M','E','t','V','W','C','t','e','p','w','a','n','w','y','X','h','8','e','G','C','H','q','r','X','G','9','c','h','7','k','8','M', + 'G','b','a','m','Y','Q','w','8','J','z','a','F','r','4','W','M','j','P','q','a','z','U','y','u','3','b','Z','f','Y','5','7','g', + 'N','M','h','M','a','3','C','K','6','6','f','a','p','i','f','q','k','T','i','z','w','f','Z','c','H','L','X','g','6','m','g','r', + 'w','Y','u','K','8','L','p','8','P','R','A','R','A','b','Z','V','a','x','V','c','G','A','H','t','Y','6','P','T','L','W','N','z', + 'g','z','k','d','E','v','C','t','Z','M','Z','K','4','w','9','5','D','W','f','U','8','5','u','6','b','5','B','8','g','y','C','E', + 'Q','z','e','9','p','N','S','P','D','D','f','x','k','Z','4','R','v','X','V','k','p','b','n','t','c','F','R','e','x','9','C','D', + 'J','2','6','f','Z','D','w','J','R','j','j','9','b','w','N','N','p','R','f','Z','z','j','F','r','Q','e','F','x','f','t','V','V', + 'A','y','J','G','W','Z','H','r','D','5','M','u','H','V','L','N','U','V','X','z','j','9','r','v','e','d','R','c','u','V','x','r', + 'c','6','k','L','h','q','w','U','W','Q','g','G','F','C','t','E','a','D','h','x','9','5','P','R','Z','E','M','5','f','4','2','t', + 'A','6','f','r','X','G','X','Y','B','8','G','E','n','B','v','x','f','M','R','f','B','z','Y','3','2','q','z','G','t','P','C','6', + '6','r','z','J','r','c','n','d','6','h','e','w','D','D','h','V','L','u','i','b','5','K','d','S','y','9','N','p','E','r','D','k', + 'B','z','u','v','d','Q','p','K','5','m','J','r','b','Y','Z','7','p','M','J','F','E','q','x','f','E','K','U','U','4','f','a','6', + 'g','5','a','q','D','U','8','F','y','R','a','P','5','5','x','z','6','V','T','P','D','m','y','7','U','5','C','A','7','Q','h','w', + 'r','6','x','g','Q','i','b','K','F','p','B','X','Q','h','i','E','r','C','z','v','x','W','Q','6','p','6','b','M','K','V','x','u', + 'k','d','R','S','k','Q','p','n','h','d','Q','Y','x','n','x','5','K','t','5','w','A','5','p','k','F','z','W','p','j','U','y','V', + 'x','G','m','y','L','A','X','H','G','A','a','J','5','E','P','q','E','U','7','p','6','A','9','n','d','G','D','g','i','h','t','W', + 'b','c','E','2','P','d','y','J','M','u','4','g','P','S','X','J','v','w','3','v','D','q','U','i','U','T','q','E','Y','5','2','t', + 'b','j','P','2','j','D','9','y','i','B','5','Y','3','X','L','w','m','V','X','z','X','r','Z','d','H','L','A','H','k','R','X','5', + 'i','L','m','q','3','p','a','G','P','j','g','h','R','P','Y','U','z','M','5','R','M','A','E','Q','V','c','w','r','4','M','S','k', + 'N','D','i','R','R','x','t','q','T','i','u','N','K','R','x','Z','K','a','g','G','y','9','c','j','J','S','9','3','H','T','f','F', + 'q','6','D','W','F','K','h','e','p','p','b','q','N','k','A','C','m','y','u','B','J','v','q','D','e','j','e','b','2','w','R','t', + 'J','N','j','F','T','A','8','L','m','X','i','T','g','j','c','V','4','V','h','2','h','R','p','2','9','k','c','c','G','D','h','z', + 't','i','h','t','W','R','n','Y','i','8','u','6','G','9','T','P','9','9','J','P','Y','R','h','X','K','z','h','L','W','r','C','U', + '2','L','T','k','2','m','6','W','L','P','T','Z','z','t','i','H','5','G','w','t','E','v','z','k','b','H','b','b','W','W','u','b', + 'i','h','C','Q','n','H','N','u','5','u','K','X','r','M','W','U','3','Y','k','P','2','k','x','f','x','C','w','z','z','b','G','8', + 'y','W','e','j','v','2','v','r','t','q','z','p','Y','d','w','6','Z','D','J','L','9','F','z','G','U','4','a','8','H','6','U','a', + 'q','7','y','Q','J','v','m','D','P','S','j','q','v','t','n','t','g','j','3','t','8','f','K','K','7','b','W','d','F','i','N','K', + 'a','R','V','V','V','v','m','A','Q','2','y','j','c','t','f','k','j','7','X','y','j','b','U','F','w','W','3','9','6','A','S','J', + 'p','q','2','Z','7','L','p','b','7','b','5','i','p','r','r','h','P','M','h','j','c','y','e','u','h','B','d','9','9','u','f','d', + 'g','u','p','w','u','9','S','c','L','U','g','A','y','V','F','V','6','D','D','X','i','V','m','u','Y','P','J','v','L','T','A','F', + 'M','Q','H','Z','6','v','8','p','A','L','P','z','C','V','a','C','h','X','j','W','8','G','z','j','d','M','4','u','x','w','H','g', + 'V','q','K','z','b','g','2','3','D','N','y','G','X','F','T','v','T','L','y','v','L','9','g','c','C','R','8','L','A','7','Y','N', + 't','n','R','6','b','n','m','9','i','h','t','T','F','a','V','N','J','J','3','J','q','p','W','7','b','T','G','r','M','k','a','7', + 'D','H','v','y','T','A','C','U','P','u','q','L','R','Y','4','q','h','y','f','F','J','x','K','7','N','B','v','3','a','Z','M','t', + 'U','x','8','9','V','E','t','j','K','r','u','Y','Y','A','u','w','Y','2','y','Q','z','S','n','J','B','2','t','X','x','K','z','g', + '6','d','n','i','7','Z','N','F','Q','6','w','N','r','b','k','d','W','X','S','t','c','U','m','6','4','2','e','w','6','x','Z','a', + 'Q','A','7','4','h','H','z','r','e','J','q','j','w','4','q','c','i','R','4','x','n','r','j','r','P','g','E','7','t','k','b','Z', + 'r','A','b','d','g','i','G','V','D','E','U','L','b','J','U','q','2','S','K','m','A','U','L','k','Q','4','N','p','k','G','C','6', + 'R','Z','B','y','B','B','j','y','x','L','d','h','L','G','6','x','H','z','T','5','d','Y','4','2','m','q','Q','y','H','6','c','N', + 'u','m','U','v','i','Y','Z','7','4','L','K','F','b','v','2','Y','h','x','8','a','R','w','q','x','E','a','T','y','m','C','2','Q', + 'U','T','D','Q','v','u','M','9','D','8','r','8','b','m','p','E','7','C','T','9','B','A','G','k','b','G','z','Z','G','L','N','k', + 'h','3','k','J','e','f','d','x','F','8','W','K','7','T','6','h','H','V','C','h','P','u','H','e','v','w','z','P','K','r','D','G', + 'X','Z','B','X','f','H','Q','4','e','D','y','W','Z','6','4','K','A','e','a','F','S','N','h','x','S','W','J','c','E','P','g','j', + 'a','w','T','m','Z','X','E','P','Y','R','M','2','R','2','X','N','F','X','Y','W','x','z','p','J','g','n','D','4','i','p','6','N', + 'r','9','G','k','E','h','T','h','U','h','x','B','Q','9','H','7','w','U','P','Q','d','G','6','q','p','j','j','v','C','a','X','J', + 'N','G','Y','w','f','H','C','x','F','k','z','3','9','r','h','8','7','5','V','i','V','C','R','q','x','N','2','2','i','W','F','U', + '7','T','H','f','z','E','a','n','u','Q','t','U','Y','G','t','3','A','m','r','6','d','f','e','n','e','z','F','u','U','N','8','m', + 'h','p','R','N','S','H','6','6','V','M','S','t','q','P','E','i','u','y','g','8','L','Q','Y','Y','G','e','W','W','C','G','y','b', + 'y','t','u','P','R','P','5','m','N','K','B','Z','w','f','t','k','x','3','L','b','q','d','w','S','G','E','h','R','F','4','q','e', + '5','6','F','2','n','q','T','R','y','f','n','Y','h','2','F','u','x','M','i','i','h','w','G','C','Z','v','i','C','a','X','U','C', + 'Y','8','d','h','R','x','V','n','v','G','i','D','a','U','p','U','a','e','b','F','w','P','d','X','n','K','h','9','H','r','b','g', + '2','f','m','X','k','m','q','6','n','5','b','G','H','d','R','9','D','U','c','r','Z','Y','W','S','Z','x','p','t','x','y','4','k', + 'j','F','U','t','C','i','e','i','b','p','e','4','C','z','h','3','3','5','Q','P','n','G','i','A','8','c','Q','z','B','a','V','4', + '2','B','2','z','u','u','3','i','L','w','y','g','K','H','k','y','2','B','b','e','5','e','4','e','U','4','z','n','P','z','a','c', + 'E','f','u','M','G','C','g','z','j','4','E','7','R','t','D','K','c','t','p','g','W','H','C','H','J','Q','J','c','F','5','4','W', + 'K','7','j','h','A','T','K','z','t','S','f','f','j','C','c','8','n','7','c','T','U','R','Q','E','7','A','W','Z','z','K','5','j', + '2','H','k','a','j','g','g','W','w','4','T','A','9','J','U','e','S','N','P','K','d','k','L','Q','G','Z','e','W','i','H','u','j', + 'C','z','4','E','2','v','5','L','u','9','Z','a','9','A','b','C','M','G','X','B','C','2','Y','Z','e','U','n','E','5','Y','n','y', + 'F','h','H','p','9','j','Y','F','V','w','Y','r','8','Q','f','C','J','4','T','t','z','Q','N','M','e','7','4','3','y','E','M','m', + 'b','S','c','h','w','a','X','E','d','E','z','t','h','9','k','p','A','k','K','H','x','q','K','Z','B','u','a','9','3','U','U','u', + '8','E','D','v','y','k','W','Y','X','k','r','R','D','X','n','Q','V','d','e','D','g','x','E','V','Y','w','k','m','K','r','H','D', + 't','2','6','N','U','g','3','t','B','9','t','u','M','D','z','Y','K','z','K','r','V','5','i','e','p','M','d','t','w','6','a','f', + 'f','W','k','L','i','g','M','V','M','Y','b','x','e','4','h','h','Y','g','w','Z','m','e','e','6','R','W','M','x','G','y','V','n', + '6','e','g','A','g','K','a','N','7','p','a','u','E','4','6','M','t','X','h','g','b','j','p','5','x','x','B','P','3','J','M','7', + 'j','Z','P','y','e','Q','Z','e','t','j','3','t','F','V','x','m','b','b','B','y','J','L','L','9','3','R','a','5','j','S','V','t', + 'e','2','6','m','H','w','r','w','r','6','Q','3','x','z','m','A','d','x','t','E','H','c','Z','x','c','P','j','r','u','U','W','k', + '6','g','X','g','n','f','n','7','H','M','B','t','v','6','v','x','g','M','f','e','2','w','m','y','d','H','S','q','c','K','U','H', + '2','X','h','d','p','Q','7','J','X','i','X','f','a','z','V','A','F','2','8','z','v','h','C','h','e','4','g','z','w','z','h','q', + 'p','6','B','n','m','8','h','W','U','7','z','h','T','6','J','f','4','Z','n','Q','W','z','2','N','4','t','g','7','u','4','X','2', + 'C','F','L','n','J','n','m','j','3','P','3','Y','e','J','R','A','H','e','R','D','z','7','u','X','Y','y','D','w','J','m','G','U', + 'P','H','5','S','d','a','F','F','Y','c','M','f','3','3','L','v','V','B','U','C','A','d','N','H','Q','h','7','8','4','r','p','G', + 'v','M','D','H','7','e','E','r','i','K','Q','i','B','D','M','Z','p','c','R','G','u','c','H','a','N','k','E','f','9','R','7','x', + '6','3','5','u','x','3','h','v','p','6','q','r','j','u','f','W','T','q','P','n','Y','L','B','6','U','w','P','2','T','W','R','g', + '2','3','3','e','N','V','a','j','b','e','4','T','u','J','u','u','F','B','D','G','H','x','x','k','5','G','e','3','4','B','m','L', + 'S','b','i','t','T','p','M','D','Z','A','A','i','r','J','p','4','H','U','A','G','y','d','Q','5','U','R','F','8','q','a','S','H', + 'n','5','z','9','g','3','u','R','H','m','G','m','b','p','c','L','Z','Y','u','m','i','K','A','Q','R','T','X','G','t','b','8','7', + '7','6','w','M','N','f','R','G','r','L','m','q','n','7','5','k','X','8','g','u','K','7','Y','w','K','q','U','e','W','A','r','i', + 'Z','a','p','q','L','5','P','u','n','t','y','G','x','C','N','X','q','P','r','U','v','A','r','r','q','e','f','c','z','M','7','N', + '6','a','z','Z','a','t','f','p','4','v','J','Y','j','h','M','D','t','k','A','B','p','Q','A','y','x','X','7','p','S','8','m','M', + 'y','K','B','A','5','2','7','b','y','R','K','q','A','u','3','J'}; + +static const adler32_test tests[] = { + {0x1, (const uint8_t *)0x0, 0, 0x1}, + {0x1, (const uint8_t *)"", 1, 0x10001}, + {0x1, (const uint8_t *)"a", 1, 0x620062}, + {0x1, (const uint8_t *)"abacus", 6, 0x8400270}, + {0x1, (const uint8_t *)"backlog", 7, 0xb1f02d4}, + {0x1, (const uint8_t *)"campfire", 8, 0xea10348}, + {0x1, (const uint8_t *)"delta", 5, 0x61a020b}, + {0x1, (const uint8_t *)"executable", 10, 0x16fa0423}, + {0x1, (const uint8_t *)"file", 4, 0x41401a1}, + {0x1, (const uint8_t *)"greatest", 8, 0xefa0360}, + {0x1, (const uint8_t *)"inverter", 8, 0xf6f0370}, + {0x1, (const uint8_t *)"jigsaw", 6, 0x8bd0286}, + {0x1, (const uint8_t *)"karate", 6, 0x8a50279}, + {0x1, (const uint8_t *)"landscape", 9, 0x126a03ac}, + {0x1, (const uint8_t *)"machine", 7, 0xb5302d6}, + {0x1, (const uint8_t *)"nanometer", 9, 0x12d803ca}, + {0x1, (const uint8_t *)"oblivion", 8, 0xf220363}, + {0x1, (const uint8_t *)"panama", 6, 0x8a1026f}, + {0x1, (const uint8_t *)"quest", 5, 0x6970233}, + {0x1, (const uint8_t *)"resource", 8, 0xf8d0369}, + {0x1, (const uint8_t *)"secret", 6, 0x8d10287}, + {0x1, (const uint8_t *)"ultimate", 8, 0xf8d0366}, + {0x1, (const uint8_t *)"vector", 6, 0x8fb0294}, + {0x1, (const uint8_t *)"walrus", 6, 0x918029f}, + {0x1, (const uint8_t *)"xeno", 4, 0x45e01bb}, + {0x1, (const uint8_t *)"yelling", 7, 0xbfe02f5}, + {0x1, (const uint8_t *)"zero", 4, 0x46e01c1}, + {0x1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x3eef064d}, + {0x1, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x425d065f}, + {0x1, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0x4f1a073e}, + {0x1, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x42290650}, + {0x1, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0x43fd0690}, + {0x1, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x3f770609}, + {0x1, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x4c7c0703}, + {0x1, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x48ac06b7}, + {0x1, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x489a0698}, + {0x1, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x44a906e6}, + {0x1, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x4a29071c}, + {0x1, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x4a7706f9}, + {0x1, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x4ce60769}, + {0x1, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x48ae06e5}, + {0x1, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x51d60750}, + {0x1, (const uint8_t *)"70684206568419061514", 20, 0x2b100414}, + {0x1, (const uint8_t *)"42015093765128581010", 20, 0x2a550405}, + {0x1, (const uint8_t *)"88214814356148806939", 20, 0x2b450423}, + {0x1, (const uint8_t *)"43472694284527343838", 20, 0x2b460421}, + {0x1, (const uint8_t *)"49769333513942933689", 20, 0x2bc1042b}, + {0x1, (const uint8_t *)"54979784887993251199", 20, 0x2ccd043d}, + {0x1, (const uint8_t *)"58360544869206793220", 20, 0x2b68041a}, + {0x1, (const uint8_t *)"27347953487840714234", 20, 0x2b84041d}, + {0x1, (const uint8_t *)"07650690295365319082", 20, 0x2afa0417}, + {0x1, (const uint8_t *)"42655507906821911703", 20, 0x2aff0412}, + {0x1, (const uint8_t *)"29977409200786225655", 20, 0x2b8d0420}, + {0x1, (const uint8_t *)"85181542907229116674", 20, 0x2b140419}, + {0x1, (const uint8_t *)"87963594337989416799", 20, 0x2c8e043f}, + {0x1, (const uint8_t *)"21395988329504168551", 20, 0x2b68041f}, + {0x1, (const uint8_t *)"51991013580943379423", 20, 0x2af10417}, + {0x1, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x7c9d0841}, + {0x1, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x71060751}, + {0x1, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x7095070a}, + {0x1, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x82530815}, + {0x1, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x61250661}, + {0x1, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x642006a3}, + {0x1, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x674206cb}, + {0x1, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x67670680}, + {0x1, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0x7547070f}, + {0x1, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x69ea06ee}, + {0x1, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x1b01e92}, + {0x1, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xfbdb1e96}, + {0x1, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0x47a61ec8}, + {0x1, (const uint8_t *)long_string, 5552, 0x8b81718f}, + {0x7a30360d, (const uint8_t *)0x0, 0, 0x1}, + {0x6fd767ee, (const uint8_t *)"", 1, 0xd7c567ee}, + {0xefeb7589, (const uint8_t *)"a", 1, 0x65e475ea}, + {0x61cf7e6b, (const uint8_t *)"abacus", 6, 0x60b880da}, + {0xdc712e2, (const uint8_t *)"backlog", 7, 0x9d0d15b5}, + {0xad23c7fd, (const uint8_t *)"campfire", 8, 0xfbfecb44}, + {0x85cb2317, (const uint8_t *)"delta", 5, 0x3b622521}, + {0x9eed31b0, (const uint8_t *)"executable", 10, 0xa6db35d2}, + {0xb94f34ca, (const uint8_t *)"file", 4, 0x9096366a}, + {0xab058a2, (const uint8_t *)"greatest", 8, 0xded05c01}, + {0x5bff2b7a, (const uint8_t *)"inverter", 8, 0xc7452ee9}, + {0x605c9a5f, (const uint8_t *)"jigsaw", 6, 0x7899ce4}, + {0x51bdeea5, (const uint8_t *)"karate", 6, 0xf285f11d}, + {0x85c21c79, (const uint8_t *)"landscape", 9, 0x98732024}, + {0x97216f56, (const uint8_t *)"machine", 7, 0xadf4722b}, + {0x18444af2, (const uint8_t *)"nanometer", 9, 0xcdb34ebb}, + {0xbe6ce359, (const uint8_t *)"oblivion", 8, 0xe8b7e6bb}, + {0x843071f1, (const uint8_t *)"panama", 6, 0x389e745f}, + {0xf2480c60, (const uint8_t *)"quest", 5, 0x36c90e92}, + {0x2d2feb3d, (const uint8_t *)"resource", 8, 0x9705eea5}, + {0x7490310a, (const uint8_t *)"secret", 6, 0xa3a63390}, + {0x97d247d4, (const uint8_t *)"ultimate", 8, 0xe6154b39}, + {0x93cf7599, (const uint8_t *)"vector", 6, 0x5e87782c}, + {0x73c84278, (const uint8_t *)"walrus", 6, 0xbc84516}, + {0x228a87d1, (const uint8_t *)"xeno", 4, 0x4646898b}, + {0xa7a048d0, (const uint8_t *)"yelling", 7, 0xb1654bc4}, + {0x1f0ded40, (const uint8_t *)"zero", 4, 0xd8a4ef00}, + {0xa804a62f, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xe34eac7b}, + {0x508fae6a, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x33f2b4c8}, + {0xe5adaf4f, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xe7b1b68c}, + {0x67136a40, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0xf6a0708f}, + {0xb00c4a10, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xbd8f509f}, + {0x2e0c84b5, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xcc298abd}, + {0x81238d44, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xd7809446}, + {0xf853aa92, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0x9525b148}, + {0x5a692325, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x620029bc}, + {0x3275b9f, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x70916284}, + {0x38371feb, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xd52706}, + {0xafc8bf62, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xeeb4c65a}, + {0x9b07db73, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xde3e2db}, + {0xe75b214, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x4171b8f8}, + {0x72d0fe6f, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0xa66a05cd}, + {0xf857a4b1, (const uint8_t *)"70684206568419061514", 20, 0x1f9a8c4}, + {0x54b8e14, (const uint8_t *)"42015093765128581010", 20, 0x49c19218}, + {0xd6aa5616, (const uint8_t *)"88214814356148806939", 20, 0xbbfc5a38}, + {0x11e63098, (const uint8_t *)"43472694284527343838", 20, 0x93434b8}, + {0xbe92385, (const uint8_t *)"49769333513942933689", 20, 0xfe1827af}, + {0x49511de0, (const uint8_t *)"54979784887993251199", 20, 0xcba8221c}, + {0x3db13bc1, (const uint8_t *)"58360544869206793220", 20, 0x14643fda}, + {0xbb899bea, (const uint8_t *)"27347953487840714234", 20, 0x1604a006}, + {0xf6cd9436, (const uint8_t *)"07650690295365319082", 20, 0xb69f984c}, + {0x9109e6c3, (const uint8_t *)"42655507906821911703", 20, 0xc43eead4}, + {0x75770fc, (const uint8_t *)"29977409200786225655", 20, 0x707751b}, + {0x69b1d19b, (const uint8_t *)"85181542907229116674", 20, 0xf5bdd5b3}, + {0xc6132975, (const uint8_t *)"87963594337989416799", 20, 0x2fed2db3}, + {0xd58cb00c, (const uint8_t *)"21395988329504168551", 20, 0xc2a2b42a}, + {0xb63b8caa, (const uint8_t *)"51991013580943379423", 20, 0xdf0590c0}, + {0x8a45a2b8, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x1980aaf8}, + {0xcbe95b78, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xf58662c8}, + {0x4ef8a54b, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0x1f65ac54}, + {0x76ad267a, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x7b792e8e}, + {0x569e613c, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x1d61679c}, + {0x36aa61da, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x12ec687c}, + {0xf67222df, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x740329a9}, + {0x74b34fd3, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x374c5652}, + {0x351fd770, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xeadfde7e}, + {0xc45aef77, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x3fcbf664}, + {0xd034ea71, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0x6b080911}, + {0xdeadc0de, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0x355fdf73}, + {0xba5eba11, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xb48bd8d8}, + {0x7712aa45, (const uint8_t *)long_string, 5552, 0x7dc51be2}, +}; + +class adler32_variant : public ::testing::TestWithParam { +public: + void hash(adler32_test param, adler32_func adler32) { + uint32_t adler = adler32((uint32_t)param.adler, param.buf, param.len); + EXPECT_EQ(adler, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(adler32, adler32_variant, testing::ValuesIn(tests)); + +#define TEST_ADLER32(name, func, support_flag) \ + TEST_P(adler32_variant, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_ADLER32(c, adler32_c, 1) + +#ifdef ARM_NEON +TEST_ADLER32(neon, adler32_neon, test_cpu_features.arm.has_neon) +#elif defined(POWER8_VSX) +TEST_ADLER32(power8, adler32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(PPC_VMX) +TEST_ADLER32(vmx, adler32_vmx, test_cpu_features.power.has_altivec) +#endif + +#ifdef X86_SSSE3 +TEST_ADLER32(ssse3, adler32_ssse3, test_cpu_features.x86.has_ssse3) +#endif +#ifdef X86_AVX2 +TEST_ADLER32(avx2, adler32_avx2, test_cpu_features.x86.has_avx2) +#endif +#ifdef X86_AVX512 +TEST_ADLER32(avx512, adler32_avx512, test_cpu_features.x86.has_avx512) +#endif +#ifdef X86_AVX512VNNI +TEST_ADLER32(avx512_vnni, adler32_avx512_vnni, test_cpu_features.x86.has_avx512vnni) +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_aligned_alloc.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_aligned_alloc.cc new file mode 100644 index 000000000..07f99a9da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_aligned_alloc.cc @@ -0,0 +1,48 @@ +/* test_aligned_alloc.cc - Test zng_alloc_aligned and zng_free_aligned */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil.h" +} + +#include + +#include "test_shared.h" + +void *zng_calloc_unaligned(void *opaque, unsigned items, unsigned size) { + uint8_t *pointer = (uint8_t *)calloc(1, (items * size) + 2); + Z_UNUSED(opaque); + if (pointer == NULL) + return pointer; + /* Store whether or not our allocation is aligned */ + *pointer = ((uint64_t)(intptr_t)pointer + 1) % 2 == 0; + pointer++; + if (*pointer) { + /* Return pointer that is off by one */ + pointer++; + } + return (void *)pointer; +} + +void zng_cfree_unaligned(void *opaque, void *ptr) { + uint8_t *pointer = (uint8_t *)ptr; + Z_UNUSED(opaque); + pointer--; + /* Get whether or not our original memory pointer was aligned */ + if (*pointer) { + /* Return original aligned pointer to free() */ + pointer--; + } + free(pointer); +} + +TEST(zalloc, aligned_64) { + void *return_ptr = PREFIX3(alloc_aligned)(zng_calloc_unaligned, 0, 1, 100, 64); + ASSERT_TRUE(return_ptr != NULL); + EXPECT_EQ((intptr_t)return_ptr % 64, 0); + PREFIX3(free_aligned)(zng_cfree_unaligned, 0, return_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compare256.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compare256.cc new file mode 100644 index 000000000..0e656da37 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compare256.cc @@ -0,0 +1,83 @@ +/* test_compare256.cc -- compare256 unit tests + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +#include "test_shared.h" + +#define MAX_COMPARE_SIZE (256) + + +/* Ensure that compare256 returns the correct match length */ +static inline void compare256_match_check(compare256_func compare256) { + int32_t match_len, i; + uint8_t *str1; + uint8_t *str2; + + str1 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str1 != NULL); + memset(str1, 'a', MAX_COMPARE_SIZE); + + str2 = (uint8_t *)zng_alloc(MAX_COMPARE_SIZE); + ASSERT_TRUE(str2 != NULL); + memset(str2, 'a', MAX_COMPARE_SIZE); + + for (i = 0; i <= MAX_COMPARE_SIZE; i++) { + if (i < MAX_COMPARE_SIZE) + str2[i] = 0; + + match_len = compare256(str1, str2); + EXPECT_EQ(match_len, i); + + if (i < MAX_COMPARE_SIZE) + str2[i] = 'a'; + } + + zng_free(str1); + zng_free(str2); +} + +#define TEST_COMPARE256(name, func, support_flag) \ + TEST(compare256, name) { \ + if (!support_flag) { \ + GTEST_SKIP(); \ + return; \ + } \ + compare256_match_check(func); \ + } + +TEST_COMPARE256(c, compare256_c, 1) + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +TEST_COMPARE256(unaligned_16, compare256_unaligned_16, 1) +#ifdef HAVE_BUILTIN_CTZ +TEST_COMPARE256(unaligned_32, compare256_unaligned_32, 1) +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(unaligned_64, compare256_unaligned_64, 1) +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(sse2, compare256_sse2, test_cpu_features.x86.has_sse2) +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +TEST_COMPARE256(avx2, compare256_avx2, test_cpu_features.x86.has_avx2) +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +TEST_COMPARE256(neon, compare256_neon, test_cpu_features.arm.has_neon) +#endif +#ifdef POWER9 +TEST_COMPARE256(power9, compare256_power9, test_cpu_features.power.has_arch_3_00) +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress.cc new file mode 100644 index 000000000..e069b69d3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress.cc @@ -0,0 +1,33 @@ +/* test_compress.cc - Test compress() and uncompress() using hello world string */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic) { + uint8_t compr[128], uncompr[128]; + z_uintmax_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = PREFIX(compress)(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = PREFIX(uncompress)(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_bound.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_bound.cc new file mode 100644 index 000000000..b83b59f4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_bound.cc @@ -0,0 +1,59 @@ +/* test_compress_bound.cc - Test compressBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +class compress_bound_variant : public testing::TestWithParam { +public: + void estimate(int32_t level) { + z_size_t estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t dest[128]; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + + /* buffer with values for worst case compression */ + for (int32_t j = 0; j < MAX_LENGTH; j++) { + uncompressed[j] = (uint8_t)j; + } + + for (z_size_t i = 0; i < MAX_LENGTH; i++) { + z_uintmax_t dest_len = sizeof(dest); + + /* calculate actual output length */ + estimate_len = PREFIX(compressBound)(i); + + err = PREFIX(compress2)(dest, &dest_len, uncompressed, i, level); + EXPECT_EQ(err, Z_OK); + EXPECT_GE(estimate_len, dest_len) << + "level: " << level << "\n" << + "length: " << i; + } + + free(uncompressed); + } +}; + +TEST_P(compress_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(compress_bound, compress_bound_variant, + testing::Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_dual.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_dual.cc new file mode 100644 index 000000000..a92ab4be3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_compress_dual.cc @@ -0,0 +1,28 @@ +/* test_compress_dual.cc - Test linking against both zlib and zlib-ng */ + +#include "zlib.h" + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(compress, basic_zlib) { + Byte compr[128], uncompr[128]; + uLong compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + err = compress(compr, &compr_len, (const unsigned char *)hello, hello_len); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + err = uncompress(uncompr, &uncompr_len, compr, compr_len); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, (char *)hello); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cpu_features.h b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cpu_features.h new file mode 100644 index 000000000..1bb4b13a0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cpu_features.h @@ -0,0 +1,8 @@ +#ifndef TEST_CPU_FEATURES_H +#define TEST_CPU_FEATURES_H + +#include "cpu_features.h" + +extern struct cpu_features test_cpu_features; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_crc32.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_crc32.cc new file mode 100644 index 000000000..f194b4ccf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_crc32.cc @@ -0,0 +1,222 @@ +/* test_crc32.cc -- crc32 unit test + * Copyright (C) 2019-2021 IBM Corporation + * Authors: Rogerio Alves + * Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include +#include + +extern "C" { +# include "zbuild.h" +# include "zutil_p.h" +# include "test_cpu_features.h" +} + +#include + +typedef struct { + unsigned long crc; + const uint8_t *buf; + size_t len; + unsigned long expect; +} crc32_test; + +static const crc32_test tests[] = { + {0x0, (const uint8_t *)0x0, 0, 0x0}, + {0xffffffff, (const uint8_t *)0x0, 0, 0x0}, + {0x0, (const uint8_t *)0x0, 255, 0x0}, /* BZ 174799. */ + {0x0, (const uint8_t *)0x0, 256, 0x0}, + {0x0, (const uint8_t *)0x0, 257, 0x0}, + {0x0, (const uint8_t *)0x0, 32767, 0x0}, + {0x0, (const uint8_t *)0x0, 32768, 0x0}, + {0x0, (const uint8_t *)0x0, 32769, 0x0}, + {0x0, (const uint8_t *)"", 0, 0x0}, + {0xffffffff, (const uint8_t *)"", 0, 0xffffffff}, + {0x0, (const uint8_t *)"abacus", 6, 0xc3d7115b}, + {0x0, (const uint8_t *)"backlog", 7, 0x269205}, + {0x0, (const uint8_t *)"campfire", 8, 0x22a515f8}, + {0x0, (const uint8_t *)"delta", 5, 0x9643fed9}, + {0x0, (const uint8_t *)"executable", 10, 0xd68eda01}, + {0x0, (const uint8_t *)"file", 4, 0x8c9f3610}, + {0x0, (const uint8_t *)"greatest", 8, 0xc1abd6cd}, + {0x0, (const uint8_t *)"hello", 5, 0x3610a686}, + {0x0, (const uint8_t *)"inverter", 8, 0xc9e962c9}, + {0x0, (const uint8_t *)"jigsaw", 6, 0xce4e3f69}, + {0x0, (const uint8_t *)"karate", 6, 0x890be0e2}, + {0x0, (const uint8_t *)"landscape", 9, 0xc4e0330b}, + {0x0, (const uint8_t *)"machine", 7, 0x1505df84}, + {0x0, (const uint8_t *)"nanometer", 9, 0xd4e19f39}, + {0x0, (const uint8_t *)"oblivion", 8, 0xdae9de77}, + {0x0, (const uint8_t *)"panama", 6, 0x66b8979c}, + {0x0, (const uint8_t *)"quest", 5, 0x4317f817}, + {0x0, (const uint8_t *)"resource", 8, 0xbc91f416}, + {0x0, (const uint8_t *)"secret", 6, 0x5ca2e8e5}, + {0x0, (const uint8_t *)"test", 4, 0xd87f7e0c}, + {0x0, (const uint8_t *)"ultimate", 8, 0x3fc79b0b}, + {0x0, (const uint8_t *)"vector", 6, 0x1b6e485b}, + {0x0, (const uint8_t *)"walrus", 6, 0xbe769b97}, + {0x0, (const uint8_t *)"xeno", 4, 0xe7a06444}, + {0x0, (const uint8_t *)"yelling", 7, 0xfe3944e5}, + {0x0, (const uint8_t *)"zlib", 4, 0x73887d3a}, + {0x0, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0xd487a5a1}, + {0x0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0x61a0132e}, + {0x0, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdf02f76}, + {0x0, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x579b2b0a}, + {0x0, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xf7d16e2d}, + {0x0, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0x731788f5}, + {0x0, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0x7112bb11}, + {0x0, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xf32a0dac}, + {0x0, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0x625437bb}, + {0x0, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0x896930f9}, + {0x0, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0x8579a37}, + {0x0, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0x632aa8e0}, + {0x0, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0xc829af29}, + {0x0, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x1b08b7e8}, + {0x0, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x4e33b192}, + {0x0, (const uint8_t *)"70684206568419061514", 20, 0x59a179f0}, + {0x0, (const uint8_t *)"42015093765128581010", 20, 0xcd1013d7}, + {0x0, (const uint8_t *)"88214814356148806939", 20, 0xab927546}, + {0x0, (const uint8_t *)"43472694284527343838", 20, 0x11f3b20c}, + {0x0, (const uint8_t *)"49769333513942933689", 20, 0xd562d4ca}, + {0x0, (const uint8_t *)"54979784887993251199", 20, 0x233395f7}, + {0x0, (const uint8_t *)"58360544869206793220", 20, 0x2d167fd5}, + {0x0, (const uint8_t *)"27347953487840714234", 20, 0x8b5108ba}, + {0x0, (const uint8_t *)"07650690295365319082", 20, 0xc46b3cd8}, + {0x0, (const uint8_t *)"42655507906821911703", 20, 0xc10b2662}, + {0x0, (const uint8_t *)"29977409200786225655", 20, 0xc9a0f9d2}, + {0x0, (const uint8_t *)"85181542907229116674", 20, 0x9341357b}, + {0x0, (const uint8_t *)"87963594337989416799", 20, 0xf0424937}, + {0x0, (const uint8_t *)"21395988329504168551", 20, 0xd7c4c31f}, + {0x0, (const uint8_t *)"51991013580943379423", 20, 0xf11edcc4}, + {0x0, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x40795df4}, + {0x0, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0xdd61a631}, + {0x0, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xca907a99}, + {0x0, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0xf652deac}, + {0x0, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0xaf39a5a9}, + {0x0, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x6bebb4cf}, + {0x0, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0x76430bac}, + {0x0, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x6c80c388}, + {0x0, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xd54d977d}, + {0x0, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0xe3966ad5}, + {0x0, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xe7c71db9}, + {0x0, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xeaa52777}, + {0x0, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xcd472048}, + {0x7a30360d, (const uint8_t *)"abacus", 6, 0xf8655a84}, + {0x6fd767ee, (const uint8_t *)"backlog", 7, 0x1ed834b1}, + {0xefeb7589, (const uint8_t *)"campfire", 8, 0x686cfca}, + {0x61cf7e6b, (const uint8_t *)"delta", 5, 0x1554e4b1}, + {0xdc712e2, (const uint8_t *)"executable", 10, 0x761b4254}, + {0xad23c7fd, (const uint8_t *)"file", 4, 0x7abdd09b}, + {0x85cb2317, (const uint8_t *)"greatest", 8, 0x4ba91c6b}, + {0x9eed31b0, (const uint8_t *)"inverter", 8, 0xd5e78ba5}, + {0xb94f34ca, (const uint8_t *)"jigsaw", 6, 0x23649109}, + {0xab058a2, (const uint8_t *)"karate", 6, 0xc5591f41}, + {0x5bff2b7a, (const uint8_t *)"landscape", 9, 0xf10eb644}, + {0x605c9a5f, (const uint8_t *)"machine", 7, 0xbaa0a636}, + {0x51bdeea5, (const uint8_t *)"nanometer", 9, 0x6af89afb}, + {0x85c21c79, (const uint8_t *)"oblivion", 8, 0xecae222b}, + {0x97216f56, (const uint8_t *)"panama", 6, 0x47dffac4}, + {0x18444af2, (const uint8_t *)"quest", 5, 0x70c2fe36}, + {0xbe6ce359, (const uint8_t *)"resource", 8, 0x1471d925}, + {0x843071f1, (const uint8_t *)"secret", 6, 0x50c9a0db}, + {0xf2480c60, (const uint8_t *)"ultimate", 8, 0xf973daf8}, + {0x2d2feb3d, (const uint8_t *)"vector", 6, 0x344ac03d}, + {0x7490310a, (const uint8_t *)"walrus", 6, 0x6d1408ef}, + {0x97d247d4, (const uint8_t *)"xeno", 4, 0xe62670b5}, + {0x93cf7599, (const uint8_t *)"yelling", 7, 0x1b36da38}, + {0x73c84278, (const uint8_t *)"zlib", 4, 0x6432d127}, + {0x228a87d1, (const uint8_t *)"4BJD7PocN1VqX0jXVpWB", 20, 0x997107d0}, + {0xa7a048d0, (const uint8_t *)"F1rPWI7XvDs6nAIRx41l", 20, 0xdc567274}, + {0x1f0ded40, (const uint8_t *)"ldhKlsVkPFOveXgkGtC2", 20, 0xdcc63870}, + {0xa804a62f, (const uint8_t *)"5KKnGOOrs8BvJ35iKTOS", 20, 0x6926cffd}, + {0x508fae6a, (const uint8_t *)"0l1tw7GOcem06Ddu7yn4", 20, 0xb52b38bc}, + {0xe5adaf4f, (const uint8_t *)"MCr47CjPIn9R1IvE1Tm5", 20, 0xf83b8178}, + {0x67136a40, (const uint8_t *)"UcixbzPKTIv0SvILHVdO", 20, 0xc5213070}, + {0xb00c4a10, (const uint8_t *)"dGnAyAhRQDsWw0ESou24", 20, 0xbc7648b0}, + {0x2e0c84b5, (const uint8_t *)"di0nvmY9UYMYDh0r45XT", 20, 0xd8123a72}, + {0x81238d44, (const uint8_t *)"2XKDwHfAhFsV0RhbqtvH", 20, 0xd5ac5620}, + {0xf853aa92, (const uint8_t *)"ZhrANFIiIvRnqClIVyeD", 20, 0xceae099d}, + {0x5a692325, (const uint8_t *)"v7Q9ehzioTOVeDIZioT1", 20, 0xb07d2b24}, + {0x3275b9f, (const uint8_t *)"Yod5hEeKcYqyhfXbhxj2", 20, 0x24ce91df}, + {0x38371feb, (const uint8_t *)"GehSWY2ay4uUKhehXYb0", 20, 0x707b3b30}, + {0xafc8bf62, (const uint8_t *)"kwytJmq6UqpflV8Y8GoE", 20, 0x16abc6a9}, + {0x9b07db73, (const uint8_t *)"70684206568419061514", 20, 0xae1fb7b7}, + {0xe75b214, (const uint8_t *)"42015093765128581010", 20, 0xd4eecd2d}, + {0x72d0fe6f, (const uint8_t *)"88214814356148806939", 20, 0x4660ec7}, + {0xf857a4b1, (const uint8_t *)"43472694284527343838", 20, 0xfd8afdf7}, + {0x54b8e14, (const uint8_t *)"49769333513942933689", 20, 0xc6d1b5f2}, + {0xd6aa5616, (const uint8_t *)"54979784887993251199", 20, 0x32476461}, + {0x11e63098, (const uint8_t *)"58360544869206793220", 20, 0xd917cf1a}, + {0xbe92385, (const uint8_t *)"27347953487840714234", 20, 0x4ad14a12}, + {0x49511de0, (const uint8_t *)"07650690295365319082", 20, 0xe37b5c6c}, + {0x3db13bc1, (const uint8_t *)"42655507906821911703", 20, 0x7cc497f1}, + {0xbb899bea, (const uint8_t *)"29977409200786225655", 20, 0x99781bb2}, + {0xf6cd9436, (const uint8_t *)"85181542907229116674", 20, 0x132256a1}, + {0x9109e6c3, (const uint8_t *)"87963594337989416799", 20, 0xbfdb2c83}, + {0x75770fc, (const uint8_t *)"21395988329504168551", 20, 0x8d9d1e81}, + {0x69b1d19b, (const uint8_t *)"51991013580943379423", 20, 0x7b6d4404}, + {0xc6132975, (const uint8_t *)"*]+@!);({_$;}[_},?{?;(_?,=-][@", 30, 0x8619f010}, + {0xd58cb00c, (const uint8_t *)"_@:_).&(#.[:[{[:)$++-($_;@[)}+", 30, 0x15746ac3}, + {0xb63b8caa, (const uint8_t *)"&[!,[$_==}+.]@!;*(+},[;:)$;)-@", 30, 0xaccf812f}, + {0x8a45a2b8, (const uint8_t *)"]{.[.+?+[[=;[?}_#&;[=)__$$:+=_", 30, 0x78af45de}, + {0xcbe95b78, (const uint8_t *)"-%.)=/[@].:.(:,()$;=%@-$?]{%+%", 30, 0x25b06b59}, + {0x4ef8a54b, (const uint8_t *)"+]#$(@&.=:,*];/.!]%/{:){:@(;)$", 30, 0x4ba0d08f}, + {0x76ad267a, (const uint8_t *)")-._.:?[&:.=+}(*$/=!.${;(=$@!}", 30, 0xe26b6aac}, + {0x569e613c, (const uint8_t *)":(_*&%/[[}+,?#$&*+#[([*-/#;%(]", 30, 0x7e2b0a66}, + {0x36aa61da, (const uint8_t *)"{[#-;:$/{)(+[}#]/{&!%(@)%:@-$:", 30, 0xb3430dc7}, + {0xf67222df, (const uint8_t *)"_{$*,}(&,@.)):=!/%(&(,,-?$}}}!", 30, 0x626c17a}, + {0x74b34fd3, (const uint8_t *)"e$98KNzqaV)Y:2X?]77].{gKRD4G5{mHZk,Z)SpU%L3FSgv!Wb8MLAFdi{+fp)c,@8m6v)yXg@]HBDFk?.4&}g5_udE*JHCiH=aL", 100, 0xccf98060}, + {0x351fd770, (const uint8_t *)"r*Fd}ef+5RJQ;+W=4jTR9)R*p!B;]Ed7tkrLi;88U7g@3v!5pk2X6D)vt,.@N8c]@yyEcKi[vwUu@.Ppm@C6%Mv*3Nw}Y,58_aH)", 100, 0xd8b95312}, + {0xc45aef77, (const uint8_t *)"h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 100, 0xbb1c9912}, + {0xc45aef77, (const uint8_t *) + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&" + "h{bcmdC+a;t+Cf{6Y_dFq-{X4Yu&7uNfVDh?q&_u.UWJU],-GiH7ADzb7-V.Q%4=+v!$L9W+T=bP]$_:]Vyg}A.ygD.r;h-D]m%&", 600, 0x888AFA5B} +}; + +class crc32_variant : public ::testing::TestWithParam { +public: + void hash(crc32_test param, crc32_func crc32) { + uint32_t crc = 0; + if (param.buf != NULL) { + if (param.len) { + crc = crc32(param.crc, param.buf, param.len); + } else { + crc = param.crc; + } + } + EXPECT_EQ(crc, param.expect); + } +}; + +INSTANTIATE_TEST_SUITE_P(crc32, crc32_variant, testing::ValuesIn(tests)); + +#define TEST_CRC32(name, func, support_flag) \ + TEST_P(crc32_variant, name) { \ + if (!(support_flag)) { \ + GTEST_SKIP(); \ + return; \ + } \ + hash(GetParam(), func); \ + } + +TEST_CRC32(braid, PREFIX(crc32_braid), 1) + +#ifdef ARM_ACLE +TEST_CRC32(acle, crc32_acle, test_cpu_features.arm.has_crc32) +#elif defined(POWER8_VSX_CRC32) +TEST_CRC32(power8, crc32_power8, test_cpu_features.power.has_arch_2_07) +#elif defined(S390_CRC32_VX) +TEST_CRC32(vx, crc32_s390_vx, test_cpu_features.s390.has_vx) +#elif defined(X86_PCLMULQDQ_CRC) +TEST_CRC32(pclmulqdq, crc32_pclmulqdq, test_cpu_features.x86.has_pclmulqdq) +# ifdef X86_VPCLMULQDQ_CRC +TEST_CRC32(vpclmulqdq, crc32_vpclmulqdq, (test_cpu_features.x86.has_pclmulqdq && test_cpu_features.x86.has_avx512 && test_cpu_features.x86.has_vpclmulqdq)) +# endif +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cve-2003-0107.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cve-2003-0107.cc new file mode 100644 index 000000000..9d9e5b00d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_cve-2003-0107.cc @@ -0,0 +1,28 @@ +// https://www.securityfocus.com/archive/1/312869 --- originally by Richard Kettlewell +#include +#include +#include + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +#if !defined(_WIN32) && defined(ZLIB_COMPAT) +TEST(gzip, cve_2003_0107) { + gzFile f; + int ret; + + f = gzopen("/dev/null", "w"); + EXPECT_TRUE(f != NULL); + + ret = gzprintf(f, "%10240s", ""); + printf("gzprintf -> %d\n", ret); + ret = gzclose(f); + printf("gzclose -> %d [%d]\n", ret, errno); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_bound.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_bound.cc new file mode 100644 index 000000000..c86d4e00b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_bound.cc @@ -0,0 +1,99 @@ +/* test_deflate_bound.cc - Test deflateBound() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define MAX_LENGTH (32) + +typedef struct { + int32_t level; + int32_t window_size; + int32_t mem_level; + bool after_init; +} deflate_bound_test; + +static const deflate_bound_test tests[] = { + {0, MAX_WBITS + 16, 1, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, true}, + {Z_BEST_SPEED, MAX_WBITS, MAX_MEM_LEVEL, false}, + {Z_BEST_COMPRESSION, MAX_WBITS, MAX_MEM_LEVEL, false}, +}; + +class deflate_bound_variant : public testing::TestWithParam { +public: + void estimate(deflate_bound_test param) { + PREFIX3(stream) c_stream; + int estimate_len = 0; + uint8_t *uncompressed = NULL; + uint8_t *out_buf = NULL; + int err; + + uncompressed = (uint8_t *)malloc(MAX_LENGTH); + ASSERT_TRUE(uncompressed != NULL); + memset(uncompressed, 'a', MAX_LENGTH); + + for (int32_t i = 0; i < MAX_LENGTH; i++) { + memset(&c_stream, 0, sizeof(c_stream)); + + c_stream.avail_in = i; + c_stream.next_in = (z_const unsigned char *)uncompressed; + c_stream.avail_out = 0; + c_stream.next_out = out_buf; + + if (!param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + + err = PREFIX(deflateInit2)(&c_stream, param.level, Z_DEFLATED, + param.window_size, param.mem_level, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* calculate actual output length and update structure */ + if (param.after_init) + estimate_len = PREFIX(deflateBound)(&c_stream, i); + out_buf = (uint8_t *)malloc(estimate_len); + + if (out_buf != NULL) { + /* update zlib configuration */ + c_stream.avail_out = estimate_len; + c_stream.next_out = out_buf; + + /* do the compression */ + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END) << + "level: " << param.level << "\n" << + "window_size: " << param.window_size << "\n" << + "mem_level: " << param.mem_level << "\n" << + "after_init: " << param.after_init << "\n" << + "length: " << i; + + free(out_buf); + out_buf = NULL; + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + } + + free(uncompressed); + } +}; + +TEST_P(deflate_bound_variant, estimate) { + estimate(GetParam()); +} + +INSTANTIATE_TEST_SUITE_P(deflate_bound, deflate_bound_variant, testing::ValuesIn(tests)); diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_concurrency.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_concurrency.cc new file mode 100644 index 000000000..1297aee64 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_concurrency.cc @@ -0,0 +1,170 @@ +/* Test deflate() on concurrently modified next_in. + * + * Plain zlib does not document that this is supported, but in practice it tolerates this, and QEMU live migration is + * known to rely on this. Make sure zlib-ng tolerates this as well. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +#include "zlib.h" +#else +#include "zlib-ng.h" +#endif + +#include + +#include +#include +#include +#include + +static uint8_t buf[8 * 1024]; +static uint8_t zbuf[4 * 1024]; +static uint8_t tmp[8 * 1024]; + +/* Thread that increments all bytes in buf by 1. */ +class Mutator { + enum class State { + PAUSED, + RUNNING, + STOPPED, + }; + +public: + Mutator() + : m_state(State::PAUSED), m_target_state(State::PAUSED), + m_thread(&Mutator::run, this) {} + ~Mutator() { + transition(State::STOPPED); + m_thread.join(); + } + + void pause() { + transition(State::PAUSED); + } + + void resume() { + transition(State::RUNNING); + } + +private: + void run() { + while (true) { + m_state.store(m_target_state); + if (m_state == State::PAUSED) + continue; + if (m_state == State::STOPPED) + break; + for (uint8_t & i: buf) + i++; + } + } + + void transition(State target_state) { + m_target_state = target_state; + while (m_state != target_state) { + } + } + + std::atomic m_state, m_target_state; + std::thread m_thread; +}; + +TEST(deflate, concurrency) { +#ifdef S390_DFLTCC_DEFLATE + GTEST_SKIP() << "Known to be broken with S390_DFLTCC_DEFLATE"; +#endif + + /* Create reusable mutator and streams. */ + Mutator mutator; + + PREFIX3(stream) dstrm; + memset(&dstrm, 0, sizeof(dstrm)); + int err = PREFIX(deflateInit2)(&dstrm, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + PREFIX3(stream) istrm; + memset(&istrm, 0, sizeof(istrm)); + err = PREFIX(inflateInit2)(&istrm, -15); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Iterate for a certain amount of time. */ + auto deadline = std::chrono::steady_clock::now() + std::chrono::seconds(1); + while (std::chrono::steady_clock::now() < deadline) { + /* Start each iteration with a fresh stream state. */ + err = PREFIX(deflateReset)(&dstrm); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + + err = PREFIX(inflateReset)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + /* Mutate and compress the first half of buf concurrently. + * Decompress and throw away the results, which are unpredictable. + */ + mutator.resume(); + dstrm.next_in = buf; + dstrm.avail_in = sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + ASSERT_EQ(Z_OK, err) << istrm.msg; + } + } + + /* Stop mutation and compress the second half of buf. + * Decompress and check that the result matches. + */ + mutator.pause(); + dstrm.next_in = buf + sizeof(buf) / 2; + dstrm.avail_in = sizeof(buf) - sizeof(buf) / 2; + while (dstrm.avail_in > 0) { + dstrm.next_out = zbuf; + dstrm.avail_out = sizeof(zbuf); + err = PREFIX(deflate)(&dstrm, Z_FINISH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, dstrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << dstrm.msg; + istrm.next_in = zbuf; + istrm.avail_in = sizeof(zbuf) - dstrm.avail_out; + while (istrm.avail_in > 0) { + size_t orig_total_out = istrm.total_out; + istrm.next_out = tmp; + istrm.avail_out = sizeof(tmp); + err = PREFIX(inflate)(&istrm, Z_NO_FLUSH); + if (err == Z_STREAM_END) + ASSERT_EQ(0u, istrm.avail_in); + else + ASSERT_EQ(Z_OK, err) << istrm.msg; + size_t concurrent_size = sizeof(buf) - sizeof(buf) / 2; + if (istrm.total_out > concurrent_size) { + size_t tmp_offset, buf_offset, size; + if (orig_total_out >= concurrent_size) { + tmp_offset = 0; + buf_offset = orig_total_out - concurrent_size; + size = istrm.total_out - orig_total_out; + } else { + tmp_offset = concurrent_size - orig_total_out; + buf_offset = 0; + size = istrm.total_out - concurrent_size; + } + ASSERT_EQ(0, memcmp(tmp + tmp_offset, buf + sizeof(buf) / 2 + buf_offset, size)); + } + } + } + } + + err = PREFIX(inflateEnd)(&istrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; + + err = PREFIX(deflateEnd)(&dstrm); + ASSERT_EQ(Z_OK, err) << istrm.msg; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_copy.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_copy.cc new file mode 100644 index 000000000..4adc9be96 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_copy.cc @@ -0,0 +1,60 @@ +/* test_deflate_copy.cc - Test deflateCopy() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "deflate.h" + +#include "test_shared.h" + +#include + +TEST(deflate, copy) { + PREFIX3(stream) c_stream, c_stream_copy; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&c_stream_copy, 0, sizeof(c_stream_copy)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateCopy)(&c_stream_copy, &c_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(c_stream.state->status, c_stream_copy.state->status); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream_copy); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_dict.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_dict.cc new file mode 100644 index 000000000..781c70db2 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_dict.cc @@ -0,0 +1,54 @@ +/* test_deflate_dict.cc - Test deflateGetDictionary() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, dictionary) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + uint32_t compr_len = sizeof(compr); + uint8_t *dict_new = NULL; + uint32_t *dict_len; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + dict_new = (uint8_t *)calloc(256, 1); + ASSERT_TRUE(dict_new != NULL); + dict_len = (uint32_t *)calloc(4, 1); + ASSERT_TRUE(dict_len != NULL); + + err = PREFIX(deflateGetDictionary)(&c_stream, dict_new, dict_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(dict_new); + free(dict_len); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_hash_head_0.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_hash_head_0.cc new file mode 100644 index 000000000..cbf601038 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_hash_head_0.cc @@ -0,0 +1,83 @@ +/* Generated by fuzzing - test hash_head == 0 handling. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, hash_head_0) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -15, 4, Z_HUFFMAN_ONLY); + EXPECT_EQ(err, Z_OK); + + unsigned char next_in[9698]; + memset(next_in, 0x30, sizeof(next_in)); + next_in[8193] = 0x00; + next_in[8194] = 0x00; + next_in[8195] = 0x00; + next_in[8199] = 0x8a; + strm.next_in = next_in; + unsigned char next_out[21572]; + strm.next_out = next_out; + + strm.avail_in = 0; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 3, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 6728; + strm.avail_out = 2696; + err = PREFIX(deflate(&strm, Z_SYNC_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 15; + strm.avail_out = 1348; + err = PREFIX(deflateParams(&strm, 9, Z_FILTERED)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 1453; + strm.avail_out = 1348; + err = PREFIX(deflate(&strm, Z_FULL_FLUSH)); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = (uint32_t)(next_in + sizeof(next_in) - strm.next_in); + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_header.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_header.cc new file mode 100644 index 000000000..0d1b7d044 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_header.cc @@ -0,0 +1,71 @@ +/* test_deflate_header.cc - Test deflateSetHeader() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, header) { + PREFIX3(stream) c_stream; + PREFIX(gz_header) *head; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + + head = (PREFIX(gz_header) *)calloc(1, sizeof(PREFIX(gz_header))); + ASSERT_TRUE(head != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + /* gzip */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + head->text = 1; + head->comment = (uint8_t *)"comment"; + head->name = (uint8_t *)"name"; + head->hcrc = 1; + head->extra = (uint8_t *)"extra"; + head->extra_len = (uint32_t)strlen((const char *)head->extra); + + err = PREFIX(deflateSetHeader)(&c_stream, head); + EXPECT_EQ(err, Z_OK); + + PREFIX(deflateBound)(&c_stream, (unsigned long)compr_len); + + c_stream.next_in = (unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + /* Check CRC32. */ + EXPECT_EQ(c_stream.adler, 0xb56c3f9dU); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(head); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_params.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_params.cc new file mode 100644 index 000000000..9fadea85f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_params.cc @@ -0,0 +1,143 @@ +/* test_deflate_params.cc - Test deflate() with dynamic change of compression level */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include "deflate.h" + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (64 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, params) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + uint32_t diff; + int32_t i; + time_t now; + int err; +#ifndef ZLIB_COMPAT + int level = -1; + int strategy = -1; + zng_deflate_param_value params[2]; + + params[0].param = Z_DEFLATE_LEVEL; + params[0].buf = &level; + params[0].size = sizeof(level); + + params[1].param = Z_DEFLATE_STRATEGY; + params[1].buf = &strategy; + params[1].size = sizeof(strategy); +#endif + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_SPEED); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + /* Feed in already compressed data and switch to no compression: */ +#ifndef ZLIB_COMPAT + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_BEST_SPEED); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_NO_COMPRESSION; + strategy = Z_DEFAULT_STRATEGY; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY); +#endif + + c_stream.next_in = compr; + diff = (unsigned int)(c_stream.next_out - compr); + c_stream.avail_in = diff; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* Switch back to compressing mode: */ +#ifndef ZLIB_COMPAT + level = -1; + strategy = -1; + zng_deflateGetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); + EXPECT_EQ(level, Z_NO_COMPRESSION); + EXPECT_EQ(strategy, Z_DEFAULT_STRATEGY); + + level = Z_BEST_COMPRESSION; + strategy = Z_FILTERED; + zng_deflateSetParams(&c_stream, params, sizeof(params) / sizeof(params[0])); +#else + PREFIX(deflateParams)(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED); +#endif + + c_stream.next_in = uncompr; + c_stream.avail_in = (unsigned int)uncompr_len; + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + do { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } while (err == Z_OK); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, (2 * uncompr_len) + diff); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_pending.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_pending.cc new file mode 100644 index 000000000..8ccedbf33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_pending.cc @@ -0,0 +1,66 @@ +/* test_deflate_pending.cc - Test deflatePending() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +TEST(deflate, pending) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int *bits; + unsigned *ped; + int err; + + + bits = (int *)calloc(256, 1); + ASSERT_TRUE(bits != NULL); + ped = (unsigned *)calloc(256, 1); + ASSERT_TRUE(ped != NULL); + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflatePending)(&c_stream, ped, bits); + EXPECT_EQ(err, Z_OK); + + EXPECT_GE(*bits, 0); + EXPECT_LE(*bits, 7); + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + free(bits); + free(ped); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_prime.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_prime.cc new file mode 100644 index 000000000..75dcf3177 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_prime.cc @@ -0,0 +1,91 @@ +/* test_deflate_prime.cc - Test deflatePrime() wrapping gzip around deflate stream */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared_ng.h" + +#include + +TEST(deflate, prime) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t crc = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + /* Raw deflate windowBits is -15 */ + err = PREFIX(deflateInit2)(&c_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Gzip magic number */ + err = PREFIX(deflatePrime)(&c_stream, 16, 0x8b1f); + EXPECT_EQ(err, Z_OK); + /* Gzip compression method (deflate) */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x08); + EXPECT_EQ(err, Z_OK); + /* Gzip flags (one byte, using two odd bit calls) */ + err = PREFIX(deflatePrime)(&c_stream, 3, 0x0); + EXPECT_EQ(err, Z_OK); + err = PREFIX(deflatePrime)(&c_stream, 5, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip modified time */ + err = deflate_prime_32(&c_stream, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip extra flags */ + err = PREFIX(deflatePrime)(&c_stream, 8, 0x0); + EXPECT_EQ(err, Z_OK); + /* Gzip operating system */ + err = PREFIX(deflatePrime)(&c_stream, 8, 255); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + /* Gzip uncompressed data crc32 */ + crc = PREFIX(crc32)(0, (const uint8_t *)hello, (uint32_t)hello_len); + err = deflate_prime_32(&c_stream, crc); + EXPECT_EQ(err, Z_OK); + /* Gzip uncompressed data length */ + err = deflate_prime_32(&c_stream, (uint32_t)hello_len); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = (uint32_t)c_stream.total_out; + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + d_stream.total_in = 0; + d_stream.total_out = 0; + + /* Inflate with gzip header */ + err = PREFIX(inflateInit2)(&d_stream, MAX_WBITS + 32); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_BUF_ERROR); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char *)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_bi_valid.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_bi_valid.cc new file mode 100644 index 000000000..8ce4c229d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_bi_valid.cc @@ -0,0 +1,80 @@ +/* Generated by fuzzing - test bi_valid handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, bi_valid) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, 31, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[554] = { + 0x8d, 0xff, 0xff, 0xff, 0xa2, 0x00, 0x00, 0xff, 0x00, 0x15, 0x1b, 0x1b, 0xa2, 0xa2, 0xaf, 0xa2, + 0xa2, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1b, 0x3f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, + 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x1e, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x07, 0x01, 0x18, 0x00, 0x22, 0x00, + 0x00, 0x00, 0xfd, 0x39, 0xff, 0x00, 0x00, 0x00, 0x1b, 0xfd, 0x3b, 0x00, 0x68, 0x00, 0x00, 0x01, + 0xff, 0xff, 0xff, 0x57, 0xf8, 0x1e, 0x00, 0x00, 0xf2, 0xf2, 0xf2, 0xf2, 0xfa, 0xff, 0xff, 0xff, + 0xff, 0x7e, 0x00, 0x00, 0x4a, 0x00, 0xc5, 0x00, 0x41, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, + 0x00, 0x02, 0x01, 0x01, 0x00, 0xa2, 0x08, 0x00, 0x00, 0x00, 0x00, 0x27, 0x4a, 0x4a, 0x4a, 0x32, + 0x00, 0xf9, 0xff, 0x00, 0x02, 0x9a, 0xff, 0x00, 0x00, 0x3f, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x08, 0x2f, 0x20, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x7a, 0x7a, 0x9e, 0xff, 0xff, 0x00, 0x1b, 0x1b, 0x04, 0x00, 0x1b, 0x1b, + 0x1b, 0x1b, 0x00, 0x00, 0x00, 0xaf, 0xad, 0xaf, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, 0x2e, 0xff, + 0xff, 0x2e, 0xc1, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x70, 0x00, 0x00, 0x00, 0xda, 0x67, 0x01, + 0x47, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x3f, + 0x54, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x34, 0x3e, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7a, 0x7a, 0x7a, 0x7a, 0x7a, 0x00, 0x00, 0x00, 0x40, 0x1b, 0x1b, 0x88, 0x1b, 0x1b, + 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1f, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x50, 0x3e, 0x7a, 0x7a, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x87, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0xff, 0x3d, 0x00, 0x11, 0x4d, 0x00, 0x00, 0x01, 0xd4, 0xd4, 0xd4, 0xd4, 0x2d, 0xd4, + 0xd4, 0xff, 0xff, 0xff, 0xfa, 0x01, 0xd4, 0x00, 0xd4, 0x00, 0x00, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, + 0xd4, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, 0x00, 0xfe, 0xf9, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x00, + 0x16, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0x00, 0x00, 0x80, 0x20, 0x00, 0x00, + 0xff, 0x2b, 0x2b, 0x2b, 0x2b, 0x35, 0xd4, 0xd4, 0x47, 0x3f, 0xd4, 0xd4, 0xd6, 0xd4, 0xd4, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x32, 0x4a, 0x4a, 0x4a, 0x4a, 0x71, 0x00, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, + 0x1f, 0x1b, 0x1b, 0x1b, 0x57, 0x57, 0x57, 0x57, 0x00, 0x00, 0x1b, 0x08, 0x2b, 0x16, 0xc3, 0x00, + 0x00, 0x00, 0x29, 0x30, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x07, 0x00, 0x00, 0x01, 0x0b, 0xff, + 0xff, 0xf5, 0xf5, 0xf5, 0x00, 0x00, 0xfe, 0xfa, 0x0f, 0x0f, 0x08, 0x00, 0xff, 0x00, 0x53, 0x3f, + 0x00, 0x04, 0x5d, 0xa8, 0x2e, 0xff, 0xff, 0x00, 0x2f, 0x2f, 0x05, 0xff, 0xff, 0xff, 0x2f, 0x2f, + 0x2f, 0x0a, 0x0a, 0x0a, 0x0a, 0x30, 0xff, 0xff, 0xff, 0xf0, 0x0a, 0x0a, 0x0a, 0x00, 0xff, 0x3f, + 0x4f, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x71, 0x71, 0x00, 0x71, 0x71, 0x71, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x3f, 0x00, 0xfa, 0x71, 0x71, 0x71, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x71, 0x71, 0x71, 0x71, 0x71}; + strm.next_in = next_in; + unsigned char next_out[1236]; + strm.next_out = next_out; + + strm.avail_in = 554; + strm.avail_out = 31; + + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_OK); + + strm.avail_in = 0; + strm.avail_out = 498; + err = PREFIX(deflate)(&strm, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_block_open.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_block_open.cc new file mode 100644 index 000000000..84a1ac8bb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_quick_block_open.cc @@ -0,0 +1,94 @@ +/* Generated by fuzzing - test block_open handling in deflate_quick(). */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate_quick, block_open) { + PREFIX3(stream) strm; + int err; + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(deflateInit2)(&strm, 1, Z_DEFLATED, -MAX_WBITS, 1, Z_FILTERED); + EXPECT_EQ(err, Z_OK); + + z_const unsigned char next_in[495] = + "\x1d\x1d\x00\x00\x00\x4a\x4a\x4a\xaf\xaf\xaf\xaf\x4a\x4a\x4a\x4a" + "\x3f\x3e\xaf\xff\xff\xff\x11\xff\xff\xff\xff\xdf\x00\x00\x00\x01" + "\x3f\x7d\x00\x50\x00\x00\xc8\x01\x2b\x60\xc8\x00\x24\x06\xff\xff" + "\x4a\x4e\x4a\x7d\xc8\x01\xf1\x2b\x28\xb2\xb2\x60\x25\xc8\x06\x00" + "\x00\x00\x31\x00\x01\xb2\xb2\xb2\xff\xff\xfd\xb2\xb2\x40\xff\x7d" + "\x3b\x34\x3e\xff\xff\x4a\x4a\x01\xf1\xff\x02\xff\x3f\xff\x02\xff" + "\xff\xff\xbf\x0a\xff\x00\x01\x3f\xb3\xff\x26\x00\x00\x13\x00\xc8" + "\x3e\x3e\x3e\x4a\x76\x4a\x4a\x2e\x7d\x3e\x3e\x3e\x3e\x1d\x1d\x1d" + "\xfe\xea\xef\x80\x01\x00\x00\x40\x00\x00\xba\x00\x06\xfa\xb9\x11" + "\xbf\x98\xee\x45\x7e\x04\x00\xff\xff\xff\x67\xc3\xc3\xc3\xc3\x00" + "\x1d\x1d\xe1\xe3\x00\xc3\x1d\x98\x1d\x1d\x1d\x1d\x1d\x00\x00\x00" + "\x02\x00\x00\x00\xe8\x00\x00\x1d\x1d\x1d\xfa\x1e\x12\xff\xff\xff" + "\x00\x01\xa7\xff\xff\xff\x1d\x1d\x1d\x63\xff\xff\xff\x1f\x00\x00" + "\x10\x40\x00\x00\xad\xff\xff\x3f\x51\x00\xf8\xff\xff\x8a\x01\x05" + "\x00\x00\x03\x00\x00\xff\x00\x00\x00\x05\x40\x1f\x08\x0a\x00\xff" + "\xff\x01\x00\x12\x00\x00\x01\x00\x3f\x40\x1d\x1d\x1d\x1d\x1d\x1d" + "\x21\x00\x1d\x00\x00\x00\xe4\x00\x00\x00\x07\x00\x00\xe6\xe6\x34" + "\xe6\xe6\xe6\xe6\xff\x2b\xee\x1d\x1d\x1d\x93\x1d\x1d\x1d\xee\x2b" + "\xee\x01\x81\x1d\x00\x00\x58\x00\x00\x01\x14\x00\x1b\x00\x00\x2c" + "\x00\x00\x00\xdb\x00\x45\x7e\x00\x00\x00\xfb\xbd\x00\x06\x21\xd3" + "\x00\xff\xff\xff\xff\xff\x00\x49\x49\xc9\x49\x3d\x00\x34\x01\x00" + "\x00\x6a\x2b\x00\x00\x50\x40\xf0\xf0\xf0\xf0\xa3\xa3\xa3\xa3\xf0" + "\xf0\x06\xfa\xa9\x01\x10\xbf\x98\x9d\x2b\xee\x2d\x21\x01\xdb\x00" + "\x45\x10\x00\x00\x7e\x00\x00\xe7\x00\xff\xff\x00\xf6\x00\x00\x00" + "\xf9\x00\x00\x00\x11\x00\x00\x00\xe2\x00\x00\x00\x2d\x00\x00\x00" + "\x2f\x00\x3f\x54\x1d\x1d\x1d\x4c\x4c\x4c\x4c\x2a\x4c\x4c\x10\xff" + "\xff\x1a\x00\x00\x01\xff\x00\xff\xf9\x00\x3f\x53\xcc\xcc\xcc\xcc" + "\x6e\x00\x00\x01\xf8\xff\xff\xff\x49\x04\x2c\x01\x00\x1d\x00\x07" + "\x01\xff\x00\x00\x00\xf8\xff\x09\x00\x27\x00\x08\x21\x1c\x00\x00" + "\x00\x00\x1d\x05\x00\x00\x00\x2c\x53\x3f\x00\x01\x00\x00\xe6\xff" + "\xff\xff\x6a\x2b\xee\xe6\x6a\x2b\xee\x2b\xee\xee\x2b\xee"; + strm.next_in = next_in; + unsigned char next_out[1116]; + strm.next_out = next_out; + + strm.avail_in = sizeof(next_in); + while (1) { + strm.avail_out = (uint32_t)(next_out + sizeof(next_out) - strm.next_out); + if (strm.avail_out > 38) + strm.avail_out = 38; + err = PREFIX(deflate)(&strm, Z_FINISH); + if (err == Z_STREAM_END) + break; + EXPECT_EQ(err, Z_OK); + } + uint32_t compressed_size = (uint32_t)(strm.next_out - next_out); + + err = PREFIX(deflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + memset(&strm, 0, sizeof(strm)); + err = PREFIX(inflateInit2)(&strm, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = next_out; + strm.avail_in = compressed_size; + unsigned char uncompressed[sizeof(next_in)]; + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, next_in, sizeof(uncompressed)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_tune.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_tune.cc new file mode 100644 index 000000000..9921ee643 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_deflate_tune.cc @@ -0,0 +1,56 @@ +/* test_deflate_tune.cc - Test deflateTune() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, tune) { + PREFIX3(stream) c_stream; + uint8_t compr[128]; + z_size_t compr_len = sizeof(compr); + int err; + int good_length = 3; + int max_lazy = 5; + int nice_length = 18; + int max_chain = 6; + + memset(&c_stream, 0, sizeof(c_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateTune)(&c_stream, good_length, max_lazy,nice_length, max_chain); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + + /* Finish the stream, still forcing small buffers: */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_dict.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_dict.cc new file mode 100644 index 000000000..af9662e3d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_dict.cc @@ -0,0 +1,96 @@ +/* test_dict.cc - Test deflate() and inflate() with preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +/* Maximum dictionary size, according to inflateGetDictionary() description. */ +#define MAX_DICTIONARY_SIZE 32768 + +static const char dictionary[] = "hello"; + +TEST(dictionary, basic) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + uint32_t dict_adler = 0; + uint8_t check_dict[MAX_DICTIONARY_SIZE]; + uint32_t check_dict_len = 0; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_BEST_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(deflateSetDictionary)(&c_stream, + (const unsigned char *)dictionary, (int)sizeof(dictionary)); + EXPECT_EQ(err, Z_OK); + + dict_adler = c_stream.adler; + c_stream.next_out = compr; + c_stream.avail_out = (uint32_t)compr_len; + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.avail_in = (uint32_t)hello_len; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage garbage garbage"); + + d_stream.next_in = compr; + d_stream.avail_in = (unsigned int)compr_len; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (unsigned int)uncompr_len; + + for (;;) { + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) + break; + if (err == Z_NEED_DICT) { + EXPECT_EQ(d_stream.adler, dict_adler); + err = PREFIX(inflateSetDictionary)(&d_stream, (const unsigned char*)dictionary, + (uint32_t)sizeof(dictionary)); + EXPECT_EQ(d_stream.adler, dict_adler); + } + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateGetDictionary)(&d_stream, NULL, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_GE(check_dict_len, sizeof(dictionary)); +#endif + + err = PREFIX(inflateGetDictionary)(&d_stream, check_dict, &check_dict_len); + EXPECT_EQ(err, Z_OK); +#ifndef S390_DFLTCC_INFLATE + EXPECT_TRUE(memcmp(dictionary, check_dict, sizeof(dictionary)) == 0); +#endif + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(strncmp((char*)uncompr, hello, sizeof(hello)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_gzio.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_gzio.cc new file mode 100644 index 000000000..3cab1dbe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_gzio.cc @@ -0,0 +1,105 @@ +/* test_gzio.cc - Test read/write of .gz files */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define TESTFILE "foo.gz" + +TEST(gzip, readwrite) { +#ifdef NO_GZCOMPRESS + fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n"); + GTEST_SKIP(); +#else + uint8_t compr[128], uncompr[128]; + uint32_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + size_t read; + int64_t pos; + gzFile file; + int err; + + /* Write gz file with test data */ + file = PREFIX(gzopen)(TESTFILE, "wb"); + ASSERT_TRUE(file != NULL); + /* Write hello, hello! using gzputs and gzprintf */ + PREFIX(gzputc)(file, 'h'); + EXPECT_EQ(PREFIX(gzputs)(file, "ello"), 4); + EXPECT_EQ(PREFIX(gzprintf)(file, ", %s!", "hello"), 8); + /* Write string null-teriminator using gzseek */ + EXPECT_GE(PREFIX(gzseek)(file, 1L, SEEK_CUR), 0); + /* Write hello, hello! using gzfwrite using best compression level */ + EXPECT_EQ(PREFIX(gzsetparams)(file, Z_BEST_COMPRESSION, Z_DEFAULT_STRATEGY), Z_OK); + EXPECT_NE(PREFIX(gzfwrite)(hello, hello_len, 1, file), 0UL); + /* Flush compressed bytes to file */ + EXPECT_EQ(PREFIX(gzflush)(file, Z_SYNC_FLUSH), Z_OK); + compr_len = (uint32_t)PREFIX(gzoffset)(file); + EXPECT_GE(compr_len, 0UL); + PREFIX(gzclose)(file); + + /* Open gz file we previously wrote */ + file = PREFIX(gzopen)(TESTFILE, "rb"); + ASSERT_TRUE(file != NULL); + + /* Read uncompressed data - hello, hello! string twice */ + strcpy((char*)uncompr, "garbages"); + EXPECT_EQ(PREFIX(gzread)(file, uncompr, (unsigned)uncompr_len), (int)(hello_len + hello_len)); + EXPECT_STREQ((char*)uncompr, hello); + + /* Check position at the end of the gz file */ + EXPECT_EQ(PREFIX(gzeof)(file), 1); + + /* Seek backwards mid-string and check char reading with gzgetc and gzungetc */ + pos = PREFIX(gzseek)(file, -22L, SEEK_CUR); + EXPECT_EQ(pos, 6); + EXPECT_EQ(PREFIX(gztell)(file), pos); + EXPECT_EQ(PREFIX(gzgetc)(file), ' '); + EXPECT_EQ(PREFIX(gzungetc)(' ', file), ' '); + /* Read first hello, hello! string with gzgets */ + strcpy((char*)uncompr, "garbages"); + PREFIX(gzgets)(file, (char*)uncompr, (int)uncompr_len); + EXPECT_EQ(strlen((char*)uncompr), 7UL); /* " hello!" */ + EXPECT_STREQ((char*)uncompr, hello + 6); + + /* Seek to second hello, hello! string */ + pos = PREFIX(gzseek)(file, 14L, SEEK_SET); + EXPECT_EQ(pos, 14); + EXPECT_EQ(PREFIX(gztell)(file), pos); + + /* Check position not at end of file */ + EXPECT_EQ(PREFIX(gzeof)(file), 0); + /* Read first hello, hello! string with gzfread */ + strcpy((char*)uncompr, "garbages"); + read = PREFIX(gzfread)(uncompr, uncompr_len, 1, file); + EXPECT_STREQ((const char *)uncompr, hello); + + pos = PREFIX(gzoffset)(file); + EXPECT_GE(pos, 0); + EXPECT_EQ(pos, (compr_len + 10)); + + /* Trigger an error and clear it with gzclearerr */ + PREFIX(gzfread)(uncompr, (size_t)-1, (size_t)-1, file); + PREFIX(gzerror)(file, &err); + EXPECT_NE(err, 0); + + PREFIX(gzclearerr)(file); + PREFIX(gzerror)(file, &err); + EXPECT_EQ(err, 0); + + PREFIX(gzclose)(file); + + EXPECT_EQ(PREFIX(gzclose)(NULL), Z_STREAM_ERROR); + Z_UNUSED(read); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_adler32.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_adler32.cc new file mode 100644 index 000000000..fb78bb1bf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_adler32.cc @@ -0,0 +1,50 @@ +/* GH-1066 - inflate small amount of data and validate with adler32 checksum. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include + +#include "test_shared.h" + +#include + +const char* original = "The quick brown fox jumped over the lazy dog"; + +z_const unsigned char compressed[] = { + 0x78, 0x9c, 0x0b, 0xc9, 0x48, 0x55, 0x28, 0x2c, 0xcd, 0x4c, 0xce, 0x56, 0x48, + 0x2a, 0xca, 0x2f, 0xcf, 0x53, 0x48, 0xcb, 0xaf, 0x50, 0xc8, 0x2a, 0xcd, 0x2d, + 0x48, 0x4d, 0x51, 0xc8, 0x2f, 0x4b, 0x2d, 0x52, 0x28, 0xc9, 0x48, 0x55, 0xc8, + 0x49, 0xac, 0xaa, 0x54, 0x48, 0xc9, 0x4f, 0x07, 0x00, 0x6b, 0x93, 0x10, 0x30 +}; + +TEST(inflate, adler32) { + unsigned char uncompressed[1024]; + PREFIX3(stream) strm; + + memset(&strm, 0, sizeof(strm)); + + int err = PREFIX(inflateInit2)(&strm, 32 + MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + strm.next_in = compressed; + strm.avail_in = sizeof(compressed); + strm.next_out = uncompressed; + strm.avail_out = sizeof(uncompressed); + + err = PREFIX(inflate)(&strm, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + EXPECT_EQ(strm.adler, 0x6b931030); + + err = PREFIX(inflateEnd)(&strm); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(uncompressed, original, MIN(strm.total_out, strlen(original))) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_sync.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_sync.cc new file mode 100644 index 000000000..a79d867e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_inflate_sync.cc @@ -0,0 +1,75 @@ +/* test_inflate_sync.cc - Test inflateSync using full flush deflate and corrupted data */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(inflate, sync) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + + /* build compressed stream with full flush */ + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + c_stream.avail_in = 3; + c_stream.avail_out = (uint32_t)compr_len; + + err = PREFIX(deflate)(&c_stream, Z_FULL_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* force an error in first compressed block */ + compr[3]++; + c_stream.avail_in = hello_len-3; + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + compr_len = (z_size_t)c_stream.total_out; + + memset(&d_stream, 0, sizeof(d_stream)); + /* just read the zlib header */ + d_stream.next_in = compr; + d_stream.avail_in = 2; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_out = uncompr; + d_stream.avail_out = (uint32_t)uncompr_len; + + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + + /* read all compressed data, but skip damaged part */ + d_stream.avail_in = (uint32_t)compr_len-2; + err = PREFIX(inflateSync)(&d_stream); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflate)(&d_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_large_buffers.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_large_buffers.cc new file mode 100644 index 000000000..3c1208140 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_large_buffers.cc @@ -0,0 +1,87 @@ +/* test_large_buffers.cc - Test deflate() and inflate() with large buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include +#include + +#include + +#include "test_shared.h" + +#define COMPR_BUFFER_SIZE (48 * 1024) +#define UNCOMPR_BUFFER_SIZE (32 * 1024) +#define UNCOMPR_RAND_SIZE (8 * 1024) + +TEST(deflate, large_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t *compr, *uncompr; + uint32_t compr_len, uncompr_len; + int32_t i; + time_t now; + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + compr = (uint8_t *)calloc(1, COMPR_BUFFER_SIZE); + ASSERT_TRUE(compr != NULL); + uncompr = (uint8_t *)calloc(1, UNCOMPR_BUFFER_SIZE); + ASSERT_TRUE(uncompr != NULL); + + compr_len = COMPR_BUFFER_SIZE; + uncompr_len = UNCOMPR_BUFFER_SIZE; + + srand((unsigned)time(&now)); + for (i = 0; i < UNCOMPR_RAND_SIZE; i++) + uncompr[i] = (uint8_t)(rand() % 256); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_out = compr; + c_stream.avail_out = compr_len; + c_stream.next_in = uncompr; + c_stream.avail_in = uncompr_len; + + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + EXPECT_EQ(c_stream.avail_in, 0); + + err = PREFIX(deflate)(&c_stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + d_stream.next_in = compr; + d_stream.avail_in = compr_len; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + for (;;) { + d_stream.next_out = uncompr; /* discard the output */ + d_stream.avail_out = uncompr_len; + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_EQ(d_stream.total_out, uncompr_len); + + free(compr); + free(uncompr); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_main.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_main.cc new file mode 100644 index 000000000..82b39e487 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_main.cc @@ -0,0 +1,19 @@ +/* test_test.cc - Main entry point for test framework */ + +#include + +#include "gtest/gtest.h" + +extern "C" { +# include "zbuild.h" +# include "test_cpu_features.h" + + struct cpu_features test_cpu_features; +} + +GTEST_API_ int main(int argc, char **argv) { + printf("Running main() from %s\n", __FILE__); + cpu_check_features(&test_cpu_features); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_raw.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_raw.cc new file mode 100644 index 000000000..a013d4bb4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_raw.cc @@ -0,0 +1,58 @@ +/* test_raw.cc - Test raw streams. */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(raw, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[512]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_SPEED, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + stream.adler = 0x12345678; + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x12345678); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -MAX_WBITS); + EXPECT_EQ(err, Z_OK); + + stream.adler = 0x87654321; + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + EXPECT_EQ(stream.adler, 0x87654321); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared.h b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared.h new file mode 100644 index 000000000..616f57342 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared.h @@ -0,0 +1,18 @@ +#ifndef TEST_SHARED_H +#define TEST_SHARED_H + +/* Test definitions that can be used in the original zlib build environment. */ + +/* "hello world" would be more standard, but the repeated "hello" + * stresses the compression code better, sorry... + */ +static const char hello[] = "hello, hello!"; +static const int hello_len = sizeof(hello); + +/* Clang static analyzer doesn't understand googletest's ASSERT_TRUE, so we need to tell that it's like assert() */ +#ifdef __clang_analyzer__ +# undef ASSERT_TRUE +# define ASSERT_TRUE assert +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared_ng.h b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared_ng.h new file mode 100644 index 000000000..81e451998 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_shared_ng.h @@ -0,0 +1,23 @@ +#ifndef TEST_SHARED_NG_H +#define TEST_SHARED_NG_H + +#include "test_shared.h" + +/* Test definitions that can only be used in the zlib-ng build environment. */ + +static inline int deflate_prime_32(PREFIX3(stream) *stream, uint32_t value) { + int err; + +#ifdef ZLIBNG_ENABLE_TESTS + err = PREFIX(deflatePrime)(stream, 32, value); +#else + /* zlib's deflatePrime() takes at most 16 bits */ + err = PREFIX(deflatePrime)(stream, 16, value & 0xffff); + if (err != Z_OK) return err; + err = PREFIX(deflatePrime)(stream, 16, value >> 16); +#endif + + return err; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_buffers.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_buffers.cc new file mode 100644 index 000000000..bb3449fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_buffers.cc @@ -0,0 +1,69 @@ +/* test_small_buffers.cc - Test deflate() and inflate() with small buffers */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(deflate, small_buffers) { + PREFIX3(stream) c_stream, d_stream; + uint8_t compr[128], uncompr[128]; + z_size_t compr_len = sizeof(compr), uncompr_len = sizeof(uncompr); + int err; + + memset(&c_stream, 0, sizeof(c_stream)); + memset(&d_stream, 0, sizeof(d_stream)); + + err = PREFIX(deflateInit)(&c_stream, Z_DEFAULT_COMPRESSION); + EXPECT_EQ(err, Z_OK); + + c_stream.next_in = (z_const unsigned char *)hello; + c_stream.next_out = compr; + + while (c_stream.total_in != hello_len && c_stream.total_out < compr_len) { + c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(deflate)(&c_stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_OK); + } + /* Finish the stream, still forcing small buffers */ + for (;;) { + c_stream.avail_out = 1; + err = PREFIX(deflate)(&c_stream, Z_FINISH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(deflateEnd)(&c_stream); + EXPECT_EQ(err, Z_OK); + + strcpy((char*)uncompr, "garbage"); + + d_stream.next_in = compr; + d_stream.next_out = uncompr; + + err = PREFIX(inflateInit)(&d_stream); + EXPECT_EQ(err, Z_OK); + + while (d_stream.total_out < uncompr_len && d_stream.total_in < compr_len) { + d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */ + err = PREFIX(inflate)(&d_stream, Z_NO_FLUSH); + if (err == Z_STREAM_END) break; + EXPECT_EQ(err, Z_OK); + } + + err = PREFIX(inflateEnd)(&d_stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_STREQ((char*)uncompr, hello); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_window.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_window.cc new file mode 100644 index 000000000..e351efac0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_small_window.cc @@ -0,0 +1,67 @@ +/* test_small_window.cc - Test deflate() and inflate() with a small window and a preset dictionary */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include + +TEST(small_window, basic) { + PREFIX3(stream) stream; + int err; + unsigned char plain[128]; + unsigned char dictionary1[(1 << 9) - sizeof(plain) / 2]; + size_t i; + unsigned char compr[sizeof(plain)]; + unsigned int compr_len; + unsigned char plain_again[sizeof(plain)]; + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(deflateInit2)(&stream, Z_BEST_COMPRESSION, Z_DEFLATED, -9, 8, Z_DEFAULT_STRATEGY); + EXPECT_EQ(err, Z_OK); + + /* Use a large dictionary that is loaded in two parts */ + memset(dictionary1, 'a', sizeof(dictionary1)); + err = PREFIX(deflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + for (i = 0; i < sizeof(plain); i++) + plain[i] = (unsigned char)i; + err = PREFIX(deflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = plain; + stream.avail_in = (uint32_t)sizeof(plain); + stream.next_out = compr; + stream.avail_out = (uint32_t)sizeof(compr); + err = PREFIX(deflate)(&stream, Z_FINISH); + EXPECT_EQ(err, Z_STREAM_END); + compr_len = sizeof(compr) - stream.avail_out; + + err = PREFIX(deflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + memset(&stream, 0, sizeof(stream)); + err = PREFIX(inflateInit2)(&stream, -9); + EXPECT_EQ(err, Z_OK); + + err = PREFIX(inflateSetDictionary)(&stream, dictionary1, (unsigned int)sizeof(dictionary1)); + EXPECT_EQ(err, Z_OK); + err = PREFIX(inflateSetDictionary)(&stream, plain, (unsigned int)sizeof(plain)); + EXPECT_EQ(err, Z_OK); + + stream.next_in = compr; + stream.avail_in = compr_len; + stream.next_out = plain_again; + stream.avail_out = (unsigned int)sizeof(plain_again); + + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + EXPECT_EQ(err, Z_STREAM_END); + + err = PREFIX(inflateEnd)(&stream); + EXPECT_EQ(err, Z_OK); + + EXPECT_TRUE(memcmp(plain_again, plain, sizeof(plain)) == 0); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/test/test_version.cc b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_version.cc new file mode 100644 index 000000000..fda87904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/test/test_version.cc @@ -0,0 +1,27 @@ +/* test_version.cc - Test zVersion() and zlibCompileFlags() */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +#include +#include +#include +#include + +#include "test_shared.h" + +#include + +TEST(version, basic) { + static const char *my_version = PREFIX2(VERSION); + + EXPECT_EQ(zVersion()[0], my_version[0]); + EXPECT_STREQ(zVersion(), PREFIX2(VERSION)); + + printf("zlib-ng version %s = 0x%08lx, compile flags = 0x%lx\n", + ZLIBNG_VERSION, ZLIBNG_VERNUM, PREFIX(zlibCompileFlags)()); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/tools/config.sub b/internal-complibs/zlib-ng-2.1.0-beta1/tools/config.sub new file mode 100755 index 000000000..dba175ae3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/tools/config.sub @@ -0,0 +1,17 @@ +#!/bin/sh +# Canonicalize CHOST. +# In particular, converts Debian multiarch tuples into GNU triplets. +# See also +# https://wiki.debian.org/Multiarch/Tuples +# https://wiki.gentoo.org/wiki/CHOST +# If you need an architecture not listed here, file a bug at github.com/zlib-ng/zlib-ng +# and work around the problem by dropping libtool's much more comprehensive config.sub +# on top of this file, see +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +case "$1" in +*-*-linux-gnu*) echo $1;; +i686-linux-gnu*|x86_64-linux-gnu*) echo $1 | sed 's/-linux-gnu/-pc-linux-gnu/';; +*-linux-gnu*) echo $1 | sed 's/-linux-gnu/-unknown-linux-gnu/';; +*) echo $1;; +esac diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/tools/makecrct.c b/internal-complibs/zlib-ng-2.1.0-beta1/tools/makecrct.c new file mode 100644 index 000000000..5c3ba58a1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/tools/makecrct.c @@ -0,0 +1,250 @@ +/* makecrct.c -- output crc32 tables + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#include +#include +#include "zbuild.h" +#include "zutil.h" + +/* + The crc32 table header file contains tables for both 32-bit and 64-bit + z_word_t's, and so requires a 64-bit type be available. In that case, + z_word_t must be defined to be 64-bits. This code then also generates + and writes out the tables for the case that z_word_t is 32 bits. +*/ + +#define W 8 /* Need a 64-bit integer type in order to generate crc32 tables. */ + +#include "crc32_braid_p.h" + +static uint32_t crc_table[256]; +static z_word_t crc_big_table[256]; + +static uint32_t crc_braid_table[W][256]; +static z_word_t crc_braid_big_table[W][256]; +static uint32_t x2n_table[32]; + +#include "crc32_braid_comb_p.h" + +static void make_crc_table(void); +static void print_crc_table(void); + +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w); + +static void write_table(const uint32_t *table, int k); +static void write_table32hi(const z_word_t *table, int k); +static void write_table64(const z_word_t *table, int k); + +/* ========================================================================= */ +/* + Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. + + Polynomials over GF(2) are represented in binary, one bit per coefficient, + with the lowest powers in the most significant bit. Then adding polynomials + is just exclusive-or, and multiplying a polynomial by x is a right shift by + one. If we call the above polynomial p, and represent a byte as the + polynomial q, also with the lowest power in the most significant bit (so the + byte 0xb1 is the polynomial x^7+x^3+x^2+1), then the CRC is (q*x^32) mod p, + where a mod b means the remainder after dividing a by b. + + This calculation is done using the shift-register method of multiplying and + taking the remainder. The register is initialized to zero, and for each + incoming bit, x^32 is added mod p to the register if the bit is a one (where + x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by x + (which is shifting right by one and adding x^32 mod p if the bit shifted out + is a one). We start with the highest power (least significant bit) of q and + repeat for all eight bits of q. + + The table is simply the CRC of all possible eight bit values. This is all the + information needed to generate CRCs on data a byte at a time for all + combinations of CRC register values and incoming bytes. +*/ +static void make_crc_table(void) { + unsigned i, j, n; + uint32_t p; + + /* initialize the CRC of bytes tables */ + for (i = 0; i < 256; i++) { + p = i; + for (j = 0; j < 8; j++) + p = p & 1 ? (p >> 1) ^ POLY : p >> 1; + crc_table[i] = p; + crc_big_table[i] = ZSWAP64(p); + } + + /* initialize the x^2^n mod p(x) table */ + p = (uint32_t)1 << 30; /* x^1 */ + x2n_table[0] = p; + for (n = 1; n < 32; n++) + x2n_table[n] = p = multmodp(p, p); + + /* initialize the braiding tables -- needs x2n_table[] */ + braid(crc_braid_table, crc_braid_big_table, N, W); +} + +/* + Generate the little and big-endian braid tables for the given n and z_word_t + size w. Each array must have room for w blocks of 256 elements. + */ +static void braid(uint32_t ltl[][256], z_word_t big[][256], int n, int w) { + int k; + uint32_t i, p, q; + for (k = 0; k < w; k++) { + p = x2nmodp(((z_off64_t)n * w + 3 - k) << 3, 0); + ltl[k][0] = 0; + big[w - 1 - k][0] = 0; + for (i = 1; i < 256; i++) { + ltl[k][i] = q = multmodp(i << 24, p); + big[w - 1 - k][i] = ZSWAP64(q); + } + } +} + +/* + Write the 32-bit values in table[0..k-1] to out, five per line in + hexadecimal separated by commas. + */ +static void write_table(const uint32_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n]), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the high 32-bits of each value in table[0..k-1] to out, five per line + in hexadecimal separated by commas. + */ +static void write_table32hi(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%08" PRIx32 "%s", n == 0 || n % 5 ? "" : " ", + (uint32_t)(table[n] >> 32), + n == k - 1 ? "" : (n % 5 == 4 ? ",\n" : ", ")); +} + +/* + Write the 64-bit values in table[0..k-1] to out, three per line in + hexadecimal separated by commas. This assumes that if there is a 64-bit + type, then there is also a long long integer type, and it is at least 64 + bits. If not, then the type cast and format string can be adjusted + accordingly. + */ +static void write_table64(const z_word_t *table, int k) { + int n; + + for (n = 0; n < k; n++) + printf("%s0x%016" PRIx64 "%s", n == 0 || n % 3 ? "" : " ", + (uint64_t)(table[n]), + n == k - 1 ? "" : (n % 3 == 2 ? ",\n" : ", ")); +} + +static void print_crc_table(void) { + int k, n; + uint32_t ltl[8][256]; + z_word_t big[8][256]; + + printf("#ifndef CRC32_BRAID_TBL_H_\n"); + printf("#define CRC32_BRAID_TBL_H_\n\n"); + printf("/* crc32_braid_tbl.h -- tables for braided CRC calculation\n"); + printf(" * Generated automatically by makecrct.c\n */\n\n"); + + /* print little-endian CRC table */ + printf("static const uint32_t crc_table[] = {\n"); + printf(" "); + write_table(crc_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 64-bit z_word_t */ + printf("#ifdef W\n\n"); + printf("#if W == 8\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table64(crc_big_table, 256); + printf("};\n\n"); + + /* print big-endian CRC table for 32-bit z_word_t */ + printf("#else /* W == 4 */\n\n"); + printf("static const z_word_t crc_big_table[] = {\n"); + printf(" "); + write_table32hi(crc_big_table, 256); + printf("};\n\n"); + printf("#endif\n\n"); + printf("#endif /* W */\n\n"); + + /* write out braid tables for each value of N */ + for (n = 1; n <= 6; n++) { + printf("#if N == %d\n", n); + + /* compute braid tables for this N and 64-bit word_t */ + braid(ltl, big, n, 8); + + /* write out braid tables for 64-bit z_word_t */ + printf("\n"); + printf("#if W == 8\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 8; k++) { + printf(" {"); + write_table64(big[k], 256); + printf("}%s", k < 7 ? ",\n" : ""); + } + printf("};\n"); + + /* compute braid tables for this N and 32-bit word_t */ + braid(ltl, big, n, 4); + + /* write out braid tables for 32-bit z_word_t */ + printf("\n"); + printf("#else /* W == 4 */\n\n"); + printf("static const uint32_t crc_braid_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table(ltl[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("static const z_word_t crc_braid_big_table[][256] = {\n"); + for (k = 0; k < 4; k++) { + printf(" {"); + write_table32hi(big[k], 256); + printf("}%s", k < 3 ? ",\n" : ""); + } + printf("};\n\n"); + printf("#endif /* W */\n\n"); + + printf("#endif /* N == %d */\n", n); + } + printf("\n"); + + /* write out zeros operator table */ + printf("static const uint32_t x2n_table[] = {\n"); + printf(" "); + write_table(x2n_table, 32); + printf("};\n"); + + printf("\n"); + printf("#endif /* CRC32_BRAID_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate crc32 tables +int main(int argc, char *argv[]) { + Z_UNUSED(argc); + Z_UNUSED(argv); + + make_crc_table(); + print_crc_table(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/tools/makefixed.c b/internal-complibs/zlib-ng-2.1.0-beta1/tools/makefixed.c new file mode 100644 index 000000000..7fe71e75e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/tools/makefixed.c @@ -0,0 +1,89 @@ +#include +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" + +// Build and return state with length and distance decoding tables and index sizes set to fixed code decoding. +void Z_INTERNAL buildfixedtables(struct inflate_state *state) { + static code *lenfix, *distfix; + static code fixed[544]; + + // build fixed huffman tables + unsigned sym, bits; + static code *next; + + // literal/length table + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + zng_inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + + // distance table + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + zng_inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; +} + + +// Create fixed tables on the fly and write out a inffixed_tbl.h file that is #include'd above. +// makefixed() writes those tables to stdout, which would be piped to inffixed_tbl.h. +void makefixed(void) { + unsigned low, size; + struct inflate_state state; + + memset(&state, 0, sizeof(state)); + buildfixedtables(&state); + puts("/* inffixed_tbl.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts("/* WARNING: this file should *not* be used by applications."); + puts(" * It is part of the implementation of this library and is"); + puts(" * subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf("static const code lenfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 7) == 0) + printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); + size = 1U << 5; + printf("\nstatic const code distfix[%u] = {", size); + low = 0; + for (;;) { + if ((low % 6) == 0) + printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, state.distcode[low].val); + if (++low == size) + break; + putchar(','); + } + puts("\n};"); +} + +// The output of this application can be piped out to recreate inffixed_tbl.h +int main(void) { + makefixed(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/tools/maketrees.c b/internal-complibs/zlib-ng-2.1.0-beta1/tools/maketrees.c new file mode 100644 index 000000000..2c32ccae0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/tools/maketrees.c @@ -0,0 +1,147 @@ +/* maketrees.c -- output static huffman trees + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" + +static ct_data static_ltree[L_CODES+2]; +/* The static literal tree. Since the bit lengths are imposed, there is no + * need for the L_CODES extra codes used during heap construction. However + * The codes 286 and 287 are needed to build a canonical tree (see zng_tr_init). + */ + +static ct_data static_dtree[D_CODES]; +/* The static distance tree. (Actually a trivial tree since all codes use 5 bits.) + */ + +static unsigned char dist_code[DIST_CODE_LEN]; +/* Distance codes. The first 256 values correspond to the distances 3 .. 258, + * the last 256 values correspond to the top 8 bits of the 15 bit distances. + */ + +static unsigned char length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; +/* length code for each normalized match length (0 == STD_MIN_MATCH) */ + +static int base_length[LENGTH_CODES]; +/* First normalized length for each code (0 = STD_MIN_MATCH) */ + +static int base_dist[D_CODES]; +/* First normalized distance for each code (0 = distance of 1) */ + + +static void tr_static_init(void) { + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + /* Initialize the mapping length (0..255) -> length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES-1; code++) { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) { + length_code[length++] = (unsigned char)code; + } + } + Assert(length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented in two different + * ways: code 284 + 5 bits or code 285, so we overwrite length_code[255] to use the best encoding: + */ + length_code[length-1] = (unsigned char)code; + + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) { + dist_code[dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for ( ; code < D_CODES; code++) { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code]-7)); n++) { + dist_code[256 + dist++] = (unsigned char)code; + } + } + Assert(dist == 256, "tr_static_init: 256+dist != 512"); + + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) + bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the tree construction + * to get a canonical Huffman tree (longest code all ones) + */ + gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) { + static_dtree[n].Len = 5; + static_dtree[n].Code = PREFIX(bi_reverse)((unsigned)n, 5); + } +} + +# define SEPARATOR(i, last, width) \ + ((i) == (last)? "\n};\n\n" : \ + ((i) % (width) == (width)-1 ? ",\n" : ", ")) + +static void gen_trees_header(void) { + int i; + + printf("#ifndef TREES_TBL_H_\n"); + printf("#define TREES_TBL_H_\n\n"); + + printf("/* header created automatically with maketrees.c */\n\n"); + + printf("Z_INTERNAL const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES+2; i++) { + printf("{{%3u},{%u}}%s", static_ltree[i].Code, static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); + } + + printf("Z_INTERNAL const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("{{%2u},{%u}}%s", static_dtree[i].Code, static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); + } + + printf("const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) { + printf("%2u%s", dist_code[i], SEPARATOR(i, DIST_CODE_LEN-1, 20)); + } + + printf("const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = {\n"); + for (i = 0; i < STD_MAX_MATCH-STD_MIN_MATCH+1; i++) { + printf("%2u%s", length_code[i], SEPARATOR(i, STD_MAX_MATCH-STD_MIN_MATCH, 20)); + } + + printf("Z_INTERNAL const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) { + printf("%d%s", base_length[i], SEPARATOR(i, LENGTH_CODES-1, 20)); + } + + printf("Z_INTERNAL const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) { + printf("%5d%s", base_dist[i], SEPARATOR(i, D_CODES-1, 10)); + } + + printf("#endif /* TREES_TBL_H_ */\n"); +} + +// The output of this application can be piped out to recreate trees.h +int main(void) { + tr_static_init(); + gen_trees_header(); + return 0; +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/trees.c b/internal-complibs/zlib-ng-2.1.0-beta1/trees.c new file mode 100644 index 000000000..5bb88389b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/trees.c @@ -0,0 +1,818 @@ +/* trees.c -- output deflated data using Huffman coding + * Copyright (C) 1995-2021 Jean-loup Gailly + * detect_data_type() function provided freely by Cosmin Truta, 2006 + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process uses several Huffman trees. The more + * common source values are represented by shorter bit sequences. + * + * Each code tree is stored in a compressed form which is itself + * a Huffman encoding of the lengths of all the code strings (in + * ascending order by source values). The actual code strings are + * reconstructed from the lengths in the inflate process, as described + * in the deflate specification. + * + * REFERENCES + * + * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". + * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc + * + * Storer, James A. + * Data Compression: Methods and Theory, pp. 49-50. + * Computer Science Press, 1988. ISBN 0-7167-8156-5. + * + * Sedgewick, R. + * Algorithms, p290. + * Addison-Wesley, 1983. ISBN 0-201-06672-6. + */ + +#include "zbuild.h" +#include "deflate.h" +#include "trees.h" +#include "trees_emit.h" +#include "trees_tbl.h" + +/* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + +/* =========================================================================== + * Local data. These are initialized only once. + */ + +struct static_tree_desc_s { + const ct_data *static_tree; /* static tree or NULL */ + const int *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + unsigned int max_length; /* max bit length for the codes */ +}; + +static const static_tree_desc static_l_desc = +{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; + +static const static_tree_desc static_d_desc = +{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; + +static const static_tree_desc static_bl_desc = +{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; + +/* =========================================================================== + * Local (static) routines in this file. + */ + +static void init_block (deflate_state *s); +static void pqdownheap (deflate_state *s, ct_data *tree, int k); +static void gen_bitlen (deflate_state *s, tree_desc *desc); +static void build_tree (deflate_state *s, tree_desc *desc); +static void scan_tree (deflate_state *s, ct_data *tree, int max_code); +static void send_tree (deflate_state *s, ct_data *tree, int max_code); +static int build_bl_tree (deflate_state *s); +static void send_all_trees (deflate_state *s, int lcodes, int dcodes, int blcodes); +static void compress_block (deflate_state *s, const ct_data *ltree, const ct_data *dtree); +static int detect_data_type (deflate_state *s); +static void bi_flush (deflate_state *s); + +/* =========================================================================== + * Initialize the tree data structures for a new zlib stream. + */ +void Z_INTERNAL zng_tr_init(deflate_state *s) { + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; + + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; + + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; + + s->bi_buf = 0; + s->bi_valid = 0; +#ifdef ZLIB_DEBUG + s->compressed_len = 0L; + s->bits_sent = 0L; +#endif + + /* Initialize the first block of the first file: */ + init_block(s); +} + +/* =========================================================================== + * Initialize a new block. + */ +static void init_block(deflate_state *s) { + int n; /* iterates over tree elements */ + + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) + s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) + s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) + s->bl_tree[n].Freq = 0; + + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->sym_next = s->matches = 0; +} + +#define SMALLEST 1 +/* Index within the heap array of least frequent node in the Huffman tree */ + + +/* =========================================================================== + * Remove the smallest element from the heap and recreate the heap with + * one less element. Updates heap and heap_len. + */ +#define pqremove(s, tree, top) \ +{\ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ +} + +/* =========================================================================== + * Compares to subtrees, using the tree depth as tie breaker when + * the subtrees have equal frequency. This minimizes the worst case length. + */ +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) + +/* =========================================================================== + * Restore the heap property by moving down the tree starting at node k, + * exchanging a node with the smallest of its two sons if necessary, stopping + * when the heap property is re-established (each father smaller than its + * two sons). + */ +static void pqdownheap(deflate_state *s, ct_data *tree, int k) { + /* tree: the tree to restore */ + /* k: node to move down */ + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) + break; + + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; + k = j; + + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; +} + +/* =========================================================================== + * Compute the optimal bit lengths for a tree and update the total bit length + * for the current block. + * IN assertion: the fields freq and dad are set, heap[heap_max] and + * above are the tree nodes sorted by increasing frequency. + * OUT assertions: the field len is set to the optimal bit length, the + * array bl_count contains the frequencies for each bit length. + * The length opt_len is updated; static_len is also updated if stree is + * not null. + */ +static void gen_bitlen(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const int *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + unsigned int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + unsigned int bits; /* bit length */ + int xbits; /* extra bits */ + uint16_t f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ + + for (bits = 0; bits <= MAX_BITS; bits++) + s->bl_count[bits] = 0; + + /* In a first pass, compute the optimal bit lengths (which may + * overflow in the case of the bit length tree). + */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1u; + if (bits > max_length){ + bits = max_length; + overflow++; + } + tree[n].Len = (uint16_t)bits; + /* We overwrite tree[n].Dad which is no longer needed */ + + if (n > max_code) /* not a leaf node */ + continue; + + s->bl_count[bits]++; + xbits = 0; + if (n >= base) + xbits = extra[n-base]; + f = tree[n].Freq; + s->opt_len += (unsigned long)f * (unsigned int)(bits + xbits); + if (stree) + s->static_len += (unsigned long)f * (unsigned int)(stree[n].Len + xbits); + } + if (overflow == 0) + return; + + Tracev((stderr, "\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ + + /* Find the first bit length which could increase: */ + do { + bits = max_length - 1; + while (s->bl_count[bits] == 0) + bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits+1] += 2u; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, + * but this does not affect bl_count[max_length] + */ + overflow -= 2; + } while (overflow > 0); + + /* Now recompute all bit lengths, scanning in increasing frequency. + * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all + * lengths instead of fixing only the wrong ones. This idea is taken + * from 'ar' written by Haruhiko Okumura.) + */ + for (bits = max_length; bits != 0; bits--) { + n = s->bl_count[bits]; + while (n != 0) { + m = s->heap[--h]; + if (m > max_code) + continue; + if (tree[m].Len != bits) { + Tracev((stderr, "code %d bits %d->%u\n", m, tree[m].Len, bits)); + s->opt_len += (unsigned long)(bits * tree[m].Freq); + s->opt_len -= (unsigned long)(tree[m].Len * tree[m].Freq); + tree[m].Len = (uint16_t)bits; + } + n--; + } + } +} + +/* =========================================================================== + * Generate the codes for a given tree and bit counts (which need not be + * optimal). + * IN assertion: the array bl_count contains the bit length statistics for + * the given tree and the field len is set for all tree elements. + * OUT assertion: the field code is set for all tree elements of non + * zero code length. + */ +Z_INTERNAL void gen_codes(ct_data *tree, int max_code, uint16_t *bl_count) { + /* tree: the tree to decorate */ + /* max_code: largest code with non zero frequency */ + /* bl_count: number of codes at each bit length */ + uint16_t next_code[MAX_BITS+1]; /* next code value for each bit length */ + unsigned int code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ + + /* The distribution counts are first used to generate the code values + * without bit reversal. + */ + for (bits = 1; bits <= MAX_BITS; bits++) { + code = (code + bl_count[bits-1]) << 1; + next_code[bits] = (uint16_t)code; + } + /* Check that the bit counts in bl_count are consistent. The last code + * must be all ones. + */ + Assert(code + bl_count[MAX_BITS]-1 == (1 << MAX_BITS)-1, "inconsistent bit counts"); + Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); + + for (n = 0; n <= max_code; n++) { + int len = tree[n].Len; + if (len == 0) + continue; + /* Now reverse the bits */ + tree[n].Code = PREFIX(bi_reverse)(next_code[len]++, len); + + Tracecv(tree != static_ltree, (stderr, "\nn %3d %c l %2d c %4x (%x) ", + n, (isgraph(n & 0xff) ? n : ' '), len, tree[n].Code, next_code[len]-1)); + } +} + +/* =========================================================================== + * Construct one Huffman tree and assigns the code bit strings and lengths. + * Update the total bit length for the current block. + * IN assertion: the field freq is set for all tree elements. + * OUT assertions: the fields len and code are set to the optimal bit length + * and corresponding code. The length opt_len is updated; static_len is + * also updated if stree is not null. The field max_code is set. + */ +static void build_tree(deflate_state *s, tree_desc *desc) { + /* desc: the tree descriptor */ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ + + /* Construct the initial heap, with least frequent element in + * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. + * heap[0] is not used. + */ + s->heap_len = 0; + s->heap_max = HEAP_SIZE; + + for (n = 0; n < elems; n++) { + if (tree[n].Freq != 0) { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } else { + tree[n].Len = 0; + } + } + + /* The pkzip format requires that at least one distance code exists, + * and that at least one bit should be sent even if there is only one + * possible code. So to avoid special checks later on we force at least + * two codes of non zero frequency. + */ + while (s->heap_len < 2) { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; + if (stree) + s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; + + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + * establish sub-heaps of increasing lengths: + */ + for (n = s->heap_len/2; n >= 1; n--) + pqdownheap(s, tree, n); + + /* Construct the Huffman tree by repeatedly combining the least two + * frequent nodes. + */ + node = elems; /* next internal node of the tree */ + do { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ + + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; + + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (unsigned char)((s->depth[n] >= s->depth[m] ? + s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (uint16_t)node; +#ifdef DUMP_BL_TREE + if (tree == s->bl_tree) { + fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } +#endif + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); + } while (s->heap_len >= 2); + + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + + /* At this point, the fields freq and dad are set. We can now + * generate the bit lengths. + */ + gen_bitlen(s, (tree_desc *)desc); + + /* The field len is now set, we can generate the bit codes */ + gen_codes((ct_data *)tree, max_code, s->bl_count); +} + +/* =========================================================================== + * Scan a literal or distance tree to determine the frequencies of the codes + * in the bit length tree. + */ +static void scan_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code: and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + uint16_t count = 0; /* repeat count of the current code */ + uint16_t max_count = 7; /* max repeat count */ + uint16_t min_count = 4; /* min repeat count */ + + if (nextlen == 0) + max_count = 138, min_count = 3; + + tree[max_code+1].Len = (uint16_t)0xffff; /* guard */ + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + s->bl_tree[curlen].Freq += count; + } else if (curlen != 0) { + if (curlen != prevlen) + s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } else if (count <= 10) { + s->bl_tree[REPZ_3_10].Freq++; + } else { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } +} + +/* =========================================================================== + * Send a literal or distance tree in compressed form, using the codes in + * bl_tree. + */ +static void send_tree(deflate_state *s, ct_data *tree, int max_code) { + /* tree: the tree to be scanned */ + /* max_code and its largest code of non zero frequency */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ + + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) + max_count = 138, min_count = 3; + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + for (n = 0; n <= max_code; n++) { + curlen = nextlen; + nextlen = tree[n+1].Len; + if (++count < max_count && curlen == nextlen) { + continue; + } else if (count < min_count) { + do { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + } while (--count != 0); + + } else if (curlen != 0) { + if (curlen != prevlen) { + send_code(s, curlen, s->bl_tree, bi_buf, bi_valid); + count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 2, bi_buf, bi_valid); + + } else if (count <= 10) { + send_code(s, REPZ_3_10, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-3, 3, bi_buf, bi_valid); + + } else { + send_code(s, REPZ_11_138, s->bl_tree, bi_buf, bi_valid); + send_bits(s, count-11, 7, bi_buf, bi_valid); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) { + max_count = 138, min_count = 3; + } else if (curlen == nextlen) { + max_count = 6, min_count = 3; + } else { + max_count = 7, min_count = 4; + } + } + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; +} + +/* =========================================================================== + * Construct the Huffman tree for the bit lengths and return the index in + * bl_order of the last bit length code to send. + */ +static int build_bl_tree(deflate_state *s) { + int max_blindex; /* index of last bit length code of non zero freq */ + + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except + * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. + */ + + /* Determine the number of bit length codes to send. The pkzip format + * requires that at least 4 bit length codes be sent. (appnote.txt says + * 3 but the actual value used is 4.) + */ + for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) + break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3*((unsigned long)max_blindex+1) + 5+5+4; + Tracev((stderr, "\ndyn trees: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + return max_blindex; +} + +/* =========================================================================== + * Send the header for a block using dynamic Huffman trees: the counts, the + * lengths of the bit length codes, the literal tree and the distance tree. + * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. + */ +static void send_all_trees(deflate_state *s, int lcodes, int dcodes, int blcodes) { + int rank; /* index in bl_order */ + + Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, "too many codes"); + + // Temp local variables + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes-257, 5, bi_buf, bi_valid); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes-1, 5, bi_buf, bi_valid); + send_bits(s, blcodes-4, 4, bi_buf, bi_valid); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) { + Tracev((stderr, "\nbl code %2u ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3, bi_buf, bi_valid); + } + Tracev((stderr, "\nbl tree: sent %lu", s->bits_sent)); + + // Store back temp variables + s->bi_buf = bi_buf; + s->bi_valid = bi_valid; + + send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %lu", s->bits_sent)); + + send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %lu", s->bits_sent)); +} + +/* =========================================================================== + * Send a stored block + */ +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + zng_tr_emit_tree(s, STORED_BLOCK, last); /* send block type */ + zng_tr_emit_align(s); /* align on byte boundary */ + cmpr_bits_align(s); + put_short(s, (uint16_t)stored_len); + put_short(s, (uint16_t)~stored_len); + cmpr_bits_add(s, 32); + sent_bits_add(s, 32); + if (stored_len) { + memcpy(s->pending_buf + s->pending, (unsigned char *)buf, stored_len); + s->pending += stored_len; + cmpr_bits_add(s, stored_len << 3); + sent_bits_add(s, stored_len << 3); + } +} + +/* =========================================================================== + * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) + */ +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s) { + bi_flush(s); +} + +/* =========================================================================== + * Send one empty static block to give enough lookahead for inflate. + * This takes 10 bits, of which 7 may remain in the bit buffer. + */ +void Z_INTERNAL zng_tr_align(deflate_state *s) { + zng_tr_emit_tree(s, STATIC_TREES, 0); + zng_tr_emit_end_block(s, static_ltree, 0); + bi_flush(s); +} + +/* =========================================================================== + * Determine the best encoding for the current block: dynamic trees, static + * trees or store, and write out the encoded block. + */ +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last) { + /* buf: input block, or NULL if too old */ + /* stored_len: length of input block */ + /* last: one if this is the last block for a file */ + unsigned long opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ + + /* Build the Huffman trees unless a stored block is forced */ + if (UNLIKELY(s->sym_next == 0)) { + /* Emit an empty static tree block with no codes */ + opt_lenb = static_lenb = 0; + s->static_len = 7; + } else if (s->level > 0) { + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); + + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %lu, stat %lu", s->opt_len, s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of + * the compressed block data, excluding the tree representations. + */ + + /* Build the bit length tree for the above two trees, and get the index + * in bl_order of the last bit length code to send. + */ + max_blindex = build_bl_tree(s); + + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len+3+7) >> 3; + static_lenb = (s->static_len+3+7) >> 3; + + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %u lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->sym_next / 3)); + + if (static_lenb <= opt_lenb || s->strategy == Z_FIXED) + opt_lenb = static_lenb; + + } else { + Assert(buf != NULL, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } + + if (stored_len+4 <= opt_lenb && buf != NULL) { + /* 4: two words for the lengths + * The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + * Otherwise we can't have processed more than WSIZE input bytes since + * the last block flush, because compression would have been + * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to + * transform a block into a stored block. + */ + zng_tr_stored_block(s, buf, stored_len, last); + + } else if (static_lenb == opt_lenb) { + zng_tr_emit_tree(s, STATIC_TREES, last); + compress_block(s, (const ct_data *)static_ltree, (const ct_data *)static_dtree); + cmpr_bits_add(s, s->static_len); + } else { + zng_tr_emit_tree(s, DYN_TREES, last); + send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, max_blindex+1); + compress_block(s, (const ct_data *)s->dyn_ltree, (const ct_data *)s->dyn_dtree); + cmpr_bits_add(s, s->opt_len); + } + Assert(s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB + * and unsigned long implemented on 32 bits. + */ + init_block(s); + + if (last) { + zng_tr_emit_align(s); + } + Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len>>3, s->compressed_len-7*last)); +} + +/* =========================================================================== + * Send the block data compressed using the given Huffman trees + */ +static void compress_block(deflate_state *s, const ct_data *ltree, const ct_data *dtree) { + /* ltree: literal tree */ + /* dtree: distance tree */ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned sx = 0; /* running index in sym_buf */ + + if (s->sym_next != 0) { + do { + dist = s->sym_buf[sx++] & 0xff; + dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8; + lc = s->sym_buf[sx++]; + if (dist == 0) { + zng_emit_lit(s, ltree, lc); + } else { + zng_emit_dist(s, ltree, dtree, lc, dist); + } /* literal or match pair ? */ + + /* Check that the overlay between pending_buf and sym_buf is ok: */ + Assert(s->pending < s->lit_bufsize + sx, "pending_buf overflow"); + } while (sx < s->sym_next); + } + + zng_emit_end_block(s, ltree, 0); +} + +/* =========================================================================== + * Check if the data type is TEXT or BINARY, using the following algorithm: + * - TEXT if the two conditions below are satisfied: + * a) There are no non-portable control characters belonging to the + * "black list" (0..6, 14..25, 28..31). + * b) There is at least one printable character belonging to the + * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). + * - BINARY otherwise. + * - The following partially-portable control characters form a + * "gray list" that is ignored in this detection algorithm: + * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). + * IN assertion: the fields Freq of dyn_ltree are set. + */ +static int detect_data_type(deflate_state *s) { + /* black_mask is the bit mask of black-listed bytes + * set bits 0..6, 14..25, and 28..31 + * 0xf3ffc07f = binary 11110011111111111100000001111111 + */ + unsigned long black_mask = 0xf3ffc07fUL; + int n; + + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; + + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; + + /* There are no "black-listed" or "white-listed" bytes: + * this stream either is empty or has tolerated ("gray-listed") bytes only. + */ + return Z_BINARY; +} + +/* =========================================================================== + * Flush the bit buffer, keeping at most 7 bits in it. + */ +static void bi_flush(deflate_state *s) { + if (s->bi_valid == 64) { + put_uint64(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } else { + if (s->bi_valid >= 32) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid >= 16) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid >= 8) { + put_byte(s, s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } + } +} + +/* =========================================================================== + * Reverse the first len bits of a code using bit manipulation + */ +Z_INTERNAL uint16_t PREFIX(bi_reverse)(unsigned code, int len) { + /* code: the value to invert */ + /* len: its bit length */ + Assert(len >= 1 && len <= 15, "code length must be 1-15"); +#define bitrev8(b) \ + (uint8_t)((((uint8_t)(b) * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32) + return (bitrev8(code >> 8) | (uint16_t)bitrev8(code) << 8) >> (16 - len); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/trees.h b/internal-complibs/zlib-ng-2.1.0-beta1/trees.h new file mode 100644 index 000000000..e57f92648 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/trees.h @@ -0,0 +1,40 @@ +#ifndef TREES_H_ +#define TREES_H_ + +/* Constants */ + +#define DIST_CODE_LEN 512 +/* see definition of array dist_code in trees.c */ + +#define MAX_BL_BITS 7 +/* Bit length codes must not exceed MAX_BL_BITS bits */ + +#define REP_3_6 16 +/* repeat previous bit length 3-6 times (2 bits of repeat count) */ + +#define REPZ_3_10 17 +/* repeat a zero length 3-10 times (3 bits of repeat count) */ + +#define REPZ_11_138 18 +/* repeat a zero length 11-138 times (7 bits of repeat count) */ + +static const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ + = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + +static const int extra_dbits[D_CODES] /* extra bits for each distance code */ + = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + +static const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ + = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; + +static const unsigned char bl_order[BL_CODES] + = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; + /* The lengths of the bit length codes are sent in order of decreasing + * probability, to avoid transmitting the lengths for unused bit length codes. + */ + + +/* Function definitions */ +void gen_codes (ct_data *tree, int max_code, uint16_t *bl_count); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/trees_emit.h b/internal-complibs/zlib-ng-2.1.0-beta1/trees_emit.h new file mode 100644 index 000000000..922daae50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/trees_emit.h @@ -0,0 +1,227 @@ +#ifndef TREES_EMIT_H_ +#define TREES_EMIT_H_ + +#include "zbuild.h" +#include "trees.h" + +#ifdef ZLIB_DEBUG +# include +# include +#endif + + +/* trees.h */ +extern Z_INTERNAL const ct_data static_ltree[L_CODES+2]; +extern Z_INTERNAL const ct_data static_dtree[D_CODES]; + +extern const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN]; +extern const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1]; + +extern Z_INTERNAL const int base_length[LENGTH_CODES]; +extern Z_INTERNAL const int base_dist[D_CODES]; + +/* Bit buffer and deflate code stderr tracing */ +#ifdef ZLIB_DEBUG +# define send_bits_trace(s, value, length) { \ + Tracevv((stderr, " l %2d v %4llx ", (int)(length), (long long)(value))); \ + Assert(length > 0 && length <= BIT_BUF_SIZE, "invalid length"); \ + } +# define send_code_trace(s, c) \ + if (z_verbose > 2) { \ + fprintf(stderr, "\ncd %3d ", (c)); \ + } +#else +# define send_bits_trace(s, value, length) +# define send_code_trace(s, c) +#endif + +/* If not enough room in bi_buf, use (valid) bits from bi_buf and + * (64 - bi_valid) bits from value, leaving (width - (64-bi_valid)) + * unused bits in value. + */ +#define send_bits(s, t_val, t_len, bi_buf, bi_valid) {\ + uint64_t val = (uint64_t)t_val;\ + uint32_t len = (uint32_t)t_len;\ + uint32_t total_bits = bi_valid + len;\ + send_bits_trace(s, val, len);\ + sent_bits_add(s, len);\ + if (total_bits < BIT_BUF_SIZE) {\ + bi_buf |= val << bi_valid;\ + bi_valid = total_bits;\ + } else if (bi_valid == BIT_BUF_SIZE) {\ + put_uint64(s, bi_buf);\ + bi_buf = val;\ + bi_valid = len;\ + } else {\ + bi_buf |= val << bi_valid;\ + put_uint64(s, bi_buf);\ + bi_buf = val >> (BIT_BUF_SIZE - bi_valid);\ + bi_valid = total_bits - BIT_BUF_SIZE;\ + }\ +} + +/* Send a code of the given tree. c and tree must not have side effects */ +#ifdef ZLIB_DEBUG +# define send_code(s, c, tree, bi_buf, bi_valid) { \ + send_code_trace(s, c); \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid); \ +} +#else +# define send_code(s, c, tree, bi_buf, bi_valid) \ + send_bits(s, tree[c].Code, tree[c].Len, bi_buf, bi_valid) +#endif + +/* =========================================================================== + * Flush the bit buffer and align the output on a byte boundary + */ +static void bi_windup(deflate_state *s) { + if (s->bi_valid > 56) { + put_uint64(s, s->bi_buf); + } else { + if (s->bi_valid > 24) { + put_uint32(s, (uint32_t)s->bi_buf); + s->bi_buf >>= 32; + s->bi_valid -= 32; + } + if (s->bi_valid > 8) { + put_short(s, (uint16_t)s->bi_buf); + s->bi_buf >>= 16; + s->bi_valid -= 16; + } + if (s->bi_valid > 0) { + put_byte(s, s->bi_buf); + } + } + s->bi_buf = 0; + s->bi_valid = 0; +} + +/* =========================================================================== + * Emit literal code + */ +static inline uint32_t zng_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + send_code(s, c, ltree, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + Tracecv(isgraph(c & 0xff), (stderr, " '%c' ", c)); + + return ltree[c].Len; +} + +/* =========================================================================== + * Emit match distance/length code + */ +static inline uint32_t zng_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + uint32_t c, extra; + uint8_t code; + uint64_t match_bits; + uint32_t match_bits_len; + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + + /* Send the length code, len is the match length - STD_MIN_MATCH */ + code = zng_length_code[lc]; + c = code+LITERALS+1; + Assert(c < L_CODES, "bad l_code"); + send_code_trace(s, c); + + match_bits = ltree[c].Code; + match_bits_len = ltree[c].Len; + extra = extra_lbits[code]; + if (extra != 0) { + lc -= base_length[code]; + match_bits |= ((uint64_t)lc << match_bits_len); + match_bits_len += extra; + } + + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert(code < D_CODES, "bad d_code"); + send_code_trace(s, code); + + /* Send the distance code */ + match_bits |= ((uint64_t)dtree[code].Code << match_bits_len); + match_bits_len += dtree[code].Len; + extra = extra_dbits[code]; + if (extra != 0) { + dist -= base_dist[code]; + match_bits |= ((uint64_t)dist << match_bits_len); + match_bits_len += extra; + } + + send_bits(s, match_bits, match_bits_len, bi_buf, bi_valid); + + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + + return match_bits_len; +} + +/* =========================================================================== + * Emit end block + */ +static inline void zng_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + send_code(s, END_BLOCK, ltree, bi_buf, bi_valid); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n+++ Emit End Block: Last: %u Pending: %u Total Out: %" PRIu64 "\n", + last, s->pending, (uint64_t)s->strm->total_out)); + Z_UNUSED(last); +} + +/* =========================================================================== + * Emit literal and count bits + */ +static inline void zng_tr_emit_lit(deflate_state *s, const ct_data *ltree, unsigned c) { + cmpr_bits_add(s, zng_emit_lit(s, ltree, c)); +} + +/* =========================================================================== + * Emit match and count bits + */ +static inline void zng_tr_emit_dist(deflate_state *s, const ct_data *ltree, const ct_data *dtree, + uint32_t lc, uint32_t dist) { + cmpr_bits_add(s, zng_emit_dist(s, ltree, dtree, lc, dist)); +} + +/* =========================================================================== + * Emit start of block + */ +static inline void zng_tr_emit_tree(deflate_state *s, int type, const int last) { + uint32_t bi_valid = s->bi_valid; + uint64_t bi_buf = s->bi_buf; + uint32_t header_bits = (type << 1) + last; + send_bits(s, header_bits, 3, bi_buf, bi_valid); + cmpr_bits_add(s, 3); + s->bi_valid = bi_valid; + s->bi_buf = bi_buf; + Tracev((stderr, "\n--- Emit Tree: Last: %u\n", last)); +} + +/* =========================================================================== + * Align bit buffer on a byte boundary and count bits + */ +static inline void zng_tr_emit_align(deflate_state *s) { + bi_windup(s); /* align on byte boundary */ + sent_bits_align(s); +} + +/* =========================================================================== + * Emit an end block and align bit buffer if last block + */ +static inline void zng_tr_emit_end_block(deflate_state *s, const ct_data *ltree, const int last) { + zng_emit_end_block(s, ltree, last); + cmpr_bits_add(s, 7); + if (last) + zng_tr_emit_align(s); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/trees_tbl.h b/internal-complibs/zlib-ng-2.1.0-beta1/trees_tbl.h new file mode 100644 index 000000000..a3912b7fd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/trees_tbl.h @@ -0,0 +1,132 @@ +#ifndef TREES_TBL_H_ +#define TREES_TBL_H_ + +/* header created automatically with maketrees.c */ + +Z_INTERNAL const ct_data static_ltree[L_CODES+2] = { +{{ 12},{8}}, {{140},{8}}, {{ 76},{8}}, {{204},{8}}, {{ 44},{8}}, +{{172},{8}}, {{108},{8}}, {{236},{8}}, {{ 28},{8}}, {{156},{8}}, +{{ 92},{8}}, {{220},{8}}, {{ 60},{8}}, {{188},{8}}, {{124},{8}}, +{{252},{8}}, {{ 2},{8}}, {{130},{8}}, {{ 66},{8}}, {{194},{8}}, +{{ 34},{8}}, {{162},{8}}, {{ 98},{8}}, {{226},{8}}, {{ 18},{8}}, +{{146},{8}}, {{ 82},{8}}, {{210},{8}}, {{ 50},{8}}, {{178},{8}}, +{{114},{8}}, {{242},{8}}, {{ 10},{8}}, {{138},{8}}, {{ 74},{8}}, +{{202},{8}}, {{ 42},{8}}, {{170},{8}}, {{106},{8}}, {{234},{8}}, +{{ 26},{8}}, {{154},{8}}, {{ 90},{8}}, {{218},{8}}, {{ 58},{8}}, +{{186},{8}}, {{122},{8}}, {{250},{8}}, {{ 6},{8}}, {{134},{8}}, +{{ 70},{8}}, {{198},{8}}, {{ 38},{8}}, {{166},{8}}, {{102},{8}}, +{{230},{8}}, {{ 22},{8}}, {{150},{8}}, {{ 86},{8}}, {{214},{8}}, +{{ 54},{8}}, {{182},{8}}, {{118},{8}}, {{246},{8}}, {{ 14},{8}}, +{{142},{8}}, {{ 78},{8}}, {{206},{8}}, {{ 46},{8}}, {{174},{8}}, +{{110},{8}}, {{238},{8}}, {{ 30},{8}}, {{158},{8}}, {{ 94},{8}}, +{{222},{8}}, {{ 62},{8}}, {{190},{8}}, {{126},{8}}, {{254},{8}}, +{{ 1},{8}}, {{129},{8}}, {{ 65},{8}}, {{193},{8}}, {{ 33},{8}}, +{{161},{8}}, {{ 97},{8}}, {{225},{8}}, {{ 17},{8}}, {{145},{8}}, +{{ 81},{8}}, {{209},{8}}, {{ 49},{8}}, {{177},{8}}, {{113},{8}}, +{{241},{8}}, {{ 9},{8}}, {{137},{8}}, {{ 73},{8}}, {{201},{8}}, +{{ 41},{8}}, {{169},{8}}, {{105},{8}}, {{233},{8}}, {{ 25},{8}}, +{{153},{8}}, {{ 89},{8}}, {{217},{8}}, {{ 57},{8}}, {{185},{8}}, +{{121},{8}}, {{249},{8}}, {{ 5},{8}}, {{133},{8}}, {{ 69},{8}}, +{{197},{8}}, {{ 37},{8}}, {{165},{8}}, {{101},{8}}, {{229},{8}}, +{{ 21},{8}}, {{149},{8}}, {{ 85},{8}}, {{213},{8}}, {{ 53},{8}}, +{{181},{8}}, {{117},{8}}, {{245},{8}}, {{ 13},{8}}, {{141},{8}}, +{{ 77},{8}}, {{205},{8}}, {{ 45},{8}}, {{173},{8}}, {{109},{8}}, +{{237},{8}}, {{ 29},{8}}, {{157},{8}}, {{ 93},{8}}, {{221},{8}}, +{{ 61},{8}}, {{189},{8}}, {{125},{8}}, {{253},{8}}, {{ 19},{9}}, +{{275},{9}}, {{147},{9}}, {{403},{9}}, {{ 83},{9}}, {{339},{9}}, +{{211},{9}}, {{467},{9}}, {{ 51},{9}}, {{307},{9}}, {{179},{9}}, +{{435},{9}}, {{115},{9}}, {{371},{9}}, {{243},{9}}, {{499},{9}}, +{{ 11},{9}}, {{267},{9}}, {{139},{9}}, {{395},{9}}, {{ 75},{9}}, +{{331},{9}}, {{203},{9}}, {{459},{9}}, {{ 43},{9}}, {{299},{9}}, +{{171},{9}}, {{427},{9}}, {{107},{9}}, {{363},{9}}, {{235},{9}}, +{{491},{9}}, {{ 27},{9}}, {{283},{9}}, {{155},{9}}, {{411},{9}}, +{{ 91},{9}}, {{347},{9}}, {{219},{9}}, {{475},{9}}, {{ 59},{9}}, +{{315},{9}}, {{187},{9}}, {{443},{9}}, {{123},{9}}, {{379},{9}}, +{{251},{9}}, {{507},{9}}, {{ 7},{9}}, {{263},{9}}, {{135},{9}}, +{{391},{9}}, {{ 71},{9}}, {{327},{9}}, {{199},{9}}, {{455},{9}}, +{{ 39},{9}}, {{295},{9}}, {{167},{9}}, {{423},{9}}, {{103},{9}}, +{{359},{9}}, {{231},{9}}, {{487},{9}}, {{ 23},{9}}, {{279},{9}}, +{{151},{9}}, {{407},{9}}, {{ 87},{9}}, {{343},{9}}, {{215},{9}}, +{{471},{9}}, {{ 55},{9}}, {{311},{9}}, {{183},{9}}, {{439},{9}}, +{{119},{9}}, {{375},{9}}, {{247},{9}}, {{503},{9}}, {{ 15},{9}}, +{{271},{9}}, {{143},{9}}, {{399},{9}}, {{ 79},{9}}, {{335},{9}}, +{{207},{9}}, {{463},{9}}, {{ 47},{9}}, {{303},{9}}, {{175},{9}}, +{{431},{9}}, {{111},{9}}, {{367},{9}}, {{239},{9}}, {{495},{9}}, +{{ 31},{9}}, {{287},{9}}, {{159},{9}}, {{415},{9}}, {{ 95},{9}}, +{{351},{9}}, {{223},{9}}, {{479},{9}}, {{ 63},{9}}, {{319},{9}}, +{{191},{9}}, {{447},{9}}, {{127},{9}}, {{383},{9}}, {{255},{9}}, +{{511},{9}}, {{ 0},{7}}, {{ 64},{7}}, {{ 32},{7}}, {{ 96},{7}}, +{{ 16},{7}}, {{ 80},{7}}, {{ 48},{7}}, {{112},{7}}, {{ 8},{7}}, +{{ 72},{7}}, {{ 40},{7}}, {{104},{7}}, {{ 24},{7}}, {{ 88},{7}}, +{{ 56},{7}}, {{120},{7}}, {{ 4},{7}}, {{ 68},{7}}, {{ 36},{7}}, +{{100},{7}}, {{ 20},{7}}, {{ 84},{7}}, {{ 52},{7}}, {{116},{7}}, +{{ 3},{8}}, {{131},{8}}, {{ 67},{8}}, {{195},{8}}, {{ 35},{8}}, +{{163},{8}}, {{ 99},{8}}, {{227},{8}} +}; + +Z_INTERNAL const ct_data static_dtree[D_CODES] = { +{{ 0},{5}}, {{16},{5}}, {{ 8},{5}}, {{24},{5}}, {{ 4},{5}}, +{{20},{5}}, {{12},{5}}, {{28},{5}}, {{ 2},{5}}, {{18},{5}}, +{{10},{5}}, {{26},{5}}, {{ 6},{5}}, {{22},{5}}, {{14},{5}}, +{{30},{5}}, {{ 1},{5}}, {{17},{5}}, {{ 9},{5}}, {{25},{5}}, +{{ 5},{5}}, {{21},{5}}, {{13},{5}}, {{29},{5}}, {{ 3},{5}}, +{{19},{5}}, {{11},{5}}, {{27},{5}}, {{ 7},{5}}, {{23},{5}} +}; + +const unsigned char Z_INTERNAL zng_dist_code[DIST_CODE_LEN] = { + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, +10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, +11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, +12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, +13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, +18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, +28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, +29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 +}; + +const unsigned char Z_INTERNAL zng_length_code[STD_MAX_MATCH-STD_MIN_MATCH+1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, +13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, +17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, +19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, +22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, +23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, +26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, +27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 +}; + +Z_INTERNAL const int base_length[LENGTH_CODES] = { +0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, +64, 80, 96, 112, 128, 160, 192, 224, 0 +}; + +Z_INTERNAL const int base_dist[D_CODES] = { + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 +}; + +#endif /* TREES_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/uncompr.c b/internal-complibs/zlib-ng-2.1.0-beta1/uncompr.c new file mode 100644 index 000000000..311eca2b0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/uncompr.c @@ -0,0 +1,80 @@ +/* uncompr.c -- decompress a memory buffer + * Copyright (C) 1995-2003, 2010, 2014, 2016 Jean-loup Gailly, Mark Adler. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + Decompresses the source buffer into the destination buffer. *sourceLen is + the byte length of the source buffer. Upon entry, *destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, + *destLen is the size of the decompressed data and *sourceLen is the number + of source bytes consumed. Upon return, source + *sourceLen points to the + first unused input byte. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, or + Z_DATA_ERROR if the input data was corrupted, including if the input data is + an incomplete zlib stream. +*/ +int Z_EXPORT PREFIX(uncompress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t *sourceLen) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_uintmax_t len, left; + unsigned char buf[1]; /* for detection of incomplete stream when *destLen == 0 */ + + len = *sourceLen; + if (*destLen) { + left = *destLen; + *destLen = 0; + } else { + left = 1; + dest = buf; + } + + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(inflateInit)(&stream); + if (err != Z_OK) return err; + + stream.next_out = dest; + stream.avail_out = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = len > (unsigned long)max ? max : (unsigned int)len; + len -= stream.avail_in; + } + err = PREFIX(inflate)(&stream, Z_NO_FLUSH); + } while (err == Z_OK); + + *sourceLen -= len + stream.avail_in; + if (dest != buf) + *destLen = (z_size_t)stream.total_out; + else if (stream.total_out && err == Z_BUF_ERROR) + left = 1; + + PREFIX(inflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : + err == Z_NEED_DICT ? Z_DATA_ERROR : + err == Z_BUF_ERROR && left + stream.avail_out ? Z_DATA_ERROR : + err; +} + +int Z_EXPORT PREFIX(uncompress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(uncompress2)(dest, destLen, source, &sourceLen); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.a64 b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.a64 new file mode 100644 index 000000000..2a0f3cfe4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.a64 @@ -0,0 +1,243 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.a64 (standard build) +# nmake -f win32/Makefile.a64 LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM64_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_NEON_HASLD4 \ + -DARM_FEATURES \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM64 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_quick.obj \ + deflate_medium.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +WFLAGS = $(WFLAGS) \ + -DARM_ACLE \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x55A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_neon.obj: $(SRCDIR)/arch/arm/slide_hash_neon.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.arm b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.arm new file mode 100644 index 000000000..7d3f1b58a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.arm @@ -0,0 +1,255 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.arm (standard build) +# nmake -f win32/Makefile.arm LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE=1 \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DARM_FEATURES \ + -DARM_NEON_HASLD4 \ + # +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dARM /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +WITH_ACLE = +WITH_NEON = +WITH_VFPV3 = +NEON_ARCH = /arch:VFPv4 +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_fold.obj \ + arm_features.obj \ + chunkset.obj \ + compare256.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + slide_hash.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +!if "$(WITH_ACLE)" != "" +WFLAGS = $(WFLAGS) -DARM_ACLE +OBJS = $(OBJS) crc32_acle.obj insert_string_acle.obj +!endif +!if "$(WITH_VFPV3)" != "" +NEON_ARCH = /arch:VFPv3 +!endif +!if "$(WITH_NEON)" != "" +CFLAGS = $(CFLAGS) $(NEON_ARCH) +WFLAGS = $(WFLAGS) \ + -D__ARM_NEON__=1 \ + -DARM_NEON \ + -DARM_NOCHECK_NEON \ + # +OBJS = $(OBJS) adler32_neon.obj chunkset_neon.obj compare256_neon.obj slide_hash_neon.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ -base:0x5A4C0000 $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/arm}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.msc b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.msc new file mode 100644 index 000000000..9ed26f283 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/Makefile.msc @@ -0,0 +1,266 @@ +# Makefile for zlib using Microsoft (Visual) C +# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler +# +# Usage: +# nmake -f win32/Makefile.msc (standard build) +# nmake -f win32/Makefile.msc LOC=-DFOO (nonstandard build) + +# The toplevel directory of the source tree. +# +TOP = . + +# optional build flags +LOC = + +# variables +STATICLIB = zlib.lib +SHAREDLIB = zlib1.dll +IMPLIB = zdll.lib +SYMBOL_PREFIX = + +CC = cl +LD = link +AR = lib +RC = rc +CP = copy /y +CFLAGS = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC) +WFLAGS = \ + -D_CRT_SECURE_NO_DEPRECATE \ + -D_CRT_NONSTDC_NO_DEPRECATE \ + -DX86_FEATURES \ + -DX86_PCLMULQDQ_CRC \ + -DX86_SSE2 \ + -DX86_SSE42 \ + -DX86_SSE42_CRC_INTRIN \ + -DX86_SSSE3 \ + -DX86_AVX2 + +LDFLAGS = -nologo -debug -incremental:no -opt:ref -manifest +ARFLAGS = -nologo +RCFLAGS = /dWIN32 /r +DEFFILE = zlib.def +RCFILE = zlib1.rc +RESFILE = zlib1.res +WITH_GZFILEOP = yes +ZLIB_COMPAT = +SUFFIX = + +OBJS = \ + adler32.obj \ + adler32_avx2.obj \ + adler32_avx512.obj \ + adler32_avx512_vnni.obj \ + adler32_sse42.obj \ + adler32_ssse3.obj \ + adler32_fold.obj \ + chunkset.obj \ + chunkset_avx2.obj \ + chunkset_sse2.obj \ + chunkset_ssse3.obj \ + compare256.obj \ + compare256_avx2.obj \ + compare256_sse2.obj \ + compress.obj \ + cpu_features.obj \ + crc32_braid.obj \ + crc32_braid_comb.obj \ + crc32_fold.obj \ + crc32_pclmulqdq.obj \ + deflate.obj \ + deflate_fast.obj \ + deflate_huff.obj \ + deflate_medium.obj \ + deflate_quick.obj \ + deflate_rle.obj \ + deflate_slow.obj \ + deflate_stored.obj \ + functable.obj \ + infback.obj \ + inflate.obj \ + inftrees.obj \ + insert_string.obj \ + insert_string_roll.obj \ + insert_string_sse42.obj \ + slide_hash.obj \ + slide_hash_avx2.obj \ + slide_hash_sse2.obj \ + trees.obj \ + uncompr.obj \ + zutil.obj \ + x86_features.obj \ + # +!if "$(ZLIB_COMPAT)" != "" +WITH_GZFILEOP = yes +WFLAGS = $(WFLAGS) -DZLIB_COMPAT +DEFFILE = zlibcompat.def +!else +STATICLIB = zlib-ng.lib +SHAREDLIB = zlib-ng1.dll +IMPLIB = zngdll.lib +DEFFILE = zlib-ng.def +RCFILE = zlib-ng1.rc +RESFILE = zlib-ng1.res +SUFFIX = -ng +!endif + +!if "$(WITH_GZFILEOP)" != "" +WFLAGS = $(WFLAGS) -DWITH_GZFILEOP +OBJS = $(OBJS) gzlib.obj gzread.obj gzwrite.obj +!endif + +# targets +all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \ + example.exe minigzip.exe example_d.exe minigzip_d.exe + +!if "$(SYMBOL_PREFIX)" != "" +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib_name_mangling$(SUFFIX).h.in zlib_name_mangling$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" +!else +zlib_name_mangling$(SUFFIX).h: zlib_name_mangling.h.empty + $(CP) $(TOP)\zlib_name_mangling.h.empty zlib_name_mangling$(SUFFIX).h +!endif + +zlib$(SUFFIX).h: zlib$(SUFFIX).h.in + cscript $(TOP)\win32\replace.vbs $(TOP)\zlib$(SUFFIX).h.in zlib$(SUFFIX).h "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +gzread.c: gzread.c.in + cscript $(TOP)\win32\replace.vbs $(TOP)\gzread.c.in gzread.c "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +zconf: $(TOP)/zconf$(SUFFIX).h.in $(TOP)/zlib$(SUFFIX).h $(TOP)/zlib_name_mangling$(SUFFIX).h + $(CP) $(TOP)\zconf$(SUFFIX).h.in $(TOP)\zconf$(SUFFIX).h + +$(TOP)/win32/$(DEFFILE): $(TOP)/win32/$(DEFFILE).in + cscript $(TOP)\win32\replace.vbs $(TOP)/win32/$(DEFFILE).in $(TOP)/win32/$(DEFFILE) "@ZLIB_SYMBOL_PREFIX@" "$(SYMBOL_PREFIX)" + +$(STATICLIB): zconf $(OBJS) + $(AR) $(ARFLAGS) -out:$@ $(OBJS) + +$(IMPLIB): $(SHAREDLIB) + +$(SHAREDLIB): zconf $(TOP)/win32/$(DEFFILE) $(OBJS) $(RESFILE) + $(LD) $(LDFLAGS) -def:$(TOP)/win32/$(DEFFILE) -dll -implib:$(IMPLIB) \ + -out:$@ $(OBJS) $(RESFILE) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;2 + +example.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + $(LD) $(LDFLAGS) minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(STATICLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +example_d.exe: example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ example.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +minigzip_d.exe: minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + $(LD) $(LDFLAGS) -out:$@ minigzip.obj gzlib2.obj gzread2.obj gzwrite2.obj $(IMPLIB) + if exist $@.manifest \ + mt -nologo -manifest $@.manifest -outputresource:$@;1 + +{$(TOP)}.c.obj: + $(CC) -c $(WFLAGS) $(CFLAGS) $< + +gzlib2.obj: gzlib.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzlib2.obj gzlib.c + +gzread2.obj: gzread.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzread2.obj gzread.c + +gzwrite2.obj: gzwrite.c + $(CC) -c $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP -Fogzwrite2.obj gzwrite.c + +{$(TOP)/arch/x86}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $< + +{$(TOP)/test}.c.obj: + $(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) -DWITH_GZFILEOP $< + +$(TOP)/zconf$(SUFFIX).h: zconf + +SRCDIR = $(TOP) +# Keep the dependences in sync with top-level Makefile.in +adler32.obj: $(SRCDIR)/adler32.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/functable.h $(SRCDIR)/adler32_p.h +adler32_avx2.obj: $(SRCDIR)/arch/x86/adler32_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/fallback_builtins.h +adler32_avx512.obj: $(SRCDIR)/arch/x86/adler32_avx512.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_avx512_vnni.obj: $(SRCDIR)/arch/x86/adler32_avx512_vnni.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/arch/x86/adler32_avx512_p.h +adler32_sse42.obj: $(SRCDIR)/arch/x86/adler32_sse42.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_ssse3.obj: $(SRCDIR)/arch/x86/adler32_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/cpu_features.h $(SRCDIR)/adler32_p.h $(SRCDIR)/adler32_fold.h \ + $(SRCDIR)/arch/x86/adler32_ssse3_p.h +adler32_fold.obj: $(SRCDIR)/adler32_fold.c $(SRCDIR)/zbuild.h $(SRCDIR)/adler32_fold.h $(SRCDIR)/functable.h +functable.obj: $(SRCDIR)/functable.c $(SRCDIR)/zbuild.h $(SRCDIR)/functable.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/zendian.h $(SRCDIR)/arch/x86/x86_features.h +gzlib.obj: $(SRCDIR)/gzlib.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzread.obj: $(SRCDIR)/gzread.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +gzwrite.obj: $(SRCDIR)/gzwrite.c $(SRCDIR)/zbuild.h $(SRCDIR)/gzguts.h $(SRCDIR)/zutil_p.h +compress.obj: $(SRCDIR)/compress.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +uncompr.obj: $(SRCDIR)/uncompr.c $(SRCDIR)/zbuild.h $(SRCDIR)/zlib$(SUFFIX).h +chunkset.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_avx2.obj: $(SRCDIR)/arch/x86/chunkset_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_sse2.obj: $(SRCDIR)/arch/x86/chunkset_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +chunkset_ssse3.obj: $(SRCDIR)/arch/x86/chunkset_ssse3.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +cpu_features.obj: $(SRCDIR)/cpu_features.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h +crc32_braid.obj: $(SRCDIR)/crc32_braid.c $(SRCDIR)/zbuild.h $(SRCDIR)/zendian.h $(SRCDIR)/deflate.h $(SRCDIR)/functable.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h +crc32_braid_comb.obj: $(SRCDIR)/crc32_braid_comb.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/crc32_braid_p.h $(SRCDIR)/crc32_braid_tbl.h $(SRCDIR)/crc32_braid_comb_p.h +crc32_fold.obj: $(SRCDIR)/crc32_fold.c $(SRCDIR)/zbuild.h +crc32_pclmulqdq.obj: $(SRCDIR)/arch/x86/crc32_pclmulqdq.c $(SRCDIR)/arch/x86/crc32_pclmulqdq_tpl.h $(SRCDIR)/arch/x86/crc32_fold_pclmulqdq_tpl.h \ + $(SRCDIR)/crc32_fold.h $(SRCDIR)/zbuild.h +deflate.obj: $(SRCDIR)/deflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_fast.obj: $(SRCDIR)/deflate_fast.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_huff.obj: $(SRCDIR)/deflate_huff.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_medium.obj: $(SRCDIR)/deflate_medium.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_quick.obj: $(SRCDIR)/deflate_quick.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/trees_emit.h +deflate_rle.obj: $(SRCDIR)/deflate_rle.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_slow.obj: $(SRCDIR)/deflate_slow.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +deflate_stored.obj: $(SRCDIR)/deflate_stored.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/deflate_p.h $(SRCDIR)/functable.h +infback.obj: $(SRCDIR)/infback.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h +inflate.obj: $(SRCDIR)/inflate.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h $(SRCDIR)/inflate.h $(SRCDIR)/inflate_p.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h $(SRCDIR)/functable.h +inftrees.obj: $(SRCDIR)/inftrees.c $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/inftrees.h +slide_hash.obj: $(SRCDIR)/slide_hash.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_avx2.obj: $(SRCDIR)/arch/x86/slide_hash_avx2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +slide_hash_sse2.obj: $(SRCDIR)/arch/x86/slide_hash_sse2.c $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h +trees.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/deflate.h $(SRCDIR)/trees_tbl.h +zutil.obj: $(SRCDIR)/zbuild.h $(SRCDIR)/zutil.h $(SRCDIR)/zutil_p.h + +example.obj: $(TOP)/test/example.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zbuild.h $(TOP)/zlib$(SUFFIX).h + +$(RESFILE): $(TOP)/win32/$(RCFILE) + $(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/$(RCFILE) + +# testing +test: example.exe minigzip.exe + example + echo hello world | minigzip | minigzip -d + +testdll: example_d.exe minigzip_d.exe + example_d + echo hello world | minigzip_d | minigzip_d -d + + +# cleanup +clean: + -del $(STATICLIB) + -del $(SHAREDLIB) + -del $(IMPLIB) + -del *.obj + -del *.res + -del *.exp + -del *.exe + -del *.pdb + -del *.manifest + +distclean: clean + -del zconf$(SUFFIX).h + -del zlib$(SUFFIX).h + -del zlib_name_mangling$(SUFFIX).h + -del $(TOP)\win32\zlib.def + -del $(TOP)\win32\zlibcompat.def + -del $(TOP)\win32\zlib-ng.def + -del gzread.c diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/replace.vbs b/internal-complibs/zlib-ng-2.1.0-beta1/win32/replace.vbs new file mode 100644 index 000000000..6779971d0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/replace.vbs @@ -0,0 +1,15 @@ +strInputFileName = Wscript.Arguments(0) +strOutputFileName = Wscript.Arguments(1) +strOldText = Wscript.Arguments(2) +strNewText = Wscript.Arguments(3) + +Set objFSO = CreateObject("Scripting.FileSystemObject") +Set objFile = objFSO.OpenTextFile(strInputFileName, 1) + +strText = objFile.ReadAll +objFile.Close +strNewText = Replace(strText, strOldText, strNewText) + +Set objFile = objFSO.OpenTextFile(strOutputFileName, 2, True) +objFile.Write strNewText +objFile.Close diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng.def.in b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng.def.in new file mode 100644 index 000000000..53b2bc21f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng.def.in @@ -0,0 +1,60 @@ +; zlib-ng data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibng_version + @ZLIB_SYMBOL_PREFIX@zng_deflate + @ZLIB_SYMBOL_PREFIX@zng_deflateEnd + @ZLIB_SYMBOL_PREFIX@zng_deflateInit + @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflate + @ZLIB_SYMBOL_PREFIX@zng_inflateEnd + @ZLIB_SYMBOL_PREFIX@zng_inflateInit + @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 + @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +; advanced functions + @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_deflateCopy + @ZLIB_SYMBOL_PREFIX@zng_deflateReset + @ZLIB_SYMBOL_PREFIX@zng_deflateParams + @ZLIB_SYMBOL_PREFIX@zng_deflateTune + @ZLIB_SYMBOL_PREFIX@zng_deflateBound + @ZLIB_SYMBOL_PREFIX@zng_deflatePending + @ZLIB_SYMBOL_PREFIX@zng_deflatePrime + @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader + @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams + @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@zng_inflateSync + @ZLIB_SYMBOL_PREFIX@zng_inflateCopy + @ZLIB_SYMBOL_PREFIX@zng_inflateReset + @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 + @ZLIB_SYMBOL_PREFIX@zng_inflatePrime + @ZLIB_SYMBOL_PREFIX@zng_inflateMark + @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader + @ZLIB_SYMBOL_PREFIX@zng_inflateBack + @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@zng_compress + @ZLIB_SYMBOL_PREFIX@zng_compress2 + @ZLIB_SYMBOL_PREFIX@zng_compressBound + @ZLIB_SYMBOL_PREFIX@zng_uncompress + @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +; checksum functions + @ZLIB_SYMBOL_PREFIX@zng_adler32 + @ZLIB_SYMBOL_PREFIX@zng_adler32_z + @ZLIB_SYMBOL_PREFIX@zng_crc32 + @ZLIB_SYMBOL_PREFIX@zng_crc32_z + @ZLIB_SYMBOL_PREFIX@zng_adler32_combine + @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@zng_zError + @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@zng_get_crc_table + @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine + @ZLIB_SYMBOL_PREFIX@zng_inflateValidate + @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep + @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng1.rc b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng1.rc new file mode 100644 index 000000000..327f17fd8 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib-ng1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib-ng.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + PRODUCTVERSION ZLIBNG_VER_MAJOR,ZLIBNG_VER_MINOR,ZLIBNG_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIBNG_VERSION "\0" + VALUE "InternalName", "zlib-ng1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib-ng1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIBNG_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib.def.in b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib.def.in new file mode 100644 index 000000000..561a42f7f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib.def.in @@ -0,0 +1,64 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 +; large file functions + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib1.rc b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib1.rc new file mode 100644 index 000000000..73bc4389c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlib1.rc @@ -0,0 +1,36 @@ +#include +#include "zlib.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + PRODUCTVERSION ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS 1 +#else + FILEFLAGS 0 +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE 0 // not used +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, char set = Windows, Multilingual + BEGIN + VALUE "FileDescription", "zlib data compression library\0" + VALUE "FileVersion", ZLIB_VERSION "\0" + VALUE "InternalName", "zlib1.dll\0" + VALUE "LegalCopyright", "(C) 1995-2022 Jean-loup Gailly & Mark Adler\0" + VALUE "OriginalFilename", "zlib1.dll\0" + VALUE "ProductName", "zlib\0" + VALUE "ProductVersion", ZLIB_VERSION "\0" + VALUE "Comments", "For more information visit https://www.zlib.net/\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlibcompat.def.in b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlibcompat.def.in new file mode 100644 index 000000000..52a713cf0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/win32/zlibcompat.def.in @@ -0,0 +1,97 @@ +; zlib data compression library +EXPORTS +; basic functions + @ZLIB_SYMBOL_PREFIX@zlibVersion + @ZLIB_SYMBOL_PREFIX@deflate + @ZLIB_SYMBOL_PREFIX@deflateEnd + @ZLIB_SYMBOL_PREFIX@inflate + @ZLIB_SYMBOL_PREFIX@inflateEnd +; advanced functions + @ZLIB_SYMBOL_PREFIX@deflateSetDictionary + @ZLIB_SYMBOL_PREFIX@deflateGetDictionary + @ZLIB_SYMBOL_PREFIX@deflateCopy + @ZLIB_SYMBOL_PREFIX@deflateReset + @ZLIB_SYMBOL_PREFIX@deflateParams + @ZLIB_SYMBOL_PREFIX@deflateTune + @ZLIB_SYMBOL_PREFIX@deflateBound + @ZLIB_SYMBOL_PREFIX@deflatePending + @ZLIB_SYMBOL_PREFIX@deflatePrime + @ZLIB_SYMBOL_PREFIX@deflateSetHeader + @ZLIB_SYMBOL_PREFIX@inflateSetDictionary + @ZLIB_SYMBOL_PREFIX@inflateGetDictionary + @ZLIB_SYMBOL_PREFIX@inflateSync + @ZLIB_SYMBOL_PREFIX@inflateCopy + @ZLIB_SYMBOL_PREFIX@inflateReset + @ZLIB_SYMBOL_PREFIX@inflateReset2 + @ZLIB_SYMBOL_PREFIX@inflatePrime + @ZLIB_SYMBOL_PREFIX@inflateMark + @ZLIB_SYMBOL_PREFIX@inflateGetHeader + @ZLIB_SYMBOL_PREFIX@inflateBack + @ZLIB_SYMBOL_PREFIX@inflateBackEnd + @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +; utility functions + @ZLIB_SYMBOL_PREFIX@compress + @ZLIB_SYMBOL_PREFIX@compress2 + @ZLIB_SYMBOL_PREFIX@compressBound + @ZLIB_SYMBOL_PREFIX@uncompress + @ZLIB_SYMBOL_PREFIX@uncompress2 + @ZLIB_SYMBOL_PREFIX@gzopen + @ZLIB_SYMBOL_PREFIX@gzdopen + @ZLIB_SYMBOL_PREFIX@gzbuffer + @ZLIB_SYMBOL_PREFIX@gzsetparams + @ZLIB_SYMBOL_PREFIX@gzread + @ZLIB_SYMBOL_PREFIX@gzfread + @ZLIB_SYMBOL_PREFIX@gzwrite + @ZLIB_SYMBOL_PREFIX@gzfwrite + @ZLIB_SYMBOL_PREFIX@gzprintf + @ZLIB_SYMBOL_PREFIX@gzvprintf + @ZLIB_SYMBOL_PREFIX@gzputs + @ZLIB_SYMBOL_PREFIX@gzgets + @ZLIB_SYMBOL_PREFIX@gzputc + @ZLIB_SYMBOL_PREFIX@gzgetc + @ZLIB_SYMBOL_PREFIX@gzungetc + @ZLIB_SYMBOL_PREFIX@gzflush + @ZLIB_SYMBOL_PREFIX@gzseek + @ZLIB_SYMBOL_PREFIX@gzrewind + @ZLIB_SYMBOL_PREFIX@gztell + @ZLIB_SYMBOL_PREFIX@gzoffset + @ZLIB_SYMBOL_PREFIX@gzeof + @ZLIB_SYMBOL_PREFIX@gzdirect + @ZLIB_SYMBOL_PREFIX@gzclose + @ZLIB_SYMBOL_PREFIX@gzclose_r + @ZLIB_SYMBOL_PREFIX@gzclose_w + @ZLIB_SYMBOL_PREFIX@gzerror + @ZLIB_SYMBOL_PREFIX@gzclearerr +; large file functions + @ZLIB_SYMBOL_PREFIX@gzopen64 + @ZLIB_SYMBOL_PREFIX@gzseek64 + @ZLIB_SYMBOL_PREFIX@gztell64 + @ZLIB_SYMBOL_PREFIX@gzoffset64 + @ZLIB_SYMBOL_PREFIX@adler32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine64 + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +; checksum functions + @ZLIB_SYMBOL_PREFIX@adler32 + @ZLIB_SYMBOL_PREFIX@adler32_z + @ZLIB_SYMBOL_PREFIX@crc32 + @ZLIB_SYMBOL_PREFIX@crc32_z + @ZLIB_SYMBOL_PREFIX@adler32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine + @ZLIB_SYMBOL_PREFIX@crc32_combine_gen + @ZLIB_SYMBOL_PREFIX@crc32_combine_op +; various hacks, don't look :) + @ZLIB_SYMBOL_PREFIX@deflateInit_ + @ZLIB_SYMBOL_PREFIX@deflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateInit_ + @ZLIB_SYMBOL_PREFIX@inflateInit2_ + @ZLIB_SYMBOL_PREFIX@inflateBackInit_ + @ZLIB_SYMBOL_PREFIX@gzgetc_ + @ZLIB_SYMBOL_PREFIX@zError + @ZLIB_SYMBOL_PREFIX@inflateSyncPoint + @ZLIB_SYMBOL_PREFIX@get_crc_table + @ZLIB_SYMBOL_PREFIX@inflateUndermine + @ZLIB_SYMBOL_PREFIX@inflateValidate + @ZLIB_SYMBOL_PREFIX@inflateCodesUsed + @ZLIB_SYMBOL_PREFIX@inflateResetKeep + @ZLIB_SYMBOL_PREFIX@deflateResetKeep + @ZLIB_SYMBOL_PREFIX@gzopen_w diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zbuild.h b/internal-complibs/zlib-ng-2.1.0-beta1/zbuild.h new file mode 100644 index 000000000..27f784a99 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zbuild.h @@ -0,0 +1,253 @@ +#ifndef _ZBUILD_H +#define _ZBUILD_H + +#define _POSIX_SOURCE 1 /* fileno */ +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200809L /* snprintf, posix_memalign, strdup */ +#endif +#ifndef _ISOC11_SOURCE +# define _ISOC11_SOURCE 1 /* aligned_alloc */ +#endif +#ifdef __OpenBSD__ +# define _BSD_SOURCE 1 +#endif + +#include +#include +#include +#include + +/* Determine compiler version of C Standard */ +#ifdef __STDC_VERSION__ +# if __STDC_VERSION__ >= 199901L +# ifndef STDC99 +# define STDC99 +# endif +# endif +# if __STDC_VERSION__ >= 201112L +# ifndef STDC11 +# define STDC11 +# endif +# endif +#endif + +/* Determine compiler support for TLS */ +#ifndef Z_TLS +# ifdef HAVE_THREAD_LOCAL +# define Z_TLS _Thread_local +# elif defined(__GNUC__) || defined(__SUNPRO_C) +# define Z_TLS __thread +# elif defined(_WIN32) && (defined(_MSC_VER) || defined(__ICL)) +# define Z_TLS __declspec(thread) +# else +# warning Unable to detect Thread Local Storage support. +# define Z_TLS +# endif +#endif + +#ifndef Z_HAS_ATTRIBUTE +# if defined(__has_attribute) +# define Z_HAS_ATTRIBUTE(a) __has_attribute(a) +# else +# define Z_HAS_ATTRIBUTE(a) 0 +# endif +#endif + +#ifndef Z_FALLTHROUGH +# if Z_HAS_ATTRIBUTE(__fallthrough__) || (defined(__GNUC__) && (__GNUC__ >= 7)) +# define Z_FALLTHROUGH __attribute__((__fallthrough__)) +# else +# define Z_FALLTHROUGH do {} while(0) /* fallthrough */ +# endif +#endif + +/* This has to be first include that defines any types */ +#if defined(_MSC_VER) +# if defined(_WIN64) + typedef __int64 ssize_t; +# else + typedef long ssize_t; +# endif + +# if defined(_WIN64) + #define SSIZE_MAX _I64_MAX +# else + #define SSIZE_MAX LONG_MAX +# endif +#endif + +/* MS Visual Studio does not allow inline in C, only C++. + But it provides __inline instead, so use that. */ +#if defined(_MSC_VER) && !defined(inline) && !defined(__cplusplus) +# define inline __inline +#endif + +#if defined(ZLIB_COMPAT) +# define PREFIX(x) x +# define PREFIX2(x) ZLIB_ ## x +# define PREFIX3(x) z_ ## x +# define PREFIX4(x) x ## 64 +# define zVersion zlibVersion +# if defined(_WIN64) +# define z_size_t unsigned __int64 +# else +# define z_size_t unsigned long +# endif +#else +# define PREFIX(x) zng_ ## x +# define PREFIX2(x) ZLIBNG_ ## x +# define PREFIX3(x) zng_ ## x +# define PREFIX4(x) zng_ ## x +# define zVersion zlibng_version +# define z_size_t size_t +#endif + +/* In zlib-compat some functions and types use unsigned long, but zlib-ng use size_t */ +#if defined(ZLIB_COMPAT) +# define z_uintmax_t unsigned long +#else +# define z_uintmax_t size_t +#endif + +/* Minimum of a and b. */ +#define MIN(a, b) ((a) > (b) ? (b) : (a)) +/* Maximum of a and b. */ +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +/* Ignore unused variable warning */ +#define Z_UNUSED(var) (void)(var) + +#if defined(HAVE_VISIBILITY_INTERNAL) +# define Z_INTERNAL __attribute__((visibility ("internal"))) +#elif defined(HAVE_VISIBILITY_HIDDEN) +# define Z_INTERNAL __attribute__((visibility ("hidden"))) +#else +# define Z_INTERNAL +#endif + +#ifndef __cplusplus +# define Z_REGISTER register +#else +# define Z_REGISTER +#endif + +/* Reverse the bytes in a value. Use compiler intrinsics when + possible to take advantage of hardware implementations. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1300) +# include +# pragma intrinsic(_byteswap_ulong) +# define ZSWAP16(q) _byteswap_ushort(q) +# define ZSWAP32(q) _byteswap_ulong(q) +# define ZSWAP64(q) _byteswap_uint64(q) + +#elif defined(__clang__) || (defined(__GNUC__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +# define ZSWAP16(q) __builtin_bswap16(q) +# define ZSWAP32(q) __builtin_bswap32(q) +# define ZSWAP64(q) __builtin_bswap64(q) + +#elif defined(__GNUC__) && (__GNUC__ >= 2) && defined(__linux__) +# include +# define ZSWAP16(q) bswap_16(q) +# define ZSWAP32(q) bswap_32(q) +# define ZSWAP64(q) bswap_64(q) + +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) +# include +# define ZSWAP16(q) bswap16(q) +# define ZSWAP32(q) bswap32(q) +# define ZSWAP64(q) bswap64(q) +#elif defined(__OpenBSD__) +# include +# define ZSWAP16(q) swap16(q) +# define ZSWAP32(q) swap32(q) +# define ZSWAP64(q) swap64(q) +#elif defined(__INTEL_COMPILER) +/* ICC does not provide a two byte swap. */ +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) _bswap(q) +# define ZSWAP64(q) _bswap64(q) + +#else +# define ZSWAP16(q) ((((q) & 0xff) << 8) | (((q) & 0xff00) >> 8)) +# define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) +# define ZSWAP64(q) \ + (((q & 0xFF00000000000000u) >> 56u) | \ + ((q & 0x00FF000000000000u) >> 40u) | \ + ((q & 0x0000FF0000000000u) >> 24u) | \ + ((q & 0x000000FF00000000u) >> 8u) | \ + ((q & 0x00000000FF000000u) << 8u) | \ + ((q & 0x0000000000FF0000u) << 24u) | \ + ((q & 0x000000000000FF00u) << 40u) | \ + ((q & 0x00000000000000FFu) << 56u)) +#endif + +/* Only enable likely/unlikely if the compiler is known to support it */ +#if (defined(__GNUC__) && (__GNUC__ >= 3)) || defined(__INTEL_COMPILER) || defined(__clang__) +# define LIKELY_NULL(x) __builtin_expect((x) != 0, 0) +# define LIKELY(x) __builtin_expect(!!(x), 1) +# define UNLIKELY(x) __builtin_expect(!!(x), 0) +#else +# define LIKELY_NULL(x) x +# define LIKELY(x) x +# define UNLIKELY(x) x +#endif /* (un)likely */ + +#if defined(HAVE_ATTRIBUTE_ALIGNED) +# define ALIGNED_(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +# define ALIGNED_(x) __declspec(align(x)) +#endif + +/* Diagnostic functions */ +#ifdef ZLIB_DEBUG +# include + extern int Z_INTERNAL z_verbose; + extern void Z_INTERNAL z_error(const char *m); +# define Assert(cond, msg) {if (!(cond)) z_error(msg);} +# define Trace(x) {if (z_verbose >= 0) fprintf x;} +# define Tracev(x) {if (z_verbose > 0) fprintf x;} +# define Tracevv(x) {if (z_verbose > 1) fprintf x;} +# define Tracec(c, x) {if (z_verbose > 0 && (c)) fprintf x;} +# define Tracecv(c, x) {if (z_verbose > 1 && (c)) fprintf x;} +#else +# define Assert(cond, msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c, x) +# define Tracecv(c, x) +#endif + +#ifndef NO_UNALIGNED +# if defined(__x86_64__) || defined(_M_X64) || defined(__amd64__) || defined(_M_AMD64) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# elif defined(__i386__) || defined(__i486__) || defined(__i586__) || \ + defined(__i686__) || defined(_X86_) || defined(_M_IX86) +# define UNALIGNED_OK +# elif defined(__aarch64__) || defined(_M_ARM64) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# elif defined(__arm__) || (_M_ARM >= 7) +# if (defined(__GNUC__) && defined(__ARM_FEATURE_UNALIGNED)) || !defined(__GNUC__) +# define UNALIGNED_OK +# endif +# elif defined(__powerpc64__) || defined(__ppc64__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define UNALIGNED_OK +# define UNALIGNED64_OK +# endif +# endif +#endif + +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) +# define Z_MEMORY_SANITIZER 1 +# include +# endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zconf-ng.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zconf-ng.h.in new file mode 100644 index 000000000..226f06a03 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zconf-ng.h.in @@ -0,0 +1,176 @@ +/* zconf-ng.h -- configuration of the zlib-ng compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONFNG_H +#define ZCONFNG_H + +#include "zlib_name_mangling-ng.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +/* Always define z_const as const */ +#define z_const const + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_EXPORT + +/* Fallback for something that includes us. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) && defined(WITH_GZFILEOP) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +#endif /* ZCONFNG_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zconf.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zconf.h.in new file mode 100644 index 000000000..765e9c4e4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zconf.h.in @@ -0,0 +1,201 @@ +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZCONF_H +#define ZCONF_H + +#include "zlib_name_mangling.h" + +#if !defined(_WIN32) && defined(__WIN32__) +# define _WIN32 +#endif + +/* Clang macro for detecting declspec support + * https://clang.llvm.org/docs/LanguageExtensions.html#has-declspec-attribute + */ +#ifndef __has_declspec_attribute +# define __has_declspec_attribute(x) 0 +#endif + +#if defined(ZLIB_CONST) && !defined(z_const) +# define z_const const +#else +# define z_const +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# define MAX_MEM_LEVEL 9 +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2. + * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files + * created by gzip. (Files created by minigzip can still be extracted by + * gzip.) + */ +#ifndef MIN_WBITS +# define MIN_WBITS 8 /* 256 LZ77 window */ +#endif +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + (1 << (windowBits+2)) + (1 << (memLevel+9)) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus about 7 kilobytes + for small objects. +*/ + +/* Type declarations */ + + +#ifndef OF /* function prototypes */ +# define OF(args) args +#endif + +#ifdef ZLIB_INTERNAL +# define Z_INTERNAL ZLIB_INTERNAL +#endif + +/* If building or using zlib as a DLL, define ZLIB_DLL. + * This is not mandatory, but it offers a little performance increase. + */ +#if defined(ZLIB_DLL) && (defined(_WIN32) || (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))) +# ifdef Z_INTERNAL +# define Z_EXTERN extern __declspec(dllexport) +# else +# define Z_EXTERN extern __declspec(dllimport) +# endif +#endif + +/* If building or using zlib with the WINAPI/WINAPIV calling convention, + * define ZLIB_WINAPI. + * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. + */ +#if defined(ZLIB_WINAPI) && defined(_WIN32) +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include + /* No need for _export, use ZLIB.DEF instead. */ + /* For complete Windows compatibility, use WINAPI, not __stdcall. */ +# define Z_EXPORT WINAPI +# define Z_EXPORTVA WINAPIV +#endif + +#ifndef Z_EXTERN +# define Z_EXTERN extern +#endif +#ifndef Z_EXPORT +# define Z_EXPORT +#endif +#ifndef Z_EXPORTVA +# define Z_EXPORTVA +#endif + +/* Conditional exports */ +#define ZNG_CONDEXPORT Z_INTERNAL + +/* For backwards compatibility */ + +#ifndef ZEXTERN +# define ZEXTERN Z_EXTERN +#endif +#ifndef ZEXPORT +# define ZEXPORT Z_EXPORT +#endif +#ifndef ZEXPORTVA +# define ZEXPORTVA Z_EXPORTVA +#endif + +/* Legacy zlib typedefs for backwards compatibility. Don't assume stdint.h is defined. */ +typedef unsigned char Byte; +typedef Byte Bytef; + +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef char charf; +typedef int intf; +typedef uInt uIntf; +typedef uLong uLongf; + +typedef void const *voidpc; +typedef void *voidpf; +typedef void *voidp; + +typedef unsigned int z_crc_t; + +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by configure/cmake/etc */ +# define Z_HAVE_UNISTD_H +#endif + +#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */ +typedef PTRDIFF_TYPE ptrdiff_t; +#endif + +#include /* for off_t */ + +#include /* for wchar_t and NULL */ + +/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and + * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even + * though the former does not conform to the LFS document), but considering + * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as + * equivalently requesting no 64-bit operations + */ +#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 +# undef _LARGEFILE64_SOURCE +#endif + +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +# ifndef z_off_t +# define z_off_t off_t +# endif +#endif + +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 +# define Z_LFS64 +#endif + +#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) +# define Z_LARGE64 +#endif + +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) +# define Z_WANT64 +#endif + +#if !defined(SEEK_SET) +# define SEEK_SET 0 /* Seek from beginning of file. */ +# define SEEK_CUR 1 /* Seek from current position. */ +# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#endif + +#ifndef z_off_t +# define z_off_t long +#endif + +#if !defined(_WIN32) && defined(Z_LARGE64) +# define z_off64_t off64_t +#else +# if defined(__MSYS__) +# define z_off64_t _off64_t +# elif defined(_WIN32) && !defined(__GNUC__) +# define z_off64_t __int64 +# else +# define z_off64_t z_off_t +# endif +#endif + +#endif /* ZCONF_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zendian.h b/internal-complibs/zlib-ng-2.1.0-beta1/zendian.h new file mode 100644 index 000000000..3fdb13041 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zendian.h @@ -0,0 +1,60 @@ +/* zendian.h -- define BYTE_ORDER for endian tests + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ENDIAN_H_ +#define ENDIAN_H_ + +/* First check whether the compiler knows the target __BYTE_ORDER__. */ +#if defined(__BYTE_ORDER__) +# if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN __ORDER_BIG_ENDIAN__ +# endif +# if !defined(BYTE_ORDER) +# define BYTE_ORDER BIG_ENDIAN +# endif +# endif +#elif defined(__MINGW32__) +# include +#elif defined(_WIN32) +# define LITTLE_ENDIAN 1234 +# define BIG_ENDIAN 4321 +# if defined(_M_IX86) || defined(_M_AMD64) || defined(_M_IA64) || defined (_M_ARM) || defined (_M_ARM64) +# define BYTE_ORDER LITTLE_ENDIAN +# else +# error Unknown endianness! +# endif +#elif defined(__linux__) +# include +#elif defined(__APPLE__) +# include +#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__bsdi__) || defined(__DragonFly__) +# include +#elif defined(__sun) || defined(sun) +# include +# if !defined(LITTLE_ENDIAN) +# define LITTLE_ENDIAN 4321 +# endif +# if !defined(BIG_ENDIAN) +# define BIG_ENDIAN 1234 +# endif +# if !defined(BYTE_ORDER) +# if defined(_BIG_ENDIAN) +# define BYTE_ORDER BIG_ENDIAN +# else +# define BYTE_ORDER LITTLE_ENDIAN +# endif +# endif +#else +# include +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.h.in new file mode 100644 index 000000000..7f68f7a33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.h.in @@ -0,0 +1,1869 @@ +#ifndef ZNGLIB_H_ +#define ZNGLIB_H_ +/* zlib-ng.h -- interface of the 'zlib-ng' compression library, forked from zlib. + + Copyright (C) 1995-2016 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf-ng.h" + +#ifndef ZCONFNG_H +# error Missing zconf-ng.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.0.beta1" +#define ZLIBNG_VERNUM 0x02010010L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 0 +#define ZLIBNG_VER_STATUS 0 /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct zng_stream_s { + const uint8_t *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + size_t total_in; /* total number of input bytes read so far */ + + uint8_t *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + size_t total_out; /* total number of bytes output so far */ + + const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + uint32_t adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} zng_stream; + +typedef zng_stream *zng_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct zng_gz_header_s { + int32_t text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int32_t xflags; /* extra flags (not used when writing a gzip file) */ + int32_t os; /* operating system */ + uint8_t *extra; /* pointer to extra field or NULL if none */ + uint32_t extra_len; /* extra field length (valid if extra != NULL) */ + uint32_t extra_max; /* space at extra (only when reading header) */ + uint8_t *name; /* pointer to zero-terminated file name or NULL */ + uint32_t name_max; /* space at name (only when reading header) */ + uint8_t *comment; /* pointer to zero-terminated comment or NULL */ + uint32_t comm_max; /* space at comment (only when reading header) */ + int32_t hcrc; /* true if there was or will be a header crc */ + int32_t done; /* true when done reading gzip header (not used when writing a gzip file) */ +} zng_gz_header; + +typedef zng_gz_header *zng_gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + + + /* basic functions */ + +Z_EXTERN Z_EXPORT +const char *zlibng_version(void); +/* The application can compare zlibng_version and ZLIBNG_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib-ng.h header file used by the application. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit(zng_stream *strm, int32_t level); +/* + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level. + msg is set to null if there is no error message. deflateInit does not perform + any compression: this will be done by deflate(). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflate(zng_stream *strm, int32_t flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_deflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit(zng_stream *strm); +/* + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit does not perform any decompression. Actual decompression will + be done by inflate(). So next_in, and avail_in, next_out, and avail_out + are unused and unchanged. The current implementation of inflateInit() + does not process any header information -- that is deferred until inflate() + is called. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflate(zng_stream *strm, int32_t flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_inflateEnd(zng_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateInit2(zng_stream *strm, int32_t level, int32_t method, int32_t windowBits, int32_t memLevel, int32_t strategy); +/* + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid method). + msg is set to null if there is no error message. deflateInit2 does not perform + any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateReset(zng_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateParams(zng_stream *strm, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateTune(zng_stream *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN Z_EXPORT +unsigned long zng_deflateBound(zng_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePending(zng_stream *strm, uint32_t *pending, int32_t *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN Z_EXPORT +int32_t zng_deflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetHeader(zng_stream *strm, zng_gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided zng_gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateInit2(zng_stream *strm, int32_t windowBits); +/* + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, or Z_STREAM_ERROR if the parameters are invalid, such as a null + pointer to the structure. msg is set to null if there is no error message. + inflateInit2 does not perform any decompression apart from possibly reading + the zlib header if present: actual decompression will be done by inflate(). + (So next_in and avail_in may be modified, but next_out and avail_out are + unused and unchanged.) The current implementation of inflateInit2() does not + process any header information -- that is deferred until inflate() is called. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSetDictionary(zng_stream *strm, const uint8_t *dictionary, uint32_t dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetDictionary(zng_stream *strm, uint8_t *dictionary, uint32_t *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateSync(zng_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateCopy(zng_stream *dest, zng_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset(zng_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateReset2(zng_stream *strm, int32_t windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflatePrime(zng_stream *strm, int32_t bits, int32_t value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +long zng_inflateMark(zng_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateGetHeader(zng_stream *strm, zng_gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided zng_gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackInit(zng_stream *strm, int32_t windowBits, uint8_t *window); +/* + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated. +*/ + +typedef uint32_t (*in_func) (void *, const uint8_t * *); +typedef int32_t (*out_func) (void *, uint8_t *, uint32_t); + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBack(zng_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_inflateBackEnd(zng_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN Z_EXPORT +unsigned long zng_zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_compress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen, int32_t level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_compressBound(size_t sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN Z_EXPORT +int32_t zng_uncompress2(uint8_t *dest, size_t *destLen, const uint8_t *source, size_t *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + +#ifdef WITH_GZFILEOP + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +Z_EXTERN Z_EXPORT +gzFile zng_gzopen(const char *path, const char *mode); +/* + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN Z_EXPORT +gzFile zng_gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzbuffer(gzFile file, uint32_t size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzsetparams(gzFile file, int32_t level, int32_t strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzread(gzFile file, void *buf, uint32_t len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfread(void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzwrite(gzFile file, void const *buf, uint32_t len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN Z_EXPORT +size_t zng_gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN Z_EXPORTVA +int32_t zng_gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +char * zng_gzgets(gzFile file, char *buf, int32_t len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzputc(gzFile file, int32_t c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzungetc(int32_t c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzflush(gzFile file, int32_t flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzseek(gzFile file, z_off64_t offset, int whence); +/* + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gztell(gzFile file); +/* + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +Z_EXTERN Z_EXPORT +z_off64_t zng_gzoffset(gzFile file); +/* + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_r(gzFile file); +Z_EXTERN Z_EXPORT +int32_t zng_gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN Z_EXPORT +const char * zng_gzerror(gzFile file, int32_t *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN Z_EXPORT +void zng_gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif /* WITH_GZFILEOP */ + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32(uint32_t adler, const uint8_t *buf, uint32_t len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_z(uint32_t adler, const uint8_t *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_adler32_combine(uint32_t adler1, uint32_t adler2, z_off64_t len2); +/* + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32(uint32_t crc, const uint8_t *buf, uint32_t len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_z(uint32_t crc, const uint8_t *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine(uint32_t crc1, uint32_t crc2, z_off64_t len2); + +/* + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_gen(z_off64_t len2); + +/* + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN Z_EXPORT +uint32_t zng_crc32_combine_op(uint32_t crc1, uint32_t crc2, const uint32_t op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + /* various hacks, don't look :) */ + +#ifdef WITH_GZFILEOP + +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +# define @ZLIB_SYMBOL_PREFIX@zng_gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@zng_gzgetc)(g)) + +#endif /* WITH_GZFILEOP */ + + +typedef enum { + Z_DEFLATE_LEVEL = 0, /* compression level, represented as an int */ + Z_DEFLATE_STRATEGY = 1, /* compression strategy, represented as an int */ + Z_DEFLATE_REPRODUCIBLE = 2, + /* + Whether reproducible compression results are required. Represented as an int, where 0 means that it is allowed + to trade reproducibility for e.g. improved performance or compression ratio, and non-0 means that + reproducibility is strictly required. Reproducibility is guaranteed only when using an identical zlib-ng build. + Default is 0. + */ +} zng_deflate_param; + +typedef struct { + zng_deflate_param param; /* parameter ID */ + void *buf; /* parameter value */ + size_t size; /* parameter value size */ + int32_t status; /* result of the last set/get call */ +} zng_deflate_param_value; + +Z_EXTERN Z_EXPORT +int32_t zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Sets the values of the given zlib-ng deflate stream parameters. All the buffers are copied internally, so the + caller still owns them after this function returns. Returns Z_OK if success. + + If the size of at least one of the buffers is too small to hold the entire value of the corresponding parameter, + or if the same parameter is specified multiple times, Z_BUF_ERROR is returned. The caller may inspect status fields + in order to determine which of the parameters caused this error. No other changes are performed. + + If the stream state is inconsistent or if at least one of the values cannot be updated, Z_STREAM_ERROR is + returned. The caller may inspect status fields in order to determine which of the parameters caused this error. + Parameters, whose status field is equal to Z_OK, have been applied successfully. If all status fields are not equal + to Z_STREAM_ERROR, then the error was caused by a stream state inconsistency. + + If there are no other errors, but at least one parameter is not supported by the current zlib-ng version, + Z_VERSION_ERROR is returned. The caller may inspect status fields in order to determine which of the parameters + caused this error. +*/ + +Z_EXTERN Z_EXPORT +int32_t zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count); +/* + Copies the values of the given zlib-ng deflate stream parameters into the user-provided buffers. Returns Z_OK if + success, Z_VERSION_ERROR if at least one parameter is not supported by the current zlib-ng version, Z_STREAM_ERROR + if the stream state is inconsistent, and Z_BUF_ERROR if the size of at least one buffer is too small to hold the + entire value of the corresponding parameter. +*/ + +/* undocumented functions */ +Z_EXTERN Z_EXPORT const char * zng_zError (int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateSyncPoint (zng_stream *); +Z_EXTERN Z_EXPORT const uint32_t * zng_get_crc_table (void); +Z_EXTERN Z_EXPORT int32_t zng_inflateUndermine (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT int32_t zng_inflateValidate (zng_stream *, int32_t); +Z_EXTERN Z_EXPORT unsigned long zng_inflateCodesUsed (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_inflateResetKeep (zng_stream *); +Z_EXTERN Z_EXPORT int32_t zng_deflateResetKeep (zng_stream *); + +#ifdef WITH_GZFILEOP +# if defined(_WIN32) + Z_EXTERN Z_EXPORT gzFile zng_gzopen_w(const wchar_t *path, const char *mode); +# endif +Z_EXTERN Z_EXPORTVA int32_t zng_gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZNGLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.map b/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.map new file mode 100644 index 000000000..64411ab10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib-ng.map @@ -0,0 +1,111 @@ +ZLIB_NG_2.1.0 { + global: + zng_deflateInit; + zng_deflateInit2; + zng_inflateBackInit; + zng_inflateInit; + zng_inflateInit2; + zlibng_version; +}; + +ZLIB_NG_2.0.0 { + global: + zng_adler32; + zng_adler32_combine; + zng_adler32_z; + zng_compress; + zng_compress2; + zng_compressBound; + zng_crc32; + zng_crc32_combine; + zng_crc32_combine_gen; + zng_crc32_combine_op; + zng_crc32_z; + zng_deflate; + zng_deflateBound; + zng_deflateCopy; + zng_deflateEnd; + zng_deflateGetDictionary; + zng_deflateGetParams; + zng_deflateInit_; + zng_deflateInit2_; + zng_deflateParams; + zng_deflatePending; + zng_deflatePrime; + zng_deflateReset; + zng_deflateResetKeep; + zng_deflateSetDictionary; + zng_deflateSetHeader; + zng_deflateSetParams; + zng_deflateTune; + zng_get_crc_table; + zng_inflate; + zng_inflateBack; + zng_inflateBackEnd; + zng_inflateBackInit_; + zng_inflateCodesUsed; + zng_inflateCopy; + zng_inflateEnd; + zng_inflateGetDictionary; + zng_inflateGetHeader; + zng_inflateInit_; + zng_inflateInit2_; + zng_inflateMark; + zng_inflatePrime; + zng_inflateReset; + zng_inflateReset2; + zng_inflateResetKeep; + zng_inflateSetDictionary; + zng_inflateSync; + zng_inflateSyncPoint; + zng_inflateUndermine; + zng_inflateValidate; + zng_uncompress; + zng_uncompress2; + zng_zError; + zng_zlibCompileFlags; + zng_vstring; + local: + zng_deflate_copyright; + zng_inflate_copyright; + zng_zcalloc; + zng_zcfree; + zng_z_errmsg; + gz_error; + _*; +}; + +ZLIB_NG_GZ_2.0.0 { + global: + zng_gzbuffer; + zng_gzclearerr; + zng_gzclose; + zng_gzclose_r; + zng_gzclose_w; + zng_gzdirect; + zng_gzdopen; + zng_gzeof; + zng_gzerror; + zng_gzflush; + zng_gzfread; + zng_gzfwrite; + zng_gzgetc; + zng_gzgets; + zng_gzoffset; + zng_gzopen; + zng_gzprintf; + zng_gzputc; + zng_gzputs; + zng_gzread; + zng_gzrewind; + zng_gzseek; + zng_gzsetparams; + zng_gztell; + zng_gzungetc; + zng_gzvprintf; + zng_gzwrite; +}; + +FAIL { + local: *; +}; diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.h.in new file mode 100644 index 000000000..6da533c40 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.h.in @@ -0,0 +1,1855 @@ +#ifndef ZLIB_H_ +#define ZLIB_H_ +/* zlib.h -- interface of the 'zlib-ng' compression library + Forked from and compatible with zlib 1.2.13 + + Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + jloup@gzip.org madler@alumni.caltech.edu + + + The data format used by the zlib library is described by RFCs (Request for + Comments) 1950 to 1952 in the files https://tools.ietf.org/html/rfc1950 + (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format). +*/ + +#ifdef ZNGLIB_H_ +# error Include zlib-ng.h for zlib-ng API or zlib.h for zlib-compat API but not both +#endif + +#ifndef RC_INVOKED +#include +#include + +#include "zconf.h" + +#ifndef ZCONF_H +# error Missing zconf.h add binary output directory to include directories +#endif +#endif /* RC_INVOKED */ + +#ifdef __cplusplus +extern "C" { +#endif + +#define ZLIBNG_VERSION "2.1.0.beta1" +#define ZLIBNG_VERNUM 0x02010010L /* MMNNRRSM: major minor revision status modified */ +#define ZLIBNG_VER_MAJOR 2 +#define ZLIBNG_VER_MINOR 1 +#define ZLIBNG_VER_REVISION 0 +#define ZLIBNG_VER_STATUS 1 /* 0=devel, 1-E=beta, F=Release */ +#define ZLIBNG_VER_MODIFIED 0 /* non-zero if modified externally from zlib-ng */ + +#define ZLIB_VERSION "1.2.13.zlib-ng" +#define ZLIB_VERNUM 0x12df +#define ZLIB_VER_MAJOR 1 +#define ZLIB_VER_MINOR 2 +#define ZLIB_VER_REVISION 13 +#define ZLIB_VER_SUBREVISION 15 /* 15=fork (0xf) */ + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed data. + This version of the library supports only one compression method (deflation) + but other algorithms will be added later and will have the same stream + interface. + + Compression can be done in a single step if the buffers are large enough, + or can be done by repeated calls of the compression function. In the latter + case, the application must provide more input and/or consume the output + (providing more output space) before each call. + + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + + The library also supports reading and writing files in gzip (.gz) format + with an interface similar to that of stdio using the functions that start + with "gz". The gzip format is different from the zlib format. gzip is a + gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. + + This library can optionally read and write gzip and raw deflate streams in + memory as well. + + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + + The library does not install any signal handler. The decoder checks + the consistency of the compressed data, so the library should never crash + even in the case of corrupted input. +*/ + +typedef void *(*alloc_func) (void *opaque, unsigned int items, unsigned int size); +typedef void (*free_func) (void *opaque, void *address); + +struct internal_state; + +typedef struct z_stream_s { + z_const unsigned char *next_in; /* next input byte */ + uint32_t avail_in; /* number of bytes available at next_in */ + unsigned long total_in; /* total number of input bytes read so far */ + + unsigned char *next_out; /* next output byte will go here */ + uint32_t avail_out; /* remaining free space at next_out */ + unsigned long total_out; /* total number of bytes output so far */ + + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + void *opaque; /* private data object passed to zalloc and zfree */ + + int data_type; /* best guess about the data type: binary or text + for deflate, or the decoding state for inflate */ + unsigned long adler; /* Adler-32 or CRC-32 value of the uncompressed data */ + unsigned long reserved; /* reserved for future use */ +} z_stream; + +typedef z_stream *z_streamp; /* Obsolete type, retained for compatibility only */ + +/* + gzip header information passed to and from zlib routines. See RFC 1952 + for more details on the meanings of these fields. +*/ +typedef struct gz_header_s { + int text; /* true if compressed data believed to be text */ + unsigned long time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + unsigned char *extra; /* pointer to extra field or NULL if none */ + unsigned int extra_len; /* extra field length (valid if extra != NULL) */ + unsigned int extra_max; /* space at extra (only when reading header) */ + unsigned char *name; /* pointer to zero-terminated file name or NULL */ + unsigned int name_max; /* space at name (only when reading header) */ + unsigned char *comment; /* pointer to zero-terminated comment or NULL */ + unsigned int comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used when writing a gzip file) */ +} gz_header; + +typedef gz_header *gz_headerp; + +/* + The application must update next_in and avail_in when avail_in has dropped + to zero. It must update next_out and avail_out when avail_out has dropped + to zero. The application must initialize zalloc, zfree and opaque before + calling the init function. All other fields are set by the compression + library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return NULL if there is not enough memory for the object. + If zlib is used in a multi-threaded application, zalloc and zfree must be + thread safe. In that case, zlib is thread-safe. When zalloc and zfree are + Z_NULL on entry to the initialization function, they are set to internal + routines that use the standard library functions malloc() and free(). + + The fields total_in and total_out can be used for statistics or progress + reports. After compression, total_in holds the total size of the + uncompressed data and may be saved for use by the decompressor (particularly + if the decompressor wants to decompress everything in a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 +/* Allowed flush values; see deflate() and inflate() below for details */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +#define Z_VERSION_ERROR (-6) +/* Return codes for the compression/decompression functions. Negative values + * are errors, positive values are used for special but normal events. + */ + +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 +/* compression strategy; see deflateInit2() below for details */ + +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 +/* Possible values of the data_type field for deflate() */ + +#define Z_DEFLATED 8 +/* The deflate compression method (the only one supported in this version) */ + +#define Z_NULL NULL /* for compatibility with zlib, was for initializing zalloc, zfree, opaque */ + +#define zlib_version zlibVersion() +/* for compatibility with versions < 1.0.2 */ + + + /* basic functions */ + +Z_EXTERN const char * Z_EXPORT zlibVersion(void); +/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is not + compatible with the zlib.h header file used by the application. This check + is automatically made by deflateInit and inflateInit. + */ + +/* +Z_EXTERN int Z_EXPORT deflateInit (z_stream *strm, int level); + + Initializes the internal stream state for compression. The fields + zalloc, zfree and opaque must be initialized before by the caller. If + zalloc and zfree are set to NULL, deflateInit updates them to use default + allocation functions. + + The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: + 1 gives best speed, 9 gives best compression, 0 gives no compression at all + (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION + requests a default compromise between speed and compression (currently + equivalent to level 6). + + deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if level is not a valid compression level, or + Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible + with the version assumed by the caller (ZLIB_VERSION). msg is set to null + if there is no error message. deflateInit does not perform any compression: + this will be done by deflate(). +*/ + + +Z_EXTERN int Z_EXPORT deflate(z_stream *strm, int flush); +/* + deflate compresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. deflate performs one or both of the + following actions: + + - Compress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in and avail_in are updated and + processing will resume at this point for the next call of deflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. This action is forced if the parameter flush is non zero. + Forcing flush frequently degrades the compression ratio, so this parameter + should be set only when necessary. Some output may be provided even if + flush is zero. + + Before the call of deflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating avail_in or avail_out accordingly; avail_out should + never be zero before the call. The application can consume the compressed + output when it wants, for example when the output buffer is full (avail_out + == 0), or after each call of deflate(). If deflate returns Z_OK and with + zero avail_out, it must be called again after making room in the output + buffer because there might be more output pending. See deflatePending(), + which can be used if desired to determine whether or not there is more output + in that case. + + Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to + decide how much data to accumulate before producing output, in order to + maximize compression. + + If the parameter flush is set to Z_SYNC_FLUSH, all pending output is + flushed to the output buffer and the output is aligned on a byte boundary, so + that the decompressor can get all input data available so far. (In + particular avail_in is zero after the call if enough output space has been + provided before the call.) Flushing may degrade compression for some + compression algorithms and so it should be used only when necessary. This + completes the current deflate block and follows it with an empty stored block + that is three bits plus filler bits to the next byte, followed by four bytes + (00 00 ff ff). + + If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the + output buffer, but the output is not aligned to a byte boundary. All of the + input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. + This completes the current deflate block and follows it with an empty fixed + codes block that is 10 bits long. This assures that enough bytes are output + in order for the decompressor to finish the block before the empty fixed + codes block. + + If flush is set to Z_BLOCK, a deflate block is completed and emitted, as + for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to + seven bits of the current block are held to be written as the next byte after + the next deflate block is completed. In this case, the decompressor may not + be provided enough bits at this point in order to complete decompression of + the data provided so far to the compressor. It may need to wait for the next + block to be emitted. This is for advanced applications that need to control + the emission of deflate blocks. + + If flush is set to Z_FULL_FLUSH, all output is flushed as with + Z_SYNC_FLUSH, and the compression state is reset so that decompression can + restart from this point if previous compressed data has been damaged or if + random access is desired. Using Z_FULL_FLUSH too often can seriously degrade + compression. + + If deflate returns with avail_out == 0, this function must be called again + with the same value of the flush parameter and more output space (updated + avail_out), until the flush is complete (deflate returns with non-zero + avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that + avail_out is greater than six to avoid repeated flush markers due to + avail_out == 0 on return. + + If the parameter flush is set to Z_FINISH, pending input is processed, + pending output is flushed and deflate returns with Z_STREAM_END if there was + enough output space. If deflate returns with Z_OK or Z_BUF_ERROR, this + function must be called again with Z_FINISH and more output space (updated + avail_out) but no more input data, until it returns with Z_STREAM_END or an + error. After deflate has returned Z_STREAM_END, the only possible operations + on the stream are deflateReset or deflateEnd. + + Z_FINISH can be used in the first deflate call after deflateInit if all the + compression is to be done in a single step. In order to complete in one + call, avail_out must be at least the value returned by deflateBound (see + below). Then deflate is guaranteed to return Z_STREAM_END. If not enough + output space is provided, deflate will not return Z_STREAM_END, and it must + be called again as described above. + + deflate() sets strm->adler to the Adler-32 checksum of all input read + so far (that is, total_in bytes). If a gzip stream is being generated, then + strm->adler will be the CRC-32 checksum of the input read so far. (See + deflateInit2 below.) + + deflate() may update strm->data_type if it can make a good guess about + the input data type (Z_BINARY or Z_TEXT). If in doubt, the data is + considered binary. This field is only for information purposes and does not + affect the compression algorithm in any manner. + + deflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if all input has been + consumed and all output has been produced (only when flush is set to + Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example + if next_in or next_out was NULL) or the state was inadvertently written over + by the application), or Z_BUF_ERROR if no progress is possible (for example + avail_in or avail_out was zero). Note that Z_BUF_ERROR is not fatal, and + deflate() can be called again with more input and more output space to + continue compressing. +*/ + + +Z_EXTERN int Z_EXPORT deflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the + stream state was inconsistent, Z_DATA_ERROR if the stream was freed + prematurely (some input or output was discarded). In the error case, msg + may be set but then points to a static string (which must not be + deallocated). +*/ + + +/* +Z_EXTERN int Z_EXPORT inflateInit (z_stream *strm); + + Initializes the internal stream state for decompression. The fields + next_in, avail_in, zalloc, zfree and opaque must be initialized before by + the caller. In the current version of inflate, the provided input is not + read or consumed. The allocation of a sliding window will be deferred to + the first call of inflate (if the decompression does not complete on the + first call). If zalloc and zfree are set to NULL, inflateInit updates + them to use default allocation functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit does not perform any decompression. + Actual decompression will be done by inflate(). So next_in, and avail_in, + next_out, and avail_out are unused and unchanged. The current + implementation of inflateInit() does not process any header information -- + that is deferred until inflate() is called. +*/ + + +Z_EXTERN int Z_EXPORT inflate(z_stream *strm, int flush); +/* + inflate decompresses as much data as possible, and stops when the input + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. + + The detailed semantics are as follows. inflate performs one or both of the + following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), then next_in and avail_in are updated + accordingly, and processing will resume at this point for the next call of + inflate(). + + - Generate more output starting at next_out and update next_out and avail_out + accordingly. inflate() provides as much output as possible, until there is + no more input data or no more space in the output buffer (see below about + the flush parameter). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming more + output, and updating the next_* and avail_* values accordingly. If the + caller of inflate() does not provide both available input and available + output space, it is possible that there will be no progress made. The + application can consume the uncompressed output when it wants, for example + when the output buffer is full (avail_out == 0), or after each call of + inflate(). If inflate returns Z_OK and with zero avail_out, it must be + called again after making room in the output buffer because there might be + more output pending. + + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, + Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() + stop if and when it gets to the next deflate block boundary. When decoding + the zlib or gzip format, this will cause inflate() to return immediately + after the header and before the first block. When doing a raw inflate, + inflate() will go ahead and process the first block, and will return when it + gets to the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + To assist in this, on return inflate() always sets strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 if + inflate() is currently decoding the last block in the deflate stream, plus + 128 if inflate() returned immediately after decoding an end-of-block code or + decoding the complete header up to just before the first byte of the deflate + stream. The end-of-block will not be indicated until all of the uncompressed + data from that block has been written to strm->next_out. The number of + unused bits may in general be greater than seven, except when bit 7 of + data_type is set, in which case the number of unused bits will be less than + eight. data_type is set as noted here every time inflate() returns for all + flush options, and so can be used to determine the amount of currently + consumed input in bits. + + The Z_TREES option behaves as Z_BLOCK does, but it also returns when the + end of each deflate block header is reached, before any actual data in that + block is decoded. This allows the caller to determine the length of the + deflate block header for later use in random access within a deflate block. + 256 is added to the value of strm->data_type when inflate() returns + immediately after reaching the end of the deflate block header. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step (a + single call of inflate), the parameter flush should be set to Z_FINISH. In + this case all pending input is processed and all pending output is flushed; + avail_out must be large enough to hold all of the uncompressed data for the + operation to complete. (The size of the uncompressed data may have been + saved by the compressor for this purpose.) The use of Z_FINISH is not + required to perform an inflation in one step. However it may be used to + inform inflate that a faster approach can be used for the single inflate() + call. Z_FINISH also informs inflate to not maintain a sliding window if the + stream completes, which reduces inflate's memory footprint. If the stream + does not complete, either because not all of the stream is provided or not + enough output space is provided, then a sliding window will be allocated and + inflate() can be called again to continue the operation as if Z_NO_FLUSH had + been used. + + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the effects of the flush parameter in this implementation are + on the return value of inflate() as noted below, when inflate() returns early + when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of + memory for a sliding window when Z_FINISH is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the Adler-32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the Adler-32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed Adler-32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() can decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically, if requested when + initializing with inflateInit2(). Any information contained in the gzip + header is not retained unless inflateGetHeader() is used. When processing + gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output + produced so far. The CRC-32 is checked against the gzip trailer, as is the + uncompressed length, modulo 2^32. + + inflate() returns Z_OK if some progress has been made (more input processed + or more output produced), Z_STREAM_END if the end of the compressed data has + been reached and all uncompressed output has been produced, Z_NEED_DICT if a + preset dictionary is needed at this point, Z_DATA_ERROR if the input data was + corrupted (input stream not conforming to the zlib format or incorrect check + value, in which case strm->msg points to a string with a more specific + error), Z_STREAM_ERROR if the stream structure was inconsistent (for example + next_in or next_out was NULL, or the state was inadvertently written over + by the application), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR + if no progress is possible or if there was not enough room in the output + buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may + then call inflateSync() to look for a good compression block if a partial + recovery of the data is to be attempted. +*/ + + +Z_EXTERN int Z_EXPORT inflateEnd(z_stream *strm); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any pending + output. + + inflateEnd returns Z_OK if success, or Z_STREAM_ERROR if the stream state + was inconsistent. +*/ + + + /* Advanced functions */ + +/* + The following functions are needed only in some special applications. +*/ + +/* +Z_EXTERN int Z_EXPORT deflateInit2 (z_stream *strm, + int level, + int method, + int windowBits, + int memLevel, + int strategy); + + This is another version of deflateInit with more compression options. The + fields zalloc, zfree and opaque must be initialized before by the caller. + + The method parameter is the compression method. It must be Z_DEFLATED in + this version of the library. + + The windowBits parameter is the base two logarithm of the window size + (the size of the history buffer). It should be in the range 8..15 for this + version of the library. Larger values of this parameter result in better + compression at the expense of memory usage. The default value is 15 if + deflateInit is used instead. + + For the current implementation of deflate(), a windowBits value of 8 (a + window size of 256 bytes) is not supported. As a result, a request for 8 + will result in 9 (a 512-byte window). In that case, providing 8 to + inflateInit2() will result in an error when the zlib header with 9 is + checked against the initialization of inflate(). The remedy is to not use 8 + with deflateInit2() with this initialization, or at least in that case use 9 + with inflateInit2(). + + windowBits can also be -8..-15 for raw deflate. In this case, -windowBits + determines the window size. deflate() will then generate raw deflate data + with no zlib header or trailer, and will not compute a check value. + + windowBits can also be greater than 15 for optional gzip encoding. Add + 16 to windowBits to write a simple gzip header and trailer around the + compressed data instead of a zlib wrapper. The gzip header will have no + file name, no extra data, no comment, no modification time (set to zero), no + header crc, and the operating system will be set to the appropriate value, + if the operating system was determined at compile time. If a gzip stream is + being written, strm->adler is a CRC-32 instead of an Adler-32. + + For raw deflate or gzip encoding, a request for a 256-byte window is + rejected as invalid, since only the zlib header provides a means of + transmitting the window size to the decompressor. + + The memLevel parameter specifies how much memory should be allocated + for the internal compression state. memLevel=1 uses minimum memory but is + slow and reduces compression ratio; memLevel=9 uses maximum memory for + optimal speed. The default value is 8. See zconf.h for total memory usage + as a function of windowBits and memLevel. + + The strategy parameter is used to tune the compression algorithm. Use the + value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a + filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no + string match), or Z_RLE to limit match distances to one (run-length + encoding). Filtered data consists mostly of small values with a somewhat + random distribution. In this case, the compression algorithm is tuned to + compress them better. The effect of Z_FILTERED is to force more Huffman + coding and less string matching; it is somewhat intermediate between + Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as + fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The + strategy parameter only affects the compression ratio but not the + correctness of the compressed output even if it is not set appropriately. + Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler + decoder for special applications. + + deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid + method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is + incompatible with the version assumed by the caller (ZLIB_VERSION). msg is + set to null if there is no error message. deflateInit2 does not perform any + compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateSetDictionary(z_stream *strm, + const unsigned char *dictionary, + unsigned int dictLength); +/* + Initializes the compression dictionary from the given byte sequence + without producing any compressed output. When using the zlib format, this + function must be called immediately after deflateInit, deflateInit2 or + deflateReset, and before any call of deflate. When doing raw deflate, this + function must be called either before any call of deflate, or immediately + after the completion of a deflate block, i.e. after all input has been + consumed and all output has been delivered when using any of the flush + options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The + compressor and decompressor must use exactly the same dictionary (see + inflateSetDictionary). + + The dictionary should consist of strings (byte sequences) that are likely + to be encountered later in the data to be compressed, with the most commonly + used strings preferably put towards the end of the dictionary. Using a + dictionary is most useful when the data to be compressed is short and can be + predicted with good accuracy; the data can then be compressed better than + with the default empty dictionary. + + Depending on the size of the compression data structures selected by + deflateInit or deflateInit2, a part of the dictionary may in effect be + discarded, for example if the dictionary is larger than the window size + provided in deflateInit or deflateInit2. Thus the strings most likely to be + useful should be put at the end of the dictionary, not at the front. In + addition, the current implementation of deflate will use at most the window + size minus 262 bytes of the provided dictionary. + + Upon return of this function, strm->adler is set to the Adler-32 value + of the dictionary; the decompressor may later use this value to determine + which dictionary has been used by the compressor. (The Adler-32 value + applies to the whole dictionary even if only a subset of the dictionary is + actually used by the compressor.) If a raw deflate was requested, then the + Adler-32 value is not computed and strm->adler is not set. + + deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent (for example if deflate has already been called for this stream + or if not at a block boundary for raw deflate). deflateSetDictionary does + not perform any compression: this will be done by deflate(). +*/ + +Z_EXTERN int Z_EXPORT deflateGetDictionary (z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by deflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If deflateGetDictionary() is called with dictionary equal to + Z_NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is Z_NULL, then it is not set. + + deflateGetDictionary() may return a length less than the window size, even + when more than the window size in input has been provided. It may return up + to 258 bytes less in that case, due to how zlib's implementation of deflate + manages the sliding window and lookahead for matches, where matches can be + up to 258 bytes long. If the application needs the last window-size bytes of + input, then that would need to be saved by the application outside of zlib. + + deflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when several compression strategies will be + tried, for example when there are several ways of pre-processing the input + data with a filter. The streams that will be discarded should then be freed + by calling deflateEnd. Note that deflateCopy duplicates the internal + compression state which can be quite large, so this strategy is slow and can + consume lots of memory. + + deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT deflateReset(z_stream *strm); +/* + This function is equivalent to deflateEnd followed by deflateInit, but + does not free and reallocate the internal compression state. The stream + will leave the compression level and any other attributes that may have been + set unchanged. + + deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT deflateParams(z_stream *strm, int level, int strategy); +/* + Dynamically update the compression level and compression strategy. The + interpretation of level and strategy is as in deflateInit2(). This can be + used to switch between compression and straight copy of the input data, or + to switch to a different kind of input data requiring a different strategy. + If the compression approach (which is a function of the level) or the + strategy is changed, and if there have been any deflate() calls since the + state was initialized or reset, then the input available so far is + compressed with the old level and strategy using deflate(strm, Z_BLOCK). + There are three approaches for the compression levels 0, 1..3, and 4..9 + respectively. The new level and strategy will take effect at the next call + of deflate(). + + If a deflate(strm, Z_BLOCK) is performed by deflateParams(), and it does + not have enough output space to complete, then the parameter change will not + take effect. In this case, deflateParams() can be called again with the + same parameters and more output space to try again. + + In order to assure a change in the parameters on the first try, the + deflate stream should be flushed using deflate() with Z_BLOCK or other flush + request until strm.avail_out is not zero, before calling deflateParams(). + Then no more input data should be provided before the deflateParams() call. + If this is done, the old level and strategy will be applied to the data + compressed before deflateParams(), and the new level and strategy will be + applied to the the data compressed after deflateParams(). + + deflateParams returns Z_OK on success, Z_STREAM_ERROR if the source stream + state was inconsistent or if a parameter was invalid, or Z_BUF_ERROR if + there was not enough output space to complete the compression of the + available input data before a change in the strategy or approach. Note that + in the case of a Z_BUF_ERROR, the parameters are not changed. A return + value of Z_BUF_ERROR is not fatal, in which case deflateParams() can be + retried with more output space. +*/ + +Z_EXTERN int Z_EXPORT deflateTune(z_stream *strm, int good_length, int max_lazy, int nice_length, int max_chain); +/* + Fine tune deflate's internal compression parameters. This should only be + used by someone who understands the algorithm used by zlib's deflate for + searching for the best matching string, and even then only by the most + fanatic optimizer trying to squeeze out the last compressed bit for their + specific input data. Read the deflate.c source code for the meaning of the + max_lazy, good_length, nice_length, and max_chain parameters. + + deflateTune() can be called after deflateInit() or deflateInit2(), and + returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. + */ + +Z_EXTERN unsigned long Z_EXPORT deflateBound(z_stream *strm, unsigned long sourceLen); +/* + deflateBound() returns an upper bound on the compressed size after + deflation of sourceLen bytes. It must be called after deflateInit() or + deflateInit2(), and after deflateSetHeader(), if used. This would be used + to allocate an output buffer for deflation in a single pass, and so would be + called before deflate(). If that first deflate() call is provided the + sourceLen input bytes, an output buffer allocated to the size returned by + deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed + to return Z_STREAM_END. Note that it is possible for the compressed size to + be larger than the value returned by deflateBound() if flush options other + than Z_FINISH or Z_NO_FLUSH are used. +*/ + +Z_EXTERN int Z_EXPORT deflatePending(z_stream *strm, uint32_t *pending, int *bits); +/* + deflatePending() returns the number of bytes and bits of output that have + been generated, but not yet provided in the available output. The bytes not + provided would be due to the available output space having being consumed. + The number of bits of output not provided are between 0 and 7, where they + await more bits to join them in order to fill out a full byte. If pending + or bits are NULL, then those values are not set. + + deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. + */ + +Z_EXTERN int Z_EXPORT deflatePrime(z_stream *strm, int bits, int value); +/* + deflatePrime() inserts bits in the deflate output stream. The intent + is that this function is used to start off the deflate output with the bits + leftover from a previous deflate stream when appending to it. As such, this + function can only be used for raw deflate, and must be used before the first + deflate() call after a deflateInit2() or deflateReset(). bits must be less + than or equal to 16, and that many of the least significant bits of value + will be inserted in the output. + + deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough + room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT deflateSetHeader(z_stream *strm, gz_headerp head); +/* + deflateSetHeader() provides gzip header information for when a gzip + stream is requested by deflateInit2(). deflateSetHeader() may be called + after deflateInit2() or deflateReset() and before the first call of + deflate(). The text, time, os, extra field, name, and comment information + in the provided gz_header structure are written to the gzip header (xflag is + ignored -- the extra flags are set according to the compression level). The + caller must assure that, if not NULL, name and comment are terminated with + a zero byte, and that if extra is not NULL, that extra_len bytes are + available there. If hcrc is true, a gzip header crc is included. Note that + the current versions of the command-line version of gzip (up through version + 1.3.x) do not support header crc's, and will report that it is a "multi-part + gzip file" and give up. + + If deflateSetHeader is not used, the default gzip header has text false, + the time set to zero, and os set to 255, with no extra, name, or comment + fields. The gzip header is returned to the default state by deflateReset(). + + deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateInit2(z_stream *strm, int windowBits); + + This is another version of inflateInit with an extra parameter. The + fields next_in, avail_in, zalloc, zfree and opaque must be initialized + before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library. The default value is 15 if inflateInit is used + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be zero to request that inflate use the window size in + the zlib header of the compressed stream. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an Adler-32 or a CRC-32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a + CRC-32 instead of an Adler-32. Unlike the gunzip utility and gzread() (see + below), inflate() will *not* automatically decode concatenated gzip members. + inflate() will return Z_STREAM_END at the end of the gzip member. The state + would need to be reset to continue decoding a subsequent gzip member. This + *must* be done if there is more data after a gzip member, in order for the + decompression to be compliant with the gzip standard (RFC 1952). + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_VERSION_ERROR if the zlib library version is incompatible with the + version assumed by the caller, or Z_STREAM_ERROR if the parameters are + invalid, such as a null pointer to the structure. msg is set to null if + there is no error message. inflateInit2 does not perform any decompression + apart from possibly reading the zlib header if present: actual decompression + will be done by inflate(). (So next_in and avail_in may be modified, but + next_out and avail_out are unused and unchanged.) The current implementation + of inflateInit2() does not process any header information -- that is + deferred until inflate() is called. +*/ + +Z_EXTERN int Z_EXPORT inflateSetDictionary(z_stream *strm, const unsigned char *dictionary, unsigned int dictLength); +/* + Initializes the decompression dictionary from the given uncompressed byte + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the Adler-32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called at any + time to set the dictionary. If the provided dictionary is smaller than the + window and there is already data in the window, then the provided dictionary + will amend what's there. The application must insure that the dictionary + that was used for compression is provided. + + inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a + parameter is invalid (e.g. dictionary being NULL) or the stream state is + inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the + expected one (incorrect Adler-32 value). inflateSetDictionary does not + perform any decompression: this will be done by subsequent calls of + inflate(). +*/ + +Z_EXTERN int Z_EXPORT inflateGetDictionary(z_stream *strm, unsigned char *dictionary, unsigned int *dictLength); +/* + Returns the sliding dictionary being maintained by inflate. dictLength is + set to the number of bytes in the dictionary, and that many bytes are copied + to dictionary. dictionary must have enough space, where 32768 bytes is + always enough. If inflateGetDictionary() is called with dictionary equal to + NULL, then only the dictionary length is returned, and nothing is copied. + Similarly, if dictLength is NULL, then it is not set. + + inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the + stream state is inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateSync(z_stream *strm); +/* + Skips invalid compressed data until a possible full flush point (see above + for the description of deflate with Z_FULL_FLUSH) can be found, or until all + available input is skipped. No output is provided. + + inflateSync searches for a 00 00 FF FF pattern in the compressed data. + All full flush points have this pattern, but not all occurrences of this + pattern are full flush points. + + inflateSync returns Z_OK if a possible full flush point has been found, + Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point + has been found, or Z_STREAM_ERROR if the stream structure was inconsistent. + In the success case, the application may save the current current value of + total_in which indicates where valid compressed data was found. In the + error case, the application may repeatedly call inflateSync, providing more + input each time, until success or end of the input data. +*/ + +Z_EXTERN int Z_EXPORT inflateCopy(z_stream *dest, z_stream *source); +/* + Sets the destination stream as a complete copy of the source stream. + + This function can be useful when randomly accessing a large stream. The + first pass through the stream can periodically record the inflate state, + allowing restarting inflate at those points when randomly accessing the + stream. + + inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_STREAM_ERROR if the source stream state was inconsistent + (such as zalloc being NULL). msg is left unchanged in both source and + destination. +*/ + +Z_EXTERN int Z_EXPORT inflateReset(z_stream *strm); +/* + This function is equivalent to inflateEnd followed by inflateInit, + but does not free and reallocate the internal decompression state. The + stream will keep attributes that may have been set by inflateInit2. + + inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL). +*/ + +Z_EXTERN int Z_EXPORT inflateReset2(z_stream *strm, int windowBits); +/* + This function is the same as inflateReset, but it also permits changing + the wrap and window size requests. The windowBits parameter is interpreted + the same as it is for inflateInit2. If the window size is changed, then the + memory allocated for the window is freed, and the window will be reallocated + by inflate() if needed. + + inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent (such as zalloc or state being NULL), or if + the windowBits parameter is invalid. +*/ + +Z_EXTERN int Z_EXPORT inflatePrime(z_stream *strm, int bits, int value); +/* + This function inserts bits in the inflate input stream. The intent is + that this function is used to start inflating at a bit position in the + middle of a byte. The provided bits will be used before any bytes are used + from next_in. This function should only be used with raw inflate, and + should be used before the first inflate() call after inflateInit2() or + inflateReset(). bits must be less than or equal to 16, and that many of the + least significant bits of value will be inserted in the input. + + If bits is negative, then the input stream bit buffer is emptied. Then + inflatePrime() can be called again to put bits in the buffer. This is used + to clear out bits leftover after feeding inflate a block description prior + to feeding inflate codes. + + inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +Z_EXTERN long Z_EXPORT inflateMark(z_stream *strm); +/* + This function returns two values, one in the lower 16 bits of the return + value, and the other in the remaining upper bits, obtained by shifting the + return value down 16 bits. If the upper value is -1 and the lower value is + zero, then inflate() is currently decoding information outside of a block. + If the upper value is -1 and the lower value is non-zero, then inflate is in + the middle of a stored block, with the lower value equaling the number of + bytes from the input remaining to copy. If the upper value is not -1, then + it is the number of bits back from the current bit position in the input of + the code (literal or length/distance pair) currently being processed. In + that case the lower value is the number of bytes already emitted for that + code. + + A code is being processed if inflate is waiting for more input to complete + decoding of the code, or if it has completed decoding but is waiting for + more output space to write the literal or match data. + + inflateMark() is used to mark locations in the input data for random + access, which may be at bit positions, and to note those cases where the + output of a code may span boundaries of random access blocks. The current + location in the input stream can be determined from avail_in and data_type + as noted in the description for the Z_BLOCK flush parameter for inflate. + + inflateMark returns the value noted above, or -65536 if the provided + source stream state was inconsistent. +*/ + +Z_EXTERN int Z_EXPORT inflateGetHeader(z_stream *strm, gz_headerp head); +/* + inflateGetHeader() requests that gzip header information be stored in the + provided gz_header structure. inflateGetHeader() may be called after + inflateInit2() or inflateReset(), and before the first call of inflate(). + As inflate() processes the gzip stream, head->done is zero until the header + is completed, at which time head->done is set to one. If a zlib stream is + being decoded, then head->done is set to -1 to indicate that there will be + no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be + used to force inflate() to return immediately after header processing is + complete and before any actual data is decompressed. + + The text, time, xflags, and os fields are filled in with the gzip header + contents. hcrc is set to true if there is a header CRC. (The header CRC + was valid if done is set to one.) If extra is not NULL, then extra_max + contains the maximum number of bytes to write to extra. Once done is true, + extra_len contains the actual extra field length, and extra contains the + extra field, or that field truncated if extra_max is less than extra_len. + If name is not NULL, then up to name_max characters are written there, + terminated with a zero unless the length is greater than name_max. If + comment is not NULL, then up to comm_max characters are written there, + terminated with a zero unless the length is greater than comm_max. When any + of extra, name, or comment are not NULL and the respective field is not + present in the header, then that field is set to NULL to signal its + absence. This allows the use of deflateSetHeader() with the returned + structure to duplicate the header. However if those fields are set to + allocated memory, then the application will need to save those pointers + elsewhere so that they can be eventually freed. + + If inflateGetHeader is not used, then the header information is simply + discarded. The header is always checked for validity, including the header + CRC if present. inflateReset() will reset the process to discard the header + information. The application would need to call inflateGetHeader() again to + retrieve the header from the next gzip stream. + + inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source + stream state was inconsistent. +*/ + +/* +Z_EXTERN int Z_EXPORT inflateBackInit (z_stream *strm, int windowBits, unsigned char *window); + + Initialize the internal stream state for decompression using inflateBack() + calls. The fields zalloc, zfree and opaque in strm must be initialized + before the call. If zalloc and zfree are NULL, then the default library- + derived memory allocation routines are used. windowBits is the base two + logarithm of the window size, in the range 8..15. window is a caller + supplied buffer of that size. Except for special applications where it is + assured that deflate was used with small window sizes, windowBits must be 15 + and a 32K byte window must be supplied to be able to decompress general + deflate streams. + + See inflateBack() for the usage of these routines. + + inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of + the parameters are invalid, Z_MEM_ERROR if the internal state could not be + allocated, or Z_VERSION_ERROR if the version of the library does not match + the version of the header file. +*/ + +typedef uint32_t (*in_func) (void *, z_const unsigned char * *); +typedef int (*out_func) (void *, unsigned char *, uint32_t); + +Z_EXTERN int Z_EXPORT inflateBack(z_stream *strm, in_func in, void *in_desc, out_func out, void *out_desc); +/* + inflateBack() does a raw inflate with a single call using a call-back + interface for input and output. This is potentially more efficient than + inflate() for file i/o applications, in that it avoids copying between the + output and the sliding window by simply making the window itself the output + buffer. inflate() can be faster on modern CPUs when used with large + buffers. inflateBack() trusts the application to not change the output + buffer passed by the output function, at least until inflateBack() returns. + + inflateBackInit() must be called first to allocate the internal state + and to initialize the state with the user-provided window buffer. + inflateBack() may then be used multiple times to inflate a complete, raw + deflate stream with each call. inflateBackEnd() is then called to free the + allocated state. + + A raw deflate stream is one with no zlib or gzip header or trailer. + This routine would normally be used in a utility that reads zip or gzip + files and writes out uncompressed files. The utility would decode the + header and process the trailer on its own, hence this routine expects only + the raw deflate stream to decompress. This is different from the default + behavior of inflate(), which expects a zlib header and trailer around the + deflate stream. + + inflateBack() uses two subroutines supplied by the caller that are then + called by inflateBack() for input and output. inflateBack() calls those + routines until it reads a complete deflate stream and writes out all of the + uncompressed data, or until it encounters an error. The function's + parameters and return types are defined above in the in_func and out_func + typedefs. inflateBack() will call in(in_desc, &buf) which should return the + number of bytes of provided input, and a pointer to that input in buf. If + there is no input available, in() must return zero -- buf is ignored in that + case -- and inflateBack() will return a buffer error. inflateBack() will + call out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. + out() should return zero on success, or non-zero on failure. If out() + returns non-zero, inflateBack() will return with an error. Neither in() nor + out() are permitted to change the contents of the window provided to + inflateBackInit(), which is also the buffer that out() uses to write from. + The length written by out() will be at most the window size. Any non-zero + amount of input may be provided by in(). + + For convenience, inflateBack() can be provided input on the first call by + setting strm->next_in and strm->avail_in. If that input is exhausted, then + in() will be called. Therefore strm->next_in must be initialized before + calling inflateBack(). If strm->next_in is NULL, then in() will be called + immediately for input. If strm->next_in is not NULL, then strm->avail_in + must also be initialized, and then if strm->avail_in is not zero, input will + initially be taken from strm->next_in[0 .. strm->avail_in - 1]. + + The in_desc and out_desc parameters of inflateBack() is passed as the + first parameter of in() and out() respectively when they are called. These + descriptors can be optionally used to pass any information that the caller- + supplied in() and out() functions need to do their job. + + On return, inflateBack() will set strm->next_in and strm->avail_in to + pass back any unused input that was provided by the last in() call. The + return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR + if in() or out() returned an error, Z_DATA_ERROR if there was a format error + in the deflate stream (in which case strm->msg is set to indicate the nature + of the error), or Z_STREAM_ERROR if the stream was not properly initialized. + In the case of Z_BUF_ERROR, an input or output error can be distinguished + using strm->next_in which will be NULL only if in() returned an error. If + strm->next_in is not NULL, then the Z_BUF_ERROR was due to out() returning + non-zero. (in() will always be called before out(), so strm->next_in is + assured to be defined if out() returns non-zero.) Note that inflateBack() + cannot return Z_OK. +*/ + +Z_EXTERN int Z_EXPORT inflateBackEnd(z_stream *strm); +/* + All memory allocated by inflateBackInit() is freed. + + inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream + state was inconsistent. +*/ + +Z_EXTERN unsigned long Z_EXPORT zlibCompileFlags(void); +/* Return flags indicating compile-time options. + + Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: + 1.0: size of unsigned int + 3.2: size of unsigned long + 5.4: size of void * (pointer) + 7.6: size of z_off_t + + Compiler, assembler, and debug options: + 8: ZLIB_DEBUG + 9: ASMV or ASMINF -- use ASM code + 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention + 11: 0 (reserved) + + One-time table building (smaller code, but not thread-safe if true): + 12: BUILDFIXED -- build static block decoding tables when needed (not supported by zlib-ng) + 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed + 14,15: 0 (reserved) + + Library content (indicates missing functionality): + 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking + deflate code when not needed) + 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect + and decode gzip streams (to avoid linking crc code) + 18-19: 0 (reserved) + + Operation variations (changes in library functionality): + 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate + 21: FASTEST -- deflate algorithm with only one, lowest compression level + 22,23: 0 (reserved) + + The sprintf variant used by gzprintf (zero is best): + 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format + 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! + 26: 0 = returns value, 1 = void -- 1 means inferred string length returned + + Remainder: + 27-31: 0 (reserved) + */ + + +#ifndef Z_SOLO + + /* utility functions */ + +/* + The following utility functions are implemented on top of the basic + stream-oriented functions. To simplify the interface, some default options + are assumed (compression level and memory usage, standard memory allocation + functions). The source code of these utility functions can be modified if + you need special options. +*/ + +Z_EXTERN int Z_EXPORT compress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Compresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. compress() is equivalent to compress2() with a level + parameter of Z_DEFAULT_COMPRESSION. + + compress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer. +*/ + +Z_EXTERN int Z_EXPORT compress2(unsigned char *dest, unsigned long *destLen, const unsigned char *source, + unsigned long sourceLen, int level); +/* + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least the value returned by + compressBound(sourceLen). Upon exit, destLen is the actual size of the + compressed data. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ + +Z_EXTERN unsigned long Z_EXPORT compressBound(unsigned long sourceLen); +/* + compressBound() returns an upper bound on the compressed size after + compress() or compress2() on sourceLen bytes. It would be used before a + compress() or compress2() call to allocate the destination buffer. +*/ + +Z_EXTERN int Z_EXPORT uncompress(unsigned char *dest, unsigned long *destLen, const unsigned char *source, unsigned long sourceLen); +/* + Decompresses the source buffer into the destination buffer. sourceLen is + the byte length of the source buffer. Upon entry, destLen is the total size + of the destination buffer, which must be large enough to hold the entire + uncompressed data. (The size of the uncompressed data must have been saved + previously by the compressor and transmitted to the decompressor by some + mechanism outside the scope of this compression library.) Upon exit, destLen + is the actual size of the uncompressed data. + + uncompress returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory, Z_BUF_ERROR if there was not enough room in the output + buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In + the case where there is not enough room, uncompress() will fill the output + buffer with the uncompressed data up to that point. +*/ + + +Z_EXTERN int Z_EXPORT uncompress2 (unsigned char *dest, unsigned long *destLen, + const unsigned char *source, unsigned long *sourceLen); +/* + Same as uncompress, except that sourceLen is a pointer, where the + length of the source is *sourceLen. On return, *sourceLen is the number of + source bytes consumed. +*/ + + + /* gzip file access functions */ + +/* + This library supports reading and writing files in gzip (.gz) format with + an interface similar to that of stdio, using the functions that start with + "gz". The gzip format is different from the zlib format. gzip is a gzip + wrapper, documented in RFC 1952, wrapped around a deflate stream. +*/ + +typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + +/* +Z_EXTERN gzFile Z_EXPORT gzopen(const char *path, const char *mode); + + Open the gzip (.gz) file at path for reading and decompressing, or + compressing and writing. The mode parameter is as in fopen ("rb" or "wb") + but can also include a compression level ("wb9") or a strategy: 'f' for + filtered data as in "wb6f", 'h' for Huffman-only compression as in "wb1h", + 'R' for run-length encoding as in "wb1R", or 'F' for fixed code compression + as in "wb9F". (See the description of deflateInit2 for more information + about the strategy parameter.) 'T' will request transparent writing or + appending with no compression and not using the gzip format. + + "a" can be used instead of "w" to request that the gzip stream that will + be written be appended to the file. "+" will result in an error, since + reading and writing to the same gzip file is not supported. The addition of + "x" when writing will create the file exclusively, which fails if the file + already exists. On systems that support it, the addition of "e" when + reading or writing will set the flag to close the file on an execve() call. + + These functions, as well as gzip, will read and decode a sequence of gzip + streams in a file. The append function of gzopen() can be used to create + such a file. (Also see gzflush() for another way to do this.) When + appending, gzopen does not test whether the file begins with a gzip stream, + nor does it look for the end of the gzip streams to begin appending. gzopen + will simply append a gzip stream to the existing file. + + gzopen can be used to read a file which is not in gzip format; in this + case gzread will directly read from the file without decompression. When + reading, this will be detected automatically by looking for the magic two- + byte gzip header. + + gzopen returns NULL if the file could not be opened, if there was + insufficient memory to allocate the gzFile state, or if an invalid mode was + specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). + errno can be checked to determine if the reason gzopen failed was that the + file could not be opened. +*/ + +Z_EXTERN gzFile Z_EXPORT gzdopen(int fd, const char *mode); +/* + Associate a gzFile with the file descriptor fd. File descriptors are + obtained from calls like open, dup, creat, pipe or fileno (if the file has + been previously opened with fopen). The mode parameter is as in gzopen. + + The next call of gzclose on the returned gzFile will also close the file + descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor + fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, + mode);. The duplicated descriptor should be saved to avoid a leak, since + gzdopen does not close fd if it fails. If you are using fileno() to get the + file descriptor from a FILE *, then you will have to use dup() to avoid + double-close()ing the file descriptor. Both gzclose() and fclose() will + close the associated file descriptor, so they need to have different file + descriptors. + + gzdopen returns NULL if there was insufficient memory to allocate the + gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not + provided, or '+' was provided), or if fd is -1. The file descriptor is not + used until the next gz* read, write, seek, or close operation, so gzdopen + will not detect if fd is invalid (unless fd is -1). +*/ + +Z_EXTERN int Z_EXPORT gzbuffer(gzFile file, unsigned size); +/* + Set the internal buffer size used by this library's functions for file to + size. The default buffer size is 8192 bytes. This function must be called + after gzopen() or gzdopen(), and before any other calls that read or write + the file. The buffer memory allocation is always deferred to the first read + or write. Three times that size in buffer space is allocated. A larger + buffer size of, for example, 64K or 128K bytes will noticeably increase the + speed of decompression (reading). + + The new buffer size also affects the maximum length for gzprintf(). + + gzbuffer() returns 0 on success, or -1 on failure, such as being called + too late. +*/ + +Z_EXTERN int Z_EXPORT gzsetparams(gzFile file, int level, int strategy); +/* + Dynamically update the compression level and strategy for file. See the + description of deflateInit2 for the meaning of these parameters. Previously + provided data is flushed before applying the parameter changes. + + gzsetparams returns Z_OK if success, Z_STREAM_ERROR if the file was not + opened for writing, Z_ERRNO if there is an error writing the flushed data, + or Z_MEM_ERROR if there is a memory allocation error. +*/ + +Z_EXTERN int Z_EXPORT gzread(gzFile file, void *buf, unsigned len); +/* + Read and decompress up to len uncompressed bytes from file into buf. If + the input file is not in gzip format, gzread copies the given number of + bytes into the buffer directly from the file. + + After reaching the end of a gzip stream in the input, gzread will continue + to read, looking for another gzip stream. Any number of gzip streams may be + concatenated in the input file, and will all be decompressed by gzread(). + If something other than a gzip stream is encountered after a gzip stream, + that remaining trailing garbage is ignored (and no error is returned). + + gzread can be used to read a gzip file that is being concurrently written. + Upon reaching the end of the input, gzread will return with the available + data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then + gzclearerr can be used to clear the end of file indicator in order to permit + gzread to be tried again. Z_OK indicates that a gzip stream was completed + on the last gzread. Z_BUF_ERROR indicates that the input file ended in the + middle of a gzip stream. Note that gzread does not return -1 in the event + of an incomplete gzip stream. This error is deferred until gzclose(), which + will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip + stream. Alternatively, gzerror can be used before gzclose to detect this + case. + + gzread returns the number of uncompressed bytes actually read, less than + len for end of file, or -1 for error. If len is too large to fit in an int, + then nothing is read, -1 is returned, and the error state is set to + Z_STREAM_ERROR. +*/ + +Z_EXTERN size_t Z_EXPORT gzfread (void *buf, size_t size, size_t nitems, gzFile file); +/* + Read and decompress up to nitems items of size size from file into buf, + otherwise operating as gzread() does. This duplicates the interface of + stdio's fread(), with size_t request and return types. If the library + defines size_t, then z_size_t is identical to size_t. If not, then z_size_t + is an unsigned integer type that can contain a pointer. + + gzfread() returns the number of full items read of size size, or zero if + the end of the file was reached and a full item could not be read, or if + there was an error. gzerror() must be consulted if zero is returned in + order to determine if there was an error. If the multiplication of size and + nitems overflows, i.e. the product does not fit in a size_t, then nothing + is read, zero is returned, and the error state is set to Z_STREAM_ERROR. + + In the event that the end of file is reached and only a partial item is + available at the end, i.e. the remaining uncompressed data length is not a + multiple of size, then the final partial item is nevertheless read into buf + and the end-of-file flag is set. The length of the partial item read is not + provided, but could be inferred from the result of gztell(). This behavior + is the same as the behavior of fread() implementations in common libraries, + but it prevents the direct use of gzfread() to read a concurrently written + file, resetting and retrying on end-of-file, when size is not 1. +*/ + +Z_EXTERN int Z_EXPORT gzwrite(gzFile file, void const *buf, unsigned len); +/* + Compress and write the len uncompressed bytes at buf to file. gzwrite + returns the number of uncompressed bytes written or 0 in case of error. +*/ + +Z_EXTERN size_t Z_EXPORT gzfwrite(void const *buf, size_t size, size_t nitems, gzFile file); +/* + Compress and write nitems items of size size from buf to file, duplicating + the interface of stdio's fwrite(), with size_t request and return types. + + gzfwrite() returns the number of full items written of size size, or zero + if there was an error. If the multiplication of size and nitems overflows, + i.e. the product does not fit in a size_t, then nothing is written, zero + is returned, and the error state is set to Z_STREAM_ERROR. +*/ + +Z_EXTERN int Z_EXPORTVA gzprintf(gzFile file, const char *format, ...); +/* + Convert, format, compress, and write the arguments (...) to file under + control of the string format, as in fprintf. gzprintf returns the number of + uncompressed bytes actually written, or a negative zlib error code in case + of error. The number of uncompressed bytes written is limited to 8191, or + one less than the buffer size given to gzbuffer(). The caller should assure + that this limit is not exceeded. If it is exceeded, then gzprintf() will + return an error (0) with nothing written. In this case, there may also be a + buffer overflow with unpredictable consequences, which is possible only if + zlib was compiled with the insecure functions sprintf() or vsprintf(), + because the secure snprintf() or vsnprintf() functions were not available. + This can be determined using zlibCompileFlags(). +*/ + +Z_EXTERN int Z_EXPORT gzputs(gzFile file, const char *s); +/* + Compress and write the given null-terminated string s to file, excluding + the terminating null character. + + gzputs returns the number of characters written, or -1 in case of error. +*/ + +Z_EXTERN char * Z_EXPORT gzgets(gzFile file, char *buf, int len); +/* + Read and decompress bytes from file into buf, until len-1 characters are + read, or until a newline character is read and transferred to buf, or an + end-of-file condition is encountered. If any characters are read or if len + is one, the string is terminated with a null character. If no characters + are read due to an end-of-file or len is less than one, then the buffer is + left untouched. + + gzgets returns buf which is a null-terminated string, or it returns NULL + for end-of-file or in case of error. If there was an error, the contents at + buf are indeterminate. +*/ + +Z_EXTERN int Z_EXPORT gzputc(gzFile file, int c); +/* + Compress and write c, converted to an unsigned char, into file. gzputc + returns the value that was written, or -1 in case of error. +*/ + +Z_EXTERN int Z_EXPORT gzgetc(gzFile file); +/* + Read and decompress one byte from file. gzgetc returns this byte or -1 + in case of end of file or error. This is implemented as a macro for speed. + As such, it does not do all of the checking the other functions do. I.e. + it does not check to see if file is NULL, nor whether the structure file + points to has been clobbered or not. +*/ + +Z_EXTERN int Z_EXPORT gzungetc(int c, gzFile file); +/* + Push c back onto the stream for file to be read as the first character on + the next read. At least one character of push-back is always allowed. + gzungetc() returns the character pushed, or -1 on failure. gzungetc() will + fail if c is -1, and may fail if a character has been pushed but not read + yet. If gzungetc is used immediately after gzopen or gzdopen, at least the + output buffer size of pushed characters is allowed. (See gzbuffer above.) + The pushed character will be discarded if the stream is repositioned with + gzseek() or gzrewind(). +*/ + +Z_EXTERN int Z_EXPORT gzflush(gzFile file, int flush); +/* + Flush all pending output to file. The parameter flush is as in the + deflate() function. The return value is the zlib error number (see function + gzerror below). gzflush is only permitted when writing. + + If the flush parameter is Z_FINISH, the remaining data is written and the + gzip stream is completed in the output. If gzwrite() is called again, a new + gzip stream will be started in the output. gzread() is able to read such + concatenated gzip streams. + + gzflush should be called only when strictly necessary because it will + degrade compression if called too often. +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzseek (gzFile file, z_off_t offset, int whence); + + Set the starting position to offset relative to whence for the next gzread + or gzwrite on file. The offset represents a number of bytes in the + uncompressed data stream. The whence parameter is defined as in lseek(2); + the value SEEK_END is not supported. + + If the file is opened for reading, this function is emulated but can be + extremely slow. If the file is opened for writing, only forward seeks are + supported; gzseek then compresses a sequence of zeroes up to the new + starting position. + + gzseek returns the resulting offset location as measured in bytes from + the beginning of the uncompressed stream, or -1 in case of error, in + particular if the file is opened for writing and the new starting position + would be before the current position. +*/ + +Z_EXTERN int Z_EXPORT gzrewind(gzFile file); +/* + Rewind file. This function is supported only for reading. + + gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET). +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gztell(gzFile file); + + Return the starting position for the next gzread or gzwrite on file. + This position represents a number of bytes in the uncompressed data stream, + and is zero when starting, even if appending or reading a gzip stream from + the middle of a file using gzdopen(). + + gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) +*/ + +/* +Z_EXTERN z_off_t Z_EXPORT gzoffset(gzFile file); + + Return the current compressed (actual) read or write offset of file. This + offset includes the count of bytes that precede the gzip stream, for example + when appending or when using gzdopen() for reading. When reading, the + offset does not include as yet unused buffered input. This information can + be used for a progress indicator. On error, gzoffset() returns -1. +*/ + +Z_EXTERN int Z_EXPORT gzeof(gzFile file); +/* + Return true (1) if the end-of-file indicator for file has been set while + reading, false (0) otherwise. Note that the end-of-file indicator is set + only if the read tried to go past the end of the input, but came up short. + Therefore, just like feof(), gzeof() may return false even if there is no + more data to read, in the event that the last read request was for the exact + number of bytes remaining in the input file. This will happen if the input + file size is an exact multiple of the buffer size. + + If gzeof() returns true, then the read functions will return no more data, + unless the end-of-file indicator is reset by gzclearerr() and the input file + has grown since the previous end of file was detected. +*/ + +Z_EXTERN int Z_EXPORT gzdirect(gzFile file); +/* + Return true (1) if file is being copied directly while reading, or false + (0) if file is a gzip stream being decompressed. + + If the input file is empty, gzdirect() will return true, since the input + does not contain a gzip stream. + + If gzdirect() is used immediately after gzopen() or gzdopen() it will + cause buffers to be allocated to allow reading the file to determine if it + is a gzip file. Therefore if gzbuffer() is used, it should be called before + gzdirect(). + + When writing, gzdirect() returns true (1) if transparent writing was + requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note: + gzdirect() is not needed when writing. Transparent writing must be + explicitly requested, so the application already knows the answer. When + linking statically, using gzdirect() will include all of the zlib code for + gzip file reading and decompression, which may not be desired.) +*/ + +Z_EXTERN int Z_EXPORT gzclose(gzFile file); +/* + Flush all pending output for file, if necessary, close file and + deallocate the (de)compression state. Note that once file is closed, you + cannot call gzerror with file, since its structures have been deallocated. + gzclose must not be called more than once on the same file, just as free + must not be called more than once on the same allocation. + + gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a + file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the + last read ended in the middle of a gzip stream, or Z_OK on success. +*/ + +Z_EXTERN int Z_EXPORT gzclose_r(gzFile file); +Z_EXTERN int Z_EXPORT gzclose_w(gzFile file); +/* + Same as gzclose(), but gzclose_r() is only for use when reading, and + gzclose_w() is only for use when writing or appending. The advantage to + using these instead of gzclose() is that they avoid linking in zlib + compression or decompression code that is not used when only reading or only + writing respectively. If gzclose() is used, then both compression and + decompression code will be included the application when linking to a static + zlib library. +*/ + +Z_EXTERN const char * Z_EXPORT gzerror(gzFile file, int *errnum); +/* + Return the error message for the last error which occurred on file. + errnum is set to zlib error number. If an error occurred in the file system + and not in the compression library, errnum is set to Z_ERRNO and the + application may consult errno to get the exact error code. + + The application must not modify the returned string. Future calls to + this function may invalidate the previously returned string. If file is + closed, then the string previously returned by gzerror will no longer be + available. + + gzerror() should be used to distinguish errors from end-of-file for those + functions above that do not distinguish those cases in their return values. +*/ + +Z_EXTERN void Z_EXPORT gzclearerr(gzFile file); +/* + Clear the error and end-of-file flags for file. This is analogous to the + clearerr() function in stdio. This is useful for continuing to read a gzip + file that is being written concurrently. +*/ + +#endif + + /* checksum functions */ + +/* + These functions are not related to compression but are exported + anyway because they might be useful in applications using the compression + library. +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32(unsigned long adler, const unsigned char *buf, unsigned int len); +/* + Update a running Adler-32 checksum with the bytes buf[0..len-1] and + return the updated checksum. An Adler-32 value is in the range of a 32-bit + unsigned integer. If buf is Z_NULL, this function returns the required + initial value for the checksum. + + An Adler-32 checksum is almost as reliable as a CRC-32 but can be computed + much faster. + + Usage example: + + uint32_t adler = adler32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + adler = adler32(adler, buffer, length); + } + if (adler != original_adler) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT adler32_z(unsigned long adler, const unsigned char *buf, size_t len); +/* + Same as adler32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT adler32_combine(unsigned long adler1, unsigned long adler2, z_off_t len2); + + Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 + and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for + each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of + seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note + that the z_off_t type (like off_t) is a signed integer. If len2 is + negative, the result has no meaning or utility. +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32(unsigned long crc, const unsigned char *buf, unsigned int len); +/* + Update a running CRC-32 with the bytes buf[0..len-1] and return the + updated CRC-32. A CRC-32 value is in the range of a 32-bit unsigned integer. + If buf is Z_NULL, this function returns the required initial value for the + crc. Pre- and post-conditioning (one's complement) is performed within this + function so it shouldn't be done by the application. + + Usage example: + + uint32_t crc = crc32(0L, NULL, 0); + + while (read_buffer(buffer, length) != EOF) { + crc = crc32(crc, buffer, length); + } + if (crc != original_crc) error(); +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_z(unsigned long crc, const unsigned char *buf, size_t len); +/* + Same as crc32(), but with a size_t length. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine(unsigned long crc1, unsigned long crc2, z_off64_t len2); + + Combine two CRC-32 check values into one. For two sequences of bytes, + seq1 and seq2 with lengths len1 and len2, CRC-32 check values were + calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 + check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and + len2. +*/ + +/* +Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen(z_off_t len2); + + Return the operator corresponding to length len2, to be used with + crc32_combine_op(). +*/ + +Z_EXTERN unsigned long Z_EXPORT crc32_combine_op(unsigned long crc1, unsigned long crc2, + const unsigned long op); +/* + Give the same result as crc32_combine(), using op in place of len2. op is + is generated from len2 by crc32_combine_gen(). This will be faster than + crc32_combine() if the generated op is used more than once. +*/ + + + /* various hacks, don't look :) */ + +/* deflateInit and inflateInit are macros to allow checking the zlib version + * and the compiler's view of z_stream: + */ +Z_EXTERN int Z_EXPORT deflateInit_(z_stream *strm, int level, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit_(z_stream *strm, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT deflateInit2_(z_stream *strm, int level, int method, int windowBits, int memLevel, + int strategy, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateInit2_(z_stream *strm, int windowBits, const char *version, int stream_size); +Z_EXTERN int Z_EXPORT inflateBackInit_(z_stream *strm, int windowBits, unsigned char *window, + const char *version, int stream_size); +#define @ZLIB_SYMBOL_PREFIX@deflateInit(strm, level) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit(strm) inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ + deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateInit2(strm, windowBits) inflateInit2_((strm), (windowBits), ZLIB_VERSION, (int)sizeof(z_stream)) +#define @ZLIB_SYMBOL_PREFIX@inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), ZLIB_VERSION, (int)sizeof(z_stream)) + + +#ifndef Z_SOLO +/* gzgetc() macro and its supporting function and exposed data structure. Note + * that the real internal state is much larger than the exposed structure. + * This abbreviated structure exposes just enough for the gzgetc() macro. The + * user should not mess with these exposed elements, since their names or + * behavior could change in the future, perhaps even capriciously. They can + * only be used by the gzgetc() macro. You have been warned. + */ +struct gzFile_s { + unsigned have; + unsigned char *next; + z_off64_t pos; +}; +Z_EXTERN int Z_EXPORT gzgetc_(gzFile file); /* backward compatibility */ +# define @ZLIB_SYMBOL_PREFIX@gzgetc(g) ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : (@ZLIB_SYMBOL_PREFIX@gzgetc)(g)) + +/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or + * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if + * both are true, the application gets the *64 functions, and the regular + * functions are changed to 64 bits) -- in case these are set on systems + * without large file support, _LFS64_LARGEFILE must also be true + */ +#ifdef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT gzopen64(const char *, const char *); + Z_EXTERN z_off64_t Z_EXPORT gzseek64(gzFile, z_off64_t, int); + Z_EXTERN z_off64_t Z_EXPORT gztell64(gzFile); + Z_EXTERN z_off64_t Z_EXPORT gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT adler32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine64(unsigned long, unsigned long, z_off64_t); + Z_EXTERN unsigned long Z_EXPORT crc32_combine_gen64(z_off64_t); +#endif +#endif + +#if !defined(Z_SOLO) && !defined(Z_INTERNAL) && defined(Z_WANT64) +# define @ZLIB_SYMBOL_PREFIX@gzopen @ZLIB_SYMBOL_PREFIX@gzopen64 +# define @ZLIB_SYMBOL_PREFIX@gzseek @ZLIB_SYMBOL_PREFIX@gzseek64 +# define @ZLIB_SYMBOL_PREFIX@gztell @ZLIB_SYMBOL_PREFIX@gztell64 +# define @ZLIB_SYMBOL_PREFIX@gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define @ZLIB_SYMBOL_PREFIX@adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine64 +# define @ZLIB_SYMBOL_PREFIX@crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +# ifndef Z_LARGE64 + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen64(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek64(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell64(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset64(gzFile); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine64(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64(z_off64_t); +# endif +#else +# ifndef Z_SOLO + Z_EXTERN gzFile Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzopen(const char *, const char *); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzseek(gzFile, z_off_t, int); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gztell(gzFile); + Z_EXTERN z_off_t Z_EXPORT @ZLIB_SYMBOL_PREFIX@gzoffset(gzFile); +# endif + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@adler32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine(unsigned long, unsigned long, z_off_t); + Z_EXTERN unsigned long Z_EXPORT @ZLIB_SYMBOL_PREFIX@crc32_combine_gen(z_off_t); +#endif + +/* undocumented functions */ +Z_EXTERN const char * Z_EXPORT zError (int); +Z_EXTERN int Z_EXPORT inflateSyncPoint (z_stream *); +Z_EXTERN const uint32_t * Z_EXPORT get_crc_table (void); +Z_EXTERN int Z_EXPORT inflateUndermine (z_stream *, int); +Z_EXTERN int Z_EXPORT inflateValidate (z_stream *, int); +Z_EXTERN unsigned long Z_EXPORT inflateCodesUsed (z_stream *); +Z_EXTERN int Z_EXPORT inflateResetKeep (z_stream *); +Z_EXTERN int Z_EXPORT deflateResetKeep (z_stream *); + +#ifndef Z_SOLO +#if defined(_WIN32) + Z_EXTERN gzFile Z_EXPORT gzopen_w(const wchar_t *path, const char *mode); +#endif +Z_EXTERN int Z_EXPORTVA gzvprintf(gzFile file, const char *format, va_list va); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ZLIB_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib.map b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.map new file mode 100644 index 000000000..ebca10d35 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.map @@ -0,0 +1,97 @@ +ZLIB_1.2.0 { + global: + compressBound; + deflateBound; + inflateBack; + inflateBackEnd; + inflateBackInit_; + inflateCopy; + local: + deflate_copyright; + inflate_copyright; + zcalloc; + zcfree; + z_errmsg; + gz_error; + _*; +}; + +ZLIB_1.2.0.2 { + gzclearerr; + gzungetc; + zlibCompileFlags; +} ZLIB_1.2.0; + +ZLIB_1.2.0.8 { + deflatePrime; +} ZLIB_1.2.0.2; + +ZLIB_1.2.2 { + adler32_combine; + crc32_combine; + deflateSetHeader; + inflateGetHeader; +} ZLIB_1.2.0.8; + +ZLIB_1.2.2.3 { + deflateTune; + gzdirect; +} ZLIB_1.2.2; + +ZLIB_1.2.2.4 { + inflatePrime; +} ZLIB_1.2.2.3; + +ZLIB_1.2.3.3 { + adler32_combine64; + crc32_combine64; + gzopen64; + gzseek64; + gztell64; + inflateUndermine; +} ZLIB_1.2.2.4; + +ZLIB_1.2.3.4 { + inflateReset2; + inflateMark; +} ZLIB_1.2.3.3; + +ZLIB_1.2.3.5 { + gzbuffer; + gzoffset; + gzoffset64; + gzclose_r; + gzclose_w; +} ZLIB_1.2.3.4; + +ZLIB_1.2.5.1 { + deflatePending; +} ZLIB_1.2.3.5; + +ZLIB_1.2.5.2 { + deflateResetKeep; + gzgetc_; + inflateResetKeep; +} ZLIB_1.2.5.1; + +ZLIB_1.2.7.1 { + inflateGetDictionary; + gzvprintf; +} ZLIB_1.2.5.2; + +ZLIB_1.2.9 { + inflateCodesUsed; + inflateValidate; + uncompress2; + gzfread; + gzfwrite; + deflateGetDictionary; + adler32_z; + crc32_z; +} ZLIB_1.2.7.1; + +ZLIB_1.2.12 { + crc32_combine_gen; + crc32_combine_gen64; + crc32_combine_op; +} ZLIB_1.2.9; diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.cmakein b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.cmakein new file mode 100644 index 000000000..3d440ce6b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.cmakein @@ -0,0 +1,14 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +symbol_prefix=@ZLIB_SYMBOL_PREFIX@ +libdir=@PC_LIB_INSTALL_DIR@ +sharedlibdir=${libdir} +includedir=@PC_INC_INSTALL_DIR@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @ZLIB_FULL_VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.in b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.in new file mode 100644 index 000000000..a0678fbe0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib.pc.in @@ -0,0 +1,14 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +symbol_prefix=@symbol_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: zlib@SUFFIX@ +Description: zlib-ng compression library +Version: @VERSION@ + +Requires: +Libs: -L${libdir} -L${sharedlibdir} -lz@SUFFIX@ +Cflags: -I${includedir} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling-ng.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling-ng.h.in new file mode 100644 index 000000000..e90904a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling-ng.h.in @@ -0,0 +1,178 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define zng__dist_code @ZLIB_SYMBOL_PREFIX@zng__dist_code +#define zng__length_code @ZLIB_SYMBOL_PREFIX@zng__length_code +#define zng__tr_align @ZLIB_SYMBOL_PREFIX@zng__tr_align +#define zng__tr_flush_bits @ZLIB_SYMBOL_PREFIX@zng__tr_flush_bits +#define zng__tr_flush_block @ZLIB_SYMBOL_PREFIX@zng__tr_flush_block +#define zng__tr_init @ZLIB_SYMBOL_PREFIX@zng__tr_init +#define zng__tr_stored_block @ZLIB_SYMBOL_PREFIX@zng__tr_stored_block +#define zng__tr_tally @ZLIB_SYMBOL_PREFIX@zng__tr_tally +#define zng_adler32 @ZLIB_SYMBOL_PREFIX@zng_adler32 +#define zng_adler32_combine @ZLIB_SYMBOL_PREFIX@zng_adler32_combine +#define zng_adler32_combine64 @ZLIB_SYMBOL_PREFIX@zng_adler32_combine64 +#define zng_adler32_z @ZLIB_SYMBOL_PREFIX@zng_adler32_z +#define zng_compress @ZLIB_SYMBOL_PREFIX@zng_compress +#define zng_compress2 @ZLIB_SYMBOL_PREFIX@zng_compress2 +#define zng_compressBound @ZLIB_SYMBOL_PREFIX@zng_compressBound +#define zng_crc32 @ZLIB_SYMBOL_PREFIX@zng_crc32 +#define zng_crc32_combine @ZLIB_SYMBOL_PREFIX@zng_crc32_combine +#define zng_crc32_combine64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine64 +#define zng_crc32_combine_gen @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen +#define zng_crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_gen64 +#define zng_crc32_combine_op @ZLIB_SYMBOL_PREFIX@zng_crc32_combine_op +#define zng_crc32_z @ZLIB_SYMBOL_PREFIX@zng_crc32_z +#define zng_deflate @ZLIB_SYMBOL_PREFIX@zng_deflate +#define zng_deflateBound @ZLIB_SYMBOL_PREFIX@zng_deflateBound +#define zng_deflateCopy @ZLIB_SYMBOL_PREFIX@zng_deflateCopy +#define zng_deflateEnd @ZLIB_SYMBOL_PREFIX@zng_deflateEnd +#define zng_deflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateGetDictionary +#define zng_deflateInit @ZLIB_SYMBOL_PREFIX@zng_deflateInit +#define zng_deflateInit2 @ZLIB_SYMBOL_PREFIX@zng_deflateInit2 +#define zng_deflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit2_ +#define zng_deflateInit_ @ZLIB_SYMBOL_PREFIX@zng_deflateInit_ +#define zng_deflateParams @ZLIB_SYMBOL_PREFIX@zng_deflateParams +#define zng_deflatePending @ZLIB_SYMBOL_PREFIX@zng_deflatePending +#define zng_deflatePrime @ZLIB_SYMBOL_PREFIX@zng_deflatePrime +#define zng_deflateReset @ZLIB_SYMBOL_PREFIX@zng_deflateReset +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep +#define zng_deflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_deflateSetDictionary +#define zng_deflateSetHeader @ZLIB_SYMBOL_PREFIX@zng_deflateSetHeader +#define zng_deflateTune @ZLIB_SYMBOL_PREFIX@zng_deflateTune +#define zng_deflate_copyright @ZLIB_SYMBOL_PREFIX@zng_deflate_copyright +#define zng_fill_window @ZLIB_SYMBOL_PREFIX@zng_fill_window +#define zng_fixedtables @ZLIB_SYMBOL_PREFIX@zng_fixedtables +#define zng_flush_pending @ZLIB_SYMBOL_PREFIX@zng_flush_pending +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#ifdef WITH_GZFILEOP +# define zng_gz_error @ZLIB_SYMBOL_PREFIX@zng_gz_error +# define zng_gz_strwinerror @ZLIB_SYMBOL_PREFIX@zng_gz_strwinerror +# define zng_gzbuffer @ZLIB_SYMBOL_PREFIX@zng_gzbuffer +# define zng_gzclearerr @ZLIB_SYMBOL_PREFIX@zng_gzclearerr +# define zng_gzclose @ZLIB_SYMBOL_PREFIX@zng_gzclose +# define zng_gzclose_r @ZLIB_SYMBOL_PREFIX@zng_gzclose_r +# define zng_gzclose_w @ZLIB_SYMBOL_PREFIX@zng_gzclose_w +# define zng_gzdirect @ZLIB_SYMBOL_PREFIX@zng_gzdirect +# define zng_gzdopen @ZLIB_SYMBOL_PREFIX@zng_gzdopen +# define zng_gzeof @ZLIB_SYMBOL_PREFIX@zng_gzeof +# define zng_gzerror @ZLIB_SYMBOL_PREFIX@zng_gzerror +# define zng_gzflush @ZLIB_SYMBOL_PREFIX@zng_gzflush +# define zng_gzfread @ZLIB_SYMBOL_PREFIX@zng_gzfread +# define zng_gzfwrite @ZLIB_SYMBOL_PREFIX@zng_gzfwrite +# define zng_gzgetc @ZLIB_SYMBOL_PREFIX@zng_gzgetc +# define zng_gzgetc_ @ZLIB_SYMBOL_PREFIX@zng_gzgetc_ +# define zng_gzgets @ZLIB_SYMBOL_PREFIX@zng_gzgets +# define zng_gzoffset @ZLIB_SYMBOL_PREFIX@zng_gzoffset +# define zng_gzoffset64 @ZLIB_SYMBOL_PREFIX@zng_gzoffset64 +# define zng_gzopen @ZLIB_SYMBOL_PREFIX@zng_gzopen +# define zng_gzopen64 @ZLIB_SYMBOL_PREFIX@zng_gzopen64 +# ifdef _WIN32 +# define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +# endif +# define zng_gzprintf @ZLIB_SYMBOL_PREFIX@zng_gzprintf +# define zng_gzputc @ZLIB_SYMBOL_PREFIX@zng_gzputc +# define zng_gzputs @ZLIB_SYMBOL_PREFIX@zng_gzputs +# define zng_gzread @ZLIB_SYMBOL_PREFIX@zng_gzread +# define zng_gzrewind @ZLIB_SYMBOL_PREFIX@zng_gzrewind +# define zng_gzseek @ZLIB_SYMBOL_PREFIX@zng_gzseek +# define zng_gzseek64 @ZLIB_SYMBOL_PREFIX@zng_gzseek64 +# define zng_gzsetparams @ZLIB_SYMBOL_PREFIX@zng_gzsetparams +# define zng_gztell @ZLIB_SYMBOL_PREFIX@zng_gztell +# define zng_gztell64 @ZLIB_SYMBOL_PREFIX@zng_gztell64 +# define zng_gzungetc @ZLIB_SYMBOL_PREFIX@zng_gzungetc +# define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf +# define zng_gzwrite @ZLIB_SYMBOL_PREFIX@zng_gzwrite +#endif +#define zng_inflate @ZLIB_SYMBOL_PREFIX@zng_inflate +#define zng_inflateBack @ZLIB_SYMBOL_PREFIX@zng_inflateBack +#define zng_inflateBackEnd @ZLIB_SYMBOL_PREFIX@zng_inflateBackEnd +#define zng_inflateBackInit @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit +#define zng_inflateBackInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateBackInit_ +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateCopy @ZLIB_SYMBOL_PREFIX@zng_inflateCopy +#define zng_inflateEnd @ZLIB_SYMBOL_PREFIX@zng_inflateEnd +#define zng_inflateGetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateGetDictionary +#define zng_inflateGetHeader @ZLIB_SYMBOL_PREFIX@zng_inflateGetHeader +#define zng_inflateInit @ZLIB_SYMBOL_PREFIX@zng_inflateInit +#define zng_inflateInit2 @ZLIB_SYMBOL_PREFIX@zng_inflateInit2 +#define zng_inflateInit2_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit2_ +#define zng_inflateInit_ @ZLIB_SYMBOL_PREFIX@zng_inflateInit_ +#define zng_inflateMark @ZLIB_SYMBOL_PREFIX@zng_inflateMark +#define zng_inflatePrime @ZLIB_SYMBOL_PREFIX@zng_inflatePrime +#define zng_inflateReset @ZLIB_SYMBOL_PREFIX@zng_inflateReset +#define zng_inflateReset2 @ZLIB_SYMBOL_PREFIX@zng_inflateReset2 +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_inflateSetDictionary @ZLIB_SYMBOL_PREFIX@zng_inflateSetDictionary +#define zng_inflateSync @ZLIB_SYMBOL_PREFIX@zng_inflateSync +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflate_copyright @ZLIB_SYMBOL_PREFIX@zng_inflate_copyright +#define zng_inflate_ensure_window @ZLIB_SYMBOL_PREFIX@zng_inflate_ensure_window +#define zng_inflate_fast @ZLIB_SYMBOL_PREFIX@zng_inflate_fast +#define zng_inflate_table @ZLIB_SYMBOL_PREFIX@zng_inflate_table +#define zng_read_buf @ZLIB_SYMBOL_PREFIX@zng_read_buf +#define zng_uncompress @ZLIB_SYMBOL_PREFIX@zng_uncompress +#define zng_uncompress2 @ZLIB_SYMBOL_PREFIX@zng_uncompress2 +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError +#define zng_zcalloc @ZLIB_SYMBOL_PREFIX@zng_zcalloc +#define zng_zcfree @ZLIB_SYMBOL_PREFIX@zng_zcfree +#define zng_zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zng_zlibCompileFlags +#define zng_zlibVersion @ZLIB_SYMBOL_PREFIX@zng_zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifdef WITH_GZFILEOP +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define zng_gz_header_s @ZLIB_SYMBOL_PREFIX@zng_gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* zlib-ng specific symbols */ +#define zng_deflate_param @ZLIB_SYMBOL_PREFIX@zng_deflate_param +#define zng_deflate_param_value @ZLIB_SYMBOL_PREFIX@zng_deflate_param_value +#define zng_deflateSetParams @ZLIB_SYMBOL_PREFIX@zng_deflateSetParams +#define zng_deflateGetParams @ZLIB_SYMBOL_PREFIX@zng_deflateGetParams + +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version +#define zng_vstring @ZLIB_SYMBOL_PREFIX@zng_vstring +#define zng_zError @ZLIB_SYMBOL_PREFIX@zng_zError + +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned +#define zng_get_crc_table @ZLIB_SYMBOL_PREFIX@zng_get_crc_table +#define zng_inflateSyncPoint @ZLIB_SYMBOL_PREFIX@zng_inflateSyncPoint +#define zng_inflateUndermine @ZLIB_SYMBOL_PREFIX@zng_inflateUndermine +#define zng_inflateValidate @ZLIB_SYMBOL_PREFIX@zng_inflateValidate +#define zng_inflateCodesUsed @ZLIB_SYMBOL_PREFIX@zng_inflateCodesUsed +#define zng_inflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_inflateResetKeep +#define zng_deflateResetKeep @ZLIB_SYMBOL_PREFIX@zng_deflateResetKeep + +#define zng_gzopen_w @ZLIB_SYMBOL_PREFIX@zng_gzopen_w +#define zng_gzvprintf @ZLIB_SYMBOL_PREFIX@zng_gzvprintf + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.empty b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.empty new file mode 100644 index 000000000..b24cb834a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.empty @@ -0,0 +1,8 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.empty because ZLIB_SYMBOL_PREFIX was NOT set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.in b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.in new file mode 100644 index 000000000..f49615818 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zlib_name_mangling.h.in @@ -0,0 +1,170 @@ +/* zlib_name_mangling.h has been automatically generated from + * zlib_name_mangling.h.in because ZLIB_SYMBOL_PREFIX was set. + */ + +#ifndef ZLIB_NAME_MANGLING_H +#define ZLIB_NAME_MANGLING_H + +/* all linked symbols and init macros */ +#define _dist_code @ZLIB_SYMBOL_PREFIX@_dist_code +#define _length_code @ZLIB_SYMBOL_PREFIX@_length_code +#define _tr_align @ZLIB_SYMBOL_PREFIX@_tr_align +#define _tr_flush_bits @ZLIB_SYMBOL_PREFIX@_tr_flush_bits +#define _tr_flush_block @ZLIB_SYMBOL_PREFIX@_tr_flush_block +#define _tr_init @ZLIB_SYMBOL_PREFIX@_tr_init +#define _tr_stored_block @ZLIB_SYMBOL_PREFIX@_tr_stored_block +#define _tr_tally @ZLIB_SYMBOL_PREFIX@_tr_tally +#define adler32 @ZLIB_SYMBOL_PREFIX@adler32 +#define adler32_combine @ZLIB_SYMBOL_PREFIX@adler32_combine +#define adler32_combine64 @ZLIB_SYMBOL_PREFIX@adler32_combine64 +#define adler32_z @ZLIB_SYMBOL_PREFIX@adler32_z +#ifndef Z_SOLO +# define compress @ZLIB_SYMBOL_PREFIX@compress +# define compress2 @ZLIB_SYMBOL_PREFIX@compress2 +# define compressBound @ZLIB_SYMBOL_PREFIX@compressBound +#endif +#define crc32 @ZLIB_SYMBOL_PREFIX@crc32 +#define crc32_combine @ZLIB_SYMBOL_PREFIX@crc32_combine +#define crc32_combine64 @ZLIB_SYMBOL_PREFIX@crc32_combine64 +#define crc32_combine_gen @ZLIB_SYMBOL_PREFIX@crc32_combine_gen +#define crc32_combine_gen64 @ZLIB_SYMBOL_PREFIX@crc32_combine_gen64 +#define crc32_combine_op @ZLIB_SYMBOL_PREFIX@crc32_combine_op +#define crc32_z @ZLIB_SYMBOL_PREFIX@crc32_z +#define deflate @ZLIB_SYMBOL_PREFIX@deflate +#define deflateBound @ZLIB_SYMBOL_PREFIX@deflateBound +#define deflateCopy @ZLIB_SYMBOL_PREFIX@deflateCopy +#define deflateEnd @ZLIB_SYMBOL_PREFIX@deflateEnd +#define deflateGetDictionary @ZLIB_SYMBOL_PREFIX@deflateGetDictionary +#define deflateInit @ZLIB_SYMBOL_PREFIX@deflateInit +#define deflateInit2 @ZLIB_SYMBOL_PREFIX@deflateInit2 +#define deflateInit2_ @ZLIB_SYMBOL_PREFIX@deflateInit2_ +#define deflateInit_ @ZLIB_SYMBOL_PREFIX@deflateInit_ +#define deflateParams @ZLIB_SYMBOL_PREFIX@deflateParams +#define deflatePending @ZLIB_SYMBOL_PREFIX@deflatePending +#define deflatePrime @ZLIB_SYMBOL_PREFIX@deflatePrime +#define deflateReset @ZLIB_SYMBOL_PREFIX@deflateReset +#define deflateResetKeep @ZLIB_SYMBOL_PREFIX@deflateResetKeep +#define deflateSetDictionary @ZLIB_SYMBOL_PREFIX@deflateSetDictionary +#define deflateSetHeader @ZLIB_SYMBOL_PREFIX@deflateSetHeader +#define deflateTune @ZLIB_SYMBOL_PREFIX@deflateTune +#define deflate_copyright @ZLIB_SYMBOL_PREFIX@deflate_copyright +#define fill_window @ZLIB_SYMBOL_PREFIX@fill_window +#define fixedtables @ZLIB_SYMBOL_PREFIX@fixedtables +#define flush_pending @ZLIB_SYMBOL_PREFIX@flush_pending +#define get_crc_table @ZLIB_SYMBOL_PREFIX@get_crc_table +#ifndef Z_SOLO +# define gz_error @ZLIB_SYMBOL_PREFIX@gz_error +# define gz_strwinerror @ZLIB_SYMBOL_PREFIX@gz_strwinerror +# define gzbuffer @ZLIB_SYMBOL_PREFIX@gzbuffer +# define gzclearerr @ZLIB_SYMBOL_PREFIX@gzclearerr +# define gzclose @ZLIB_SYMBOL_PREFIX@gzclose +# define gzclose_r @ZLIB_SYMBOL_PREFIX@gzclose_r +# define gzclose_w @ZLIB_SYMBOL_PREFIX@gzclose_w +# define gzdirect @ZLIB_SYMBOL_PREFIX@gzdirect +# define gzdopen @ZLIB_SYMBOL_PREFIX@gzdopen +# define gzeof @ZLIB_SYMBOL_PREFIX@gzeof +# define gzerror @ZLIB_SYMBOL_PREFIX@gzerror +# define gzflush @ZLIB_SYMBOL_PREFIX@gzflush +# define gzfread @ZLIB_SYMBOL_PREFIX@gzfread +# define gzfwrite @ZLIB_SYMBOL_PREFIX@gzfwrite +# define gzgetc @ZLIB_SYMBOL_PREFIX@gzgetc +# define gzgetc_ @ZLIB_SYMBOL_PREFIX@gzgetc_ +# define gzgets @ZLIB_SYMBOL_PREFIX@gzgets +# define gzoffset @ZLIB_SYMBOL_PREFIX@gzoffset +# define gzoffset64 @ZLIB_SYMBOL_PREFIX@gzoffset64 +# define gzopen @ZLIB_SYMBOL_PREFIX@gzopen +# define gzopen64 @ZLIB_SYMBOL_PREFIX@gzopen64 +# ifdef _WIN32 +# define gzopen_w @ZLIB_SYMBOL_PREFIX@gzopen_w +# endif +# define gzprintf @ZLIB_SYMBOL_PREFIX@gzprintf +# define gzputc @ZLIB_SYMBOL_PREFIX@gzputc +# define gzputs @ZLIB_SYMBOL_PREFIX@gzputs +# define gzread @ZLIB_SYMBOL_PREFIX@gzread +# define gzrewind @ZLIB_SYMBOL_PREFIX@gzrewind +# define gzseek @ZLIB_SYMBOL_PREFIX@gzseek +# define gzseek64 @ZLIB_SYMBOL_PREFIX@gzseek64 +# define gzsetparams @ZLIB_SYMBOL_PREFIX@gzsetparams +# define gztell @ZLIB_SYMBOL_PREFIX@gztell +# define gztell64 @ZLIB_SYMBOL_PREFIX@gztell64 +# define gzungetc @ZLIB_SYMBOL_PREFIX@gzungetc +# define gzvprintf @ZLIB_SYMBOL_PREFIX@gzvprintf +# define gzwrite @ZLIB_SYMBOL_PREFIX@gzwrite +#endif +#define inflate @ZLIB_SYMBOL_PREFIX@inflate +#define inflateBack @ZLIB_SYMBOL_PREFIX@inflateBack +#define inflateBackEnd @ZLIB_SYMBOL_PREFIX@inflateBackEnd +#define inflateBackInit @ZLIB_SYMBOL_PREFIX@inflateBackInit +#define inflateBackInit_ @ZLIB_SYMBOL_PREFIX@inflateBackInit_ +#define inflateCodesUsed @ZLIB_SYMBOL_PREFIX@inflateCodesUsed +#define inflateCopy @ZLIB_SYMBOL_PREFIX@inflateCopy +#define inflateEnd @ZLIB_SYMBOL_PREFIX@inflateEnd +#define inflateGetDictionary @ZLIB_SYMBOL_PREFIX@inflateGetDictionary +#define inflateGetHeader @ZLIB_SYMBOL_PREFIX@inflateGetHeader +#define inflateInit @ZLIB_SYMBOL_PREFIX@inflateInit +#define inflateInit2 @ZLIB_SYMBOL_PREFIX@inflateInit2 +#define inflateInit2_ @ZLIB_SYMBOL_PREFIX@inflateInit2_ +#define inflateInit_ @ZLIB_SYMBOL_PREFIX@inflateInit_ +#define inflateMark @ZLIB_SYMBOL_PREFIX@inflateMark +#define inflatePrime @ZLIB_SYMBOL_PREFIX@inflatePrime +#define inflateReset @ZLIB_SYMBOL_PREFIX@inflateReset +#define inflateReset2 @ZLIB_SYMBOL_PREFIX@inflateReset2 +#define inflateResetKeep @ZLIB_SYMBOL_PREFIX@inflateResetKeep +#define inflateSetDictionary @ZLIB_SYMBOL_PREFIX@inflateSetDictionary +#define inflateSync @ZLIB_SYMBOL_PREFIX@inflateSync +#define inflateSyncPoint @ZLIB_SYMBOL_PREFIX@inflateSyncPoint +#define inflateUndermine @ZLIB_SYMBOL_PREFIX@inflateUndermine +#define inflateValidate @ZLIB_SYMBOL_PREFIX@inflateValidate +#define inflate_copyright @ZLIB_SYMBOL_PREFIX@inflate_copyright +#define inflate_ensure_window @ZLIB_SYMBOL_PREFIX@inflate_ensure_window +#define inflate_fast @ZLIB_SYMBOL_PREFIX@inflate_fast +#define inflate_table @ZLIB_SYMBOL_PREFIX@inflate_table +#define read_buf @ZLIB_SYMBOL_PREFIX@read_buf +#ifndef Z_SOLO +# define uncompress @ZLIB_SYMBOL_PREFIX@uncompress +# define uncompress2 @ZLIB_SYMBOL_PREFIX@uncompress2 +#endif +#define zError @ZLIB_SYMBOL_PREFIX@zError +#ifndef Z_SOLO +# define zcalloc @ZLIB_SYMBOL_PREFIX@zcalloc +# define zcfree @ZLIB_SYMBOL_PREFIX@zcfree +#endif +#define zlibCompileFlags @ZLIB_SYMBOL_PREFIX@zlibCompileFlags +#define zlibVersion @ZLIB_SYMBOL_PREFIX@zlibVersion + +/* all zlib typedefs in zlib.h and zconf.h */ +#define Byte @ZLIB_SYMBOL_PREFIX@Byte +#define Bytef @ZLIB_SYMBOL_PREFIX@Bytef +#define alloc_func @ZLIB_SYMBOL_PREFIX@alloc_func +#define charf @ZLIB_SYMBOL_PREFIX@charf +#define free_func @ZLIB_SYMBOL_PREFIX@free_func +#ifndef Z_SOLO +# define gzFile @ZLIB_SYMBOL_PREFIX@gzFile +#endif +#define gz_header @ZLIB_SYMBOL_PREFIX@gz_header +#define gz_headerp @ZLIB_SYMBOL_PREFIX@gz_headerp +#define in_func @ZLIB_SYMBOL_PREFIX@in_func +#define intf @ZLIB_SYMBOL_PREFIX@intf +#define out_func @ZLIB_SYMBOL_PREFIX@out_func +#define uInt @ZLIB_SYMBOL_PREFIX@uInt +#define uIntf @ZLIB_SYMBOL_PREFIX@uIntf +#define uLong @ZLIB_SYMBOL_PREFIX@uLong +#define uLongf @ZLIB_SYMBOL_PREFIX@uLongf +#define voidp @ZLIB_SYMBOL_PREFIX@voidp +#define voidpc @ZLIB_SYMBOL_PREFIX@voidpc +#define voidpf @ZLIB_SYMBOL_PREFIX@voidpf + +/* all zlib structs in zlib.h and zconf.h */ +#define gz_header_s @ZLIB_SYMBOL_PREFIX@gz_header_s +#define internal_state @ZLIB_SYMBOL_PREFIX@internal_state + +/* all zlib structs in zutil.h */ +#define z_errmsg @ZLIB_SYMBOL_PREFIX@z_errmsg +#define z_vstring @ZLIB_SYMBOL_PREFIX@z_vstring +#define zlibng_version @ZLIB_SYMBOL_PREFIX@zlibng_version + +/* zlib-ng specific symbols */ +#define zng_alloc_aligned @ZLIB_SYMBOL_PREFIX@zng_alloc_aligned +#define zng_free_aligned @ZLIB_SYMBOL_PREFIX@zng_free_aligned + +#endif /* ZLIB_NAME_MANGLING_H */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zutil.c b/internal-complibs/zlib-ng-2.1.0-beta1/zutil.c new file mode 100644 index 000000000..0fd14f4ef --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zutil.c @@ -0,0 +1,159 @@ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995-2017 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "zutil.h" + +z_const char * const PREFIX(z_errmsg)[10] = { + (z_const char *)"need dictionary", /* Z_NEED_DICT 2 */ + (z_const char *)"stream end", /* Z_STREAM_END 1 */ + (z_const char *)"", /* Z_OK 0 */ + (z_const char *)"file error", /* Z_ERRNO (-1) */ + (z_const char *)"stream error", /* Z_STREAM_ERROR (-2) */ + (z_const char *)"data error", /* Z_DATA_ERROR (-3) */ + (z_const char *)"insufficient memory", /* Z_MEM_ERROR (-4) */ + (z_const char *)"buffer error", /* Z_BUF_ERROR (-5) */ + (z_const char *)"incompatible version",/* Z_VERSION_ERROR (-6) */ + (z_const char *)"" +}; + +const char PREFIX3(vstring)[] = + " zlib-ng 2.1.0.beta1"; + +#ifdef ZLIB_COMPAT +const char * Z_EXPORT zlibVersion(void) { + return ZLIB_VERSION; +} +#else +const char * Z_EXPORT zlibng_version(void) { + return ZLIBNG_VERSION; +} +#endif + +unsigned long Z_EXPORT PREFIX(zlibCompileFlags)(void) { + unsigned long flags; + + flags = 0; + switch ((int)(sizeof(unsigned int))) { + case 2: break; + case 4: flags += 1; break; + case 8: flags += 2; break; + default: flags += 3; + } + switch ((int)(sizeof(unsigned long))) { + case 2: break; + case 4: flags += 1 << 2; break; + case 8: flags += 2 << 2; break; + default: flags += 3 << 2; + } + switch ((int)(sizeof(void *))) { + case 2: break; + case 4: flags += 1 << 4; break; + case 8: flags += 2 << 4; break; + default: flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) { + case 2: break; + case 4: flags += 1 << 6; break; + case 8: flags += 2 << 6; break; + default: flags += 3 << 6; + } +#ifdef ZLIB_DEBUG + flags += 1 << 8; +#endif +#ifdef ZLIB_WINAPI + flags += 1 << 10; +#endif + /* Bit 13 reserved for DYNAMIC_CRC_TABLE */ +#ifdef NO_GZCOMPRESS + flags += 1L << 16; +#endif +#ifdef NO_GZIP + flags += 1L << 17; +#endif +#ifdef PKZIP_BUG_WORKAROUND + flags += 1L << 20; +#endif + return flags; +} + +#ifdef ZLIB_DEBUG +# include +# ifndef verbose +# define verbose 0 +# endif +int Z_INTERNAL z_verbose = verbose; + +void Z_INTERNAL z_error(const char *m) { + fprintf(stderr, "%s\n", m); + exit(1); +} +#endif + +/* exported to allow conversion of error code to string for compress() and + * uncompress() + */ +const char * Z_EXPORT PREFIX(zError)(int err) { + return ERR_MSG(err); +} + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size) { + Z_UNUSED(opaque); + return zng_alloc((size_t)items * (size_t)size); +} + +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr) { + Z_UNUSED(opaque); + zng_free(ptr); +} + +/* Since we support custom memory allocators, some which might not align memory as we expect, + * we have to ask for extra memory and return an aligned pointer. */ +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align) { + uintptr_t return_ptr, original_ptr; + uint32_t alloc_size, align_diff; + void *ptr; + + /* If no custom calloc function used then call zlib-ng's aligned calloc */ + if (zalloc == PREFIX(zcalloc)) + return PREFIX(zcalloc)(opaque, items, size); + + /* Allocate enough memory for proper alignment and to store the original memory pointer */ + alloc_size = sizeof(void *) + (items * size) + align; + ptr = zalloc(opaque, 1, alloc_size); + if (!ptr) + return NULL; + + /* Calculate return pointer address with space enough to store original pointer */ + align_diff = align - ((uintptr_t)ptr % align); + return_ptr = (uintptr_t)ptr + align_diff; + if (align_diff < sizeof(void *)) + return_ptr += align; + + /* Store the original pointer for free() */ + original_ptr = return_ptr - sizeof(void *); + memcpy((void *)original_ptr, &ptr, sizeof(void *)); + + /* Return properly aligned pointer in allocation */ + return (void *)return_ptr; +} + +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr) { + /* If no custom cfree function used then call zlib-ng's aligned cfree */ + if (zfree == PREFIX(zcfree)) { + PREFIX(zcfree)(opaque, ptr); + return; + } + if (!ptr) + return; + + /* Calculate offset to original memory allocation pointer */ + void *original_ptr = (void *)((uintptr_t)ptr - sizeof(void *)); + void *free_ptr = *(void **)original_ptr; + + /* Free original memory allocation */ + zfree(opaque, free_ptr); +} diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zutil.h b/internal-complibs/zlib-ng-2.1.0-beta1/zutil.h new file mode 100644 index 000000000..663616b44 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zutil.h @@ -0,0 +1,148 @@ +#ifndef ZUTIL_H_ +#define ZUTIL_H_ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995-2022 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zbuild.h" +#ifdef ZLIB_COMPAT +# include "zlib.h" +#else +# include "zlib-ng.h" +#endif + +typedef unsigned char uch; /* Included for compatibility with external code only */ +typedef uint16_t ush; /* Included for compatibility with external code only */ +typedef unsigned long ulg; + +extern z_const char * const PREFIX(z_errmsg)[10]; /* indexed by 2-zlib_error */ +/* (size given to avoid silly warnings with Visual C++) */ + +#define ERR_MSG(err) PREFIX(z_errmsg)[Z_NEED_DICT-(err)] + +#define ERR_RETURN(strm, err) return (strm->msg = ERR_MSG(err), (err)) +/* To be used only when the state is known to be valid */ + + /* common constants */ + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#define MAX_BITS 15 +/* all codes must not exceed MAX_BITS bits */ +#define MAX_DIST_EXTRA_BITS 13 +/* maximum number of extra distance bits */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define STD_MIN_MATCH 3 +#define STD_MAX_MATCH 258 +/* The minimum and maximum match lengths mandated by the deflate standard */ + +#define WANT_MIN_MATCH 4 +/* The minimum wanted match length, affects deflate_quick, deflate_fast, deflate_medium and deflate_slow */ + +#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ + +#define ADLER32_INITIAL_VALUE 1 /* initial adler-32 hash value */ +#define CRC32_INITIAL_VALUE 0 /* initial crc-32 hash value */ + +#define ZLIB_WRAPLEN 6 /* zlib format overhead */ +#define GZIP_WRAPLEN 18 /* gzip format overhead */ + +#define DEFLATE_HEADER_BITS 3 +#define DEFLATE_EOBS_BITS 15 +#define DEFLATE_PAD_BITS 6 +#define DEFLATE_BLOCK_OVERHEAD ((DEFLATE_HEADER_BITS + DEFLATE_EOBS_BITS + DEFLATE_PAD_BITS) >> 3) +/* deflate block overhead: 3 bits for block start + 15 bits for block end + padding to nearest byte */ + +#define DEFLATE_QUICK_LIT_MAX_BITS 9 +#define DEFLATE_QUICK_OVERHEAD(x) ((x * (DEFLATE_QUICK_LIT_MAX_BITS - 8) + 7) >> 3) +/* deflate_quick worst-case overhead: 9 bits per literal, round up to next byte (+7) */ + + + /* target dependencies */ + +#ifdef AMIGA +# define OS_CODE 1 +#endif + +#ifdef __370__ +# if __TARGET_LIB__ < 0x20000000 +# define OS_CODE 4 +# elif __TARGET_LIB__ < 0x40000000 +# define OS_CODE 11 +# else +# define OS_CODE 8 +# endif +#endif + +#if defined(ATARI) || defined(atarist) +# define OS_CODE 5 +#endif + +#ifdef OS2 +# define OS_CODE 6 +#endif + +#if defined(MACOS) || defined(TARGET_OS_MAC) +# define OS_CODE 7 +#endif + +#ifdef __acorn +# define OS_CODE 13 +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +# define OS_CODE 10 +#endif + +#ifdef __APPLE__ +# define OS_CODE 19 +#endif + + /* common defaults */ + +#ifndef OS_CODE +# define OS_CODE 3 /* assume Unix */ +#endif + + /* macros */ + +#define CHECK_VER_STSIZE(_ver,_stsize) ((_ver) == NULL || (_ver)[0] != PREFIX2(VERSION)[0] || (_stsize) != (int32_t)sizeof(PREFIX3(stream))) + + /* memory allocation functions */ + +void Z_INTERNAL *PREFIX(zcalloc)(void *opaque, unsigned items, unsigned size); +void Z_INTERNAL PREFIX(zcfree)(void *opaque, void *ptr); + +typedef void *zng_calloc_func(void *opaque, unsigned items, unsigned size); +typedef void zng_cfree_func(void *opaque, void *ptr); + +void Z_INTERNAL *PREFIX3(alloc_aligned)(zng_calloc_func zalloc, void *opaque, unsigned items, unsigned size, unsigned align); +void Z_INTERNAL PREFIX3(free_aligned)(zng_cfree_func zfree, void *opaque, void *ptr); + +#define ZALLOC(strm, items, size) PREFIX3(alloc_aligned)((strm)->zalloc, (strm)->opaque, (items), (size), 64) +#define ZFREE(strm, addr) PREFIX3(free_aligned)((strm)->zfree, (strm)->opaque, (void *)(addr)) + +#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + +#endif /* ZUTIL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.0-beta1/zutil_p.h b/internal-complibs/zlib-ng-2.1.0-beta1/zutil_p.h new file mode 100644 index 000000000..caec91d50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.0-beta1/zutil_p.h @@ -0,0 +1,71 @@ +/* zutil_p.h -- Private inline functions used internally in zlib-ng + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ZUTIL_P_H +#define ZUTIL_P_H + +#if defined(__APPLE__) || defined(HAVE_POSIX_MEMALIGN) || defined(HAVE_ALIGNED_ALLOC) +# include +#elif defined(__FreeBSD__) +# include +# include +#else +# include +#endif + +/* Function to allocate 16 or 64-byte aligned memory */ +static inline void *zng_alloc(size_t size) { +#ifdef HAVE_POSIX_MEMALIGN + void *ptr; + return posix_memalign(&ptr, 64, size) ? NULL : ptr; +#elif defined(_WIN32) + return (void *)_aligned_malloc(size, 64); +#elif defined(__APPLE__) + return (void *)malloc(size); /* MacOS always aligns to 16 bytes */ +#elif defined(HAVE_ALIGNED_ALLOC) + return (void *)aligned_alloc(64, size); +#else + return (void *)memalign(64, size); +#endif +} + +/* Function that can free aligned memory */ +static inline void zng_free(void *ptr) { +#if defined(_WIN32) + _aligned_free(ptr); +#else + free(ptr); +#endif +} + +/* Use memcpy instead of memcmp to avoid older compilers not converting memcmp calls to + unaligned comparisons when unaligned access is supported. */ +static inline int32_t zng_memcmp_2(const void *src0, const void *src1) { + uint16_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_4(const void *src0, const void *src1) { + uint32_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +static inline int32_t zng_memcmp_8(const void *src0, const void *src1) { + uint64_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + + return src0_cmp != src1_cmp; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.codecov.yaml b/internal-complibs/zlib-ng-2.1.1-beta2/.codecov.yaml new file mode 100644 index 000000000..fc17c66a9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.codecov.yaml @@ -0,0 +1,27 @@ +codecov: + max_report_age: off + notify: + wait_for_ci: false + require_ci_to_pass: false +comment: + require_base: false + require_head: false +coverage: + status: + project: + default: + threshold: 0.07 +fixes: +- '/home/actions-runner/_work/zlib-ng/zlib-ng::' +- '/home/actions-runner/_work/zlib-ng/zlib-ng/build/::' +ignore: +- usr/include/.* +- /usr/include/.* +- /build/usr/include/.* +- usr/lib/.* +- /usr/lib/.* +- /build/usr/lib/.* +- usr/lib64/.* +- /usr/lib64/.* +- /build/usr/lib64/.* +- _deps/**/* diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes b/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes new file mode 100644 index 000000000..ac21ec459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.gitattributes @@ -0,0 +1,8 @@ +* text=auto +*.abi text eol=lf +*.c text +*.h text +*.sh text eol=lf +crc32_braid_tbl.h hooks-max-size=1000000 +Makefile text +configure text eol=lf diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml new file mode 100644 index 000000000..7cd812915 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/FUNDING.yml @@ -0,0 +1 @@ +github: zlib-ng diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml new file mode 100644 index 000000000..cbdea0e50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/analyze.yml @@ -0,0 +1,78 @@ +name: Static Analysis +on: [push, pull_request] +jobs: + static-analysis: + name: GCC + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y gcc-10 + + - name: Generate project files + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CC: gcc-10 + CFLAGS: + -fanalyzer + -Werror + -Wanalyzer-double-fclose + -Wanalyzer-double-free + -Wanalyzer-exposure-through-output-file + -Wanalyzer-file-leak + -Wanalyzer-free-of-non-heap + -Wanalyzer-malloc-leak + -Wanalyzer-null-argument + -Wanalyzer-null-dereference + -Wanalyzer-possible-null-argument + -Wanalyzer-possible-null-dereference + -Wanalyzer-stale-setjmp-buffer + -Wanalyzer-tainted-array-index + -Wanalyzer-unsafe-call-within-signal-handler + -Wanalyzer-use-after-free + -Wanalyzer-use-of-pointer-in-stale-stack-frame + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release > /dev/null + + Clang: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Install packages (Ubuntu) + run: sudo apt-get install -y clang-tools + + - name: Generate project files + run: | + scan-build --status-bugs \ + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DWITH_FUZZERS=OFF \ + -DWITH_CODE_COVERAGE=OFF \ + -DWITH_MAINTAINER_WARNINGS=OFF + env: + CI: true + + - name: Compile source code + run: | + scan-build --status-bugs \ + cmake --build . -j2 --config Release > /dev/null diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml new file mode 100644 index 000000000..2a148626a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/cmake.yml @@ -0,0 +1,623 @@ +name: CMake +on: [push, pull_request] +env: + TERM: xterm-256color + GTEST_COLOR: 1 +jobs: + cmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SANITIZER=Address + codecov: ubuntu_gcc + + - name: Ubuntu GCC Benchmark + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_BENCHMARKS=ON + codecov: ubuntu_gcc_benchmark + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_sprefix + + - name: Ubuntu GCC Compat Symbol Prefix + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DZLIB_SYMBOL_PREFIX=zTest_ + codecov: ubuntu_gcc_compat_sprefix + + - name: Ubuntu GCC -O3 OSB + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng + codecov: ubuntu_gcc_osb + cflags: -O3 + + - name: Ubuntu GCC -O3 OSB add_subdirectory + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + build-dir: ../build + build-src-dir: ../zlib-ng/test/add-subdirectory-project + + - name: Ubuntu GCC -O1 No Unaligned UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_UNALIGNED=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_o1 + cflags: -O1 + + - name: Ubuntu GCC 32-bit + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 -DCMAKE_SHARED_LINKER_FLAGS=-m32 -DCMAKE_EXE_LINKER_FLAGS=-m32 + packages: gcc-multilib g++-multilib + codecov: ubuntu_gcc_m32 + + - name: Ubuntu GCC No CTZLL + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF + codecov: ubuntu_gcc_no_ctzll + + - name: Ubuntu GCC No CTZ + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_OPTIM=OFF -DHAVE_BUILTIN_CTZLL=OFF -DHAVE_BUILTIN_CTZ=OFF + codecov: ubuntu_gcc_no_ctz + + - name: Ubuntu GCC No AVX2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_AVX2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_avx2 + + - name: Ubuntu GCC No SSE2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE2=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse2 + + - name: Ubuntu GCC No SSE4.2 UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_SSE42=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_sse42 + + - name: Ubuntu GCC No PCLMULQDQ UBSAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_PCLMULQDQ=OFF -DWITH_SANITIZER=Undefined + codecov: ubuntu_gcc_no_pclmulqdq + + - name: Ubuntu GCC Compat No Opt ASAN + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Address + codecov: ubuntu_gcc_compat_no_opt + cflags: -DNOT_TWEAK_COMPILER + + - name: Ubuntu GCC ARM SF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf + + - name: Ubuntu GCC ARM SF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-arm.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabi g++-arm-linux-gnueabi libc-dev-armel-cross + codecov: ubuntu_gcc_armsf_compat_no_opt + + - name: Ubuntu GCC ARM HF ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf + + - name: Ubuntu GCC ARM HF No ACLE ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_acle + + - name: Ubuntu GCC ARM HF No NEON ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_no_neon + + - name: Ubuntu GCC ARM HF Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc-dev-armel-cross + codecov: ubuntu_gcc_armhf_compat_no_opt + + - name: Ubuntu GCC AARCH64 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64 + + - name: Ubuntu GCC AARCH64 No ACLE UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_ACLE=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_acle + + - name: Ubuntu GCC AARCH64 No NEON UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DWITH_NEON=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_no_neon + + - name: Ubuntu GCC AARCH64 Compat No Opt UBSAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF -DWITH_SANITIZER=Undefined + packages: qemu qemu-user gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_aarch64_compat_no_opt + + - name: Ubuntu GCC PPC + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake -DWITH_POWER8=OFF + packages: qemu qemu-user gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc-dev-powerpc-cross + codecov: ubuntu_gcc_ppc_no_power8 + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64.cmake + packages: qemu qemu-user gcc-powerpc64-linux-gnu g++-powerpc64-linux-gnu libc-dev-ppc64-cross + ldflags: -static + codecov: ubuntu_gcc_ppc64 + + - name: Ubuntu GCC PPC64LE + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu qemu-user gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc-dev-ppc64el-cross + codecov: ubuntu_gcc_ppc64le + + - name: Ubuntu GCC SPARC64 + os: ubuntu-20.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-sparc64.cmake + packages: qemu qemu-user gcc-sparc64-linux-gnu g++-sparc64-linux-gnu libc-dev-sparc64-cross + ldflags: -static + codecov: ubuntu_gcc_sparc64 + + - name: Ubuntu GCC S390X ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X No vectorized CRC32 ASAN + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-s390x.cmake -DWITH_CRC32_VX=OFF -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + packages: qemu qemu-user gcc-s390x-linux-gnu g++-s390x-linux-gnu libc-dev-s390x-cross + ldflags: -static + codecov: ubuntu_gcc_s390x_no_crc32 + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC ASAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Address + asan-options: detect_leaks=0 + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu GCC S390X DFLTCC Compat UBSAN + os: z15 + compiler: gcc + cxx-compiler: g++ + cmake-args: -DZLIB_COMPAT=ON -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Undefined + ldflags: -static + codecov: ubuntu_gcc_s390x_dfltcc_compat + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu Clang S390X DFLTCC MSAN + os: z15 + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_DFLTCC_DEFLATE=ON -DWITH_DFLTCC_INFLATE=ON -DWITH_SANITIZER=Memory + # The dedicated test VM has 4 cores + parallels-jobs: 4 + + - name: Ubuntu MinGW i686 + os: ubuntu-22.04 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-i686.cmake + packages: wine wine32 gcc-mingw-w64-i686 g++-mingw-w64-i686 libpcre2-8-0=10.39-3ubuntu0.1 libpcre2-8-0:i386=10.39-3ubuntu0.1 libodbc1=2.3.9-5 libodbc1:i386=2.3.9-5 libwine:i386=6.0.3~repack-1 libgphoto2-6:i386=2.5.27-1build2 libsane:i386=1.1.1-5 libgd3=2.3.0-2ubuntu2 libgd3:i386=2.3.0-2ubuntu2 libgcc-s1:i386 libstdc++6:i386 + ldflags: -static + codecov: ubuntu_gcc_mingw_i686 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu MinGW x86_64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-mingw-x86_64.cmake + packages: wine wine64 gcc-mingw-w64 g++-mingw-w64 + ldflags: -static + codecov: ubuntu_gcc_mingw_x86_64 + # Limit parallel test jobs to prevent wine errors + parallels-jobs: 1 + + - name: Ubuntu 20.04 Clang + os: ubuntu-20.04 + compiler: clang-6.0 + cxx-compiler: clang++-6.0 + packages: clang-6.0 + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang + + # Check for undefined symbols in the version script for the modern api + - name: Ubuntu Clang Undefined Symbols + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF + build-shared: ON + packages: clang-11 llvm-11 lld + + # Check for undefined symbols in the version script for the compat api + - name: Ubuntu Clang Undefined Symbols Compat + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=lld -Wl,--no-undefined-version" -DZLIBNG_ENABLE_TESTS=OFF -DZLIB_COMPAT=ON + build-shared: ON + packages: clang-11 llvm-11 lld + + - name: Ubuntu Clang Inflate Strict + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_STRICT=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_strict + + - name: Ubuntu Clang Inflate Allow Invalid Dist + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_INFLATE_ALLOW_INVALID_DIST=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_inflate_allow_invalid_dist + + - name: Ubuntu Clang Reduced Memory + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -DWITH_REDUCED_MEM=ON + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_reduced_mem + + - name: Ubuntu Clang Memory Map + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cflags: -DUSE_MMAP + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_mmap + + - name: Ubuntu Clang Debug + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + packages: clang-11 llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_debug + build-config: Debug + + - name: Ubuntu Clang MSAN + os: ubuntu-latest + compiler: clang-11 + cxx-compiler: clang++-11 + cmake-args: -GNinja -DWITH_SANITIZER=Memory + packages: ninja-build clang-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + # https://github.com/llvm/llvm-project/issues/55785 + msan-options: use_sigaltstack=0 + + - name: Ubuntu Clang RISC-V + os: ubuntu-latest + cmake-args: -GNinja -DCMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake -DTOOLCHAIN_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-clang -DQEMU_PATH=${PWD}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64 + packages: build-essential cmake ninja-build + codecov: ubuntu_clang_toolchain_riscv + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + cmake-args: -DCMAKE_TOOLCHAIN_FILE=${EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_C_COMPILER_TARGET=wasm32 -DCMAKE_CROSSCOMPILING_EMULATOR=${EMSDK_NODE} -DZLIB_COMPAT=ON + + - name: Windows MSVC 2022 v143 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v143 + + - name: Windows MSVC 2022 v143 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v143 + + - name: Windows MSVC 2022 v142 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v142 + + - name: Windows MSVC 2022 v142 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v142 + + - name: Windows MSVC 2022 v141 Win32 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A Win32 -T v141 + + - name: Windows MSVC 2022 v141 Win64 + os: windows-latest + compiler: cl + cmake-args: -G "Visual Studio 17 2022" -A x64 -T v141 + + - name: Windows MSVC 2019 v140 Win32 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A Win32 -T v140 + + - name: Windows MSVC 2019 v140 Win64 + os: windows-2019 + compiler: cl + cmake-args: -G "Visual Studio 16 2019" -A x64 -T v140 + + - name: Windows MSVC ARM No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM + + - name: Windows MSVC ARM64 No Test + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + + - name: Windows ClangCl Win32 + os: windows-latest + cmake-args: -T ClangCl -A Win32 + + - name: Windows ClangCl Win64 + os: windows-latest + cmake-args: -T ClangCl -A x64 + + - name: Windows GCC + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja + codecov: win64_gcc + + - name: Windows GCC Compat No Opt + os: windows-latest + compiler: gcc + cxx-compiler: g++ + cmake-args: -G Ninja -DZLIB_COMPAT=ON -DWITH_NEW_STRATEGIES=OFF -DWITH_OPTIM=OFF + codecov: win64_gcc_compat_no_opt + + - name: macOS Clang ASAN + os: macos-latest + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_SANITIZER=Address + codecov: macos_clang + + - name: macOS GCC UBSAN + os: macos-latest + compiler: gcc-10 + cxx-compiler: g++-10 + cmake-args: -DWITH_SANITIZER=Undefined + packages: gcc@10 + gcov-exec: gcov-10 + codecov: macos_gcc + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + # Don't test against all corpora with MinGW due to Wine being unable to run parallel jobs + # without connection timeout. Without parallel jobs test runs using Wine take close to an hour. + if: contains(matrix.name, 'MinGW') == false + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add repositories (Wine) + if: contains(matrix.packages, 'wine32') + run: sudo dpkg --add-architecture i386 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y --allow-downgrades --no-install-recommends ${{ matrix.packages }} + + - name: Download prebuilt RISC-V Clang toolchain & QEMU emulator + if: runner.os == 'Linux' && contains(matrix.name, 'RISC-V') + run: | + gh release download ubuntu20.04_llvm16.0.0_qemu7.0.0 --repo sifive/prepare-riscv-toolchain-qemu + tar zxvf prebuilt-riscv-toolchain-qemu.tar.gz + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install packages (Windows) + if: runner.os == 'Windows' + run: | + # strawberryperl installs /c/Strawberry/c/bin/libstdc++-6.dll, which is incompatible with the mingw64 one. + # zlib-ng does not need perl, so simply remove it. + choco uninstall --no-progress strawberryperl + choco install --no-progress ninja ${{ matrix.packages }} + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Initialize Wine + # Prevent parallel test jobs from initializing Wine at the same time + if: contains(matrix.packages, 'wine') + run: wineboot --init + + - name: Compile LLVM C++ libraries (MSAN) + if: contains(matrix.name, 'MSAN') + run: | + git clone --depth=1 https://github.com/llvm/llvm-project --single-branch --branch llvmorg-11.1.0 + cmake -S llvm-project/llvm -B llvm-project/build -G Ninja \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ + -DLLVM_USE_SANITIZER=MemoryWithOrigins \ + -DLLVM_LIBC_ENABLE_LINTING=OFF + cmake --build llvm-project/build -j2 -- cxx cxxabi + echo "LLVM_BUILD_DIR=`pwd`/llvm-project/build" >> $GITHUB_ENV + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + + - name: Generate project files + shell: bash + # Shared libraries turned off for qemu ppc* and sparc & reduce code coverage sources + run: | + cmake -S ${{ matrix.build-src-dir || '.' }} -B ${{ matrix.build-dir || '.' }} ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=${{ matrix.build-shared || 'OFF' }} \ + -DWITH_FUZZERS=ON \ + -DWITH_MAINTAINER_WARNINGS=ON \ + ${{ matrix.codecov && '-DWITH_CODE_COVERAGE=ON' }} + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build ${{ matrix.build-dir || '.' }} -j2 --config ${{ matrix.build-config || 'Release' }} + + - name: Run test cases + # Don't run tests on Windows ARM + if: runner.os != 'Windows' || contains(matrix.name, 'ARM') == false + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: ${{ matrix.build-dir || '.' }} + env: + ASAN_OPTIONS: ${{ matrix.asan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + MSAN_OPTIONS: ${{ matrix.msan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + TSAN_OPTIONS: ${{ matrix.tsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + LSAN_OPTIONS: ${{ matrix.lsan-options || 'verbosity=0' }}:abort_on_error=1:halt_on_error=1 + UBSAN_OPTIONS: ${{ matrix.ubsan-options || 'verbosity=0' }}:print_stacktrace=1:abort_on_error=1:halt_on_error=1 + + - name: Generate coverage report + if: matrix.codecov + shell: bash + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root ${{ matrix.build-src-dir || '.' }} \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + directory: ${{ matrix.build-src-dir || '.' }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: "${{secrets.CODECOV_TOKEN}}" + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml new file mode 100644 index 000000000..1cfa4d7fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/codeql.yml @@ -0,0 +1,41 @@ +name: "CodeQL" + +on: + push: + branches: [ "develop" ] + pull_request: + branches: [ "develop" ] + schedule: + - cron: "27 17 * * 0" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ cpp ] + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: ${{ matrix.language }} + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v2 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:${{ matrix.language }}" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml new file mode 100644 index 000000000..51861533e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/configure.yml @@ -0,0 +1,238 @@ +name: Configure +on: [push, pull_request] +jobs: + configure: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + configure-args: --warn + + - name: Ubuntu 20.04 GCC + os: ubuntu-20.04 + compiler: gcc + configure-args: --warn + + - name: Ubuntu GCC OSB + os: ubuntu-latest + compiler: gcc + configure-args: --warn + build-dir: ../build + build-src-dir: ../zlib-ng + + - name: Ubuntu GCC Compat No Opt + os: ubuntu-latest + compiler: gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + + - name: Ubuntu GCC ARM SF + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM SF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabi-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabi + packages: qemu qemu-user gcc-arm-linux-gnueabi libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No ACLE + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-acle + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF No NEON + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --without-neon + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC ARM HF Compat No Opt + os: ubuntu-latest + compiler: arm-linux-gnueabihf-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: arm-linux-gnueabihf + packages: qemu qemu-user gcc-arm-linux-gnueabihf libc-dev-armel-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No ACLE + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-acle + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 No NEON + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --without-neon + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC AARCH64 Compat No Opt + os: ubuntu-latest + compiler: aarch64-linux-gnu-gcc + configure-args: --warn --zlib-compat --without-optimizations --without-new-strategies + chost: aarch64-linux-gnu + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC No Power8 + os: ubuntu-latest + compiler: powerpc-linux-gnu-gcc + configure-args: --warn --without-power8 + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc-linux-gnu libc-dev-powerpc-cross + + - name: Ubuntu GCC PPC64 + os: ubuntu-latest + compiler: powerpc64-linux-gnu-gcc + configure-args: --warn --static + chost: powerpc-linux-gnu + packages: qemu qemu-user gcc-powerpc64-linux-gnu libc-dev-ppc64-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + compiler: powerpc64le-linux-gnu-gcc + configure-args: --warn + chost: powerpc64le-linux-gnu + packages: qemu qemu-user gcc-powerpc64le-linux-gnu libc-dev-ppc64el-cross + + - name: Ubuntu GCC S390X + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X No vectorized CRC32 + os: ubuntu-latest + compiler: s390x-linux-gnu-gcc + configure-args: --warn --static --without-crc32-vx + chost: s390x-linux-gnu + packages: qemu qemu-user gcc-s390x-linux-gnu libc-dev-s390x-cross + cflags: -static + ldflags: -static + + - name: Ubuntu GCC S390X DFLTCC + os: z15 + compiler: gcc + configure-args: --warn --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu GCC S390X DFLTCC Compat + os: z15 + compiler: gcc + configure-args: --warn --zlib-compat --static --with-dfltcc-deflate --with-dfltcc-inflate + + - name: Ubuntu Emscripten WASM32 + os: ubuntu-latest + chost: wasm32 + configure-args: --warn --zlib-compat --static + configure-prefix: emconfigure + cflags: -static + ldflags: -static + emu-run: node + + - name: macOS GCC Symbol Prefix + os: macOS-latest + compiler: gcc-11 + configure-args: --sprefix=zTest_ + + - name: macOS GCC Symbol Prefix & Compat + os: macOS-latest + compiler: gcc-11 + configure-args: --zlib-compat --sprefix=zTest_ + + - name: macOS GCC + os: macOS-latest + compiler: gcc-11 + configure-args: --warn + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Install Emscripten + if: contains(matrix.name, 'WASM32') + uses: mymindstorm/setup-emsdk@v12 + + - name: Generate project files + run: | + mkdir ${{ matrix.build-dir || '.not-used' }} + cd ${{ matrix.build-dir || '.' }} + ${{ matrix.configure-prefix }} ${{ matrix.build-src-dir || '.' }}/configure ${{ matrix.configure-args }} + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CHOST: ${{ matrix.chost }} + EMU_RUN: ${{ matrix.emu-run }} + CI: true + + - name: Compile source code + run: make -j2 + working-directory: ${{ matrix.build-dir }} + + - name: Run test cases + run: make test + working-directory: ${{ matrix.build-dir }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (configure) + path: | + **/Makefile + ${{ matrix.build-dir || '.' }}/configure.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml new file mode 100644 index 000000000..95d64e67a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/fuzz.yml @@ -0,0 +1,36 @@ +name: OSS-Fuzz +on: + pull_request: + push: + branches: + - stable + - develop + - pre-release + - '2.*' + tags: + - '*' + +jobs: + fuzzing: + name: Fuzzing + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + dry-run: false + + - name: Run Fuzzers + uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master + with: + oss-fuzz-project-name: 'zlib-ng' + fuzz-seconds: 600 + dry-run: false + + - name: Upload Crash + uses: actions/upload-artifact@v3 + if: failure() + with: + name: artifacts + path: ./out/artifacts diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml new file mode 100644 index 000000000..c5fea574f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/libpng.yml @@ -0,0 +1,51 @@ +name: Libpng +on: [push, pull_request] +jobs: + libpng: + name: Ubuntu Clang + runs-on: ubuntu-latest + steps: + - name: Checkout repository (zlib-ng) + uses: actions/checkout@v3 + + - name: Generate project files (zlib-ng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_COMPAT=ON \ + -DZLIB_ENABLE_TESTS=OFF + env: + CC: clang + CFLAGS: -fPIC + CI: true + + - name: Compile source code (zlib-ng) + run: cmake --build . -j2 --config Release + + - name: Checkout repository (libpng) + uses: actions/checkout@v3 + with: + repository: glennrp/libpng + path: libpng + + - name: Generate project files (libpng) + run: | + cmake . \ + -DCMAKE_BUILD_TYPE=Release \ + -DPNG_TESTS=ON \ + -DPNG_STATIC=OFF \ + -DZLIB_INCLUDE_DIR=.. \ + -DZLIB_LIBRARY=$PWD/../libz.a + working-directory: libpng + env: + CC: clang + CI: true + + - name: Compile source code (libpng) + run: cmake --build . -j2 --config Release + working-directory: libpng + + - name: Run test cases (libpng) + run: ctest -j2 -C Release --output-on-failure --max-width 120 + working-directory: libpng diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml new file mode 100644 index 000000000..5de669840 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/link.yml @@ -0,0 +1,66 @@ +name: Link +on: [push, pull_request] +jobs: + zlib: + name: Link zlib + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout zlib repository + uses: actions/checkout@v3 + with: + repository: madler/zlib + path: zlib + + - name: Generate project files (zlib) + run: cmake -S zlib -B zlib/build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF + + - name: Compile source code (zlib) + run: cmake --build zlib/build -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../zlib/build/libz.a -DZLIB_INCLUDE_DIR="../zlib/build;../zlib" + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 + + zlib-ng-compat: + name: Link zlib-ng compat + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Generate project files (compat) + run: cmake -S . -B compat -DZLIB_COMPAT=ON -DZLIB_ENABLE_TESTS=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DWITH_MAINTAINER_WARNINGS=ON + + - name: Compile source code (compat) + run: cmake --build compat -j2 --config Release + + - name: Generate project files (native) + run: cmake -S . -B native -DZLIB_COMPAT=OFF -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DZLIB_LIBRARIES=../compat/libz.a -DZLIB_INCLUDE_DIR=../compat + + - name: Compile source code (native) + run: cmake --build native -j2 --config Release + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: Link zlib-ng compat (CMake Logs) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml new file mode 100644 index 000000000..38e669093 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/nmake.yml @@ -0,0 +1,68 @@ +name: NMake +on: [push, pull_request] +jobs: + nmake: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows NMake x86 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86 + + - name: Windows NMake x64 compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes + + - name: Windows NMake x64 Symbol Prefix + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 Symbol Prefix Compat + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + additional-args: ZLIB_COMPAT=yes SYMBOL_PREFIX=zTest_ + + - name: Windows NMake x64 + os: windows-2022 + makefile: win32/Makefile.msc + arch: x86_amd64 + + - name: Windows NMake ARM No Test + os: windows-2022 + makefile: win32/Makefile.arm + arch: x86_arm + + - name: Windows NMake ARM64 No Test + os: windows-2022 + makefile: win32/Makefile.a64 + arch: x86_arm64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Setup development environment + uses: ilammy/msvc-dev-cmd@v1.12.1 + with: + arch: ${{ matrix.arch }} + + - name: Compile source code + shell: cmd + run: nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} + + - name: Run test cases + shell: cmd + # Don't run tests on Windows ARM + if: contains(matrix.arch, 'arm') == false + run: | + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} test + nmake -f ${{ matrix.makefile }} ${{ matrix.additional-args }} testdll diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml new file mode 100644 index 000000000..be4e1ce50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pigz.yml @@ -0,0 +1,131 @@ +name: Pigz +on: [push, pull_request] +jobs: + pigz: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + + - name: Ubuntu GCC Symbol Prefix + os: ubuntu-latest + compiler: gcc + codecov: ubuntu_gcc_pigz + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + + - name: Ubuntu Clang + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz + + - name: Ubuntu Clang No Optim + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_optim + cmake-args: -DWITH_OPTIM=OFF + + # Use v2.6 due to NOTHREADS bug https://github.com/madler/pigz/issues/97 + - name: Ubuntu Clang No Threads + os: ubuntu-latest + compiler: clang + packages: llvm-11 llvm-11-tools + gcov-exec: llvm-cov-11 gcov + codecov: ubuntu_clang_pigz_no_threads + cmake-args: -DWITH_THREADS=OFF -DPIGZ_VERSION=v2.6 + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + cmake-args: -DCMAKE_TOOLCHAIN_FILE=../../cmake/toolchain-aarch64.cmake + packages: qemu qemu-user gcc-aarch64-linux-gnu libc-dev-arm64-cross + codecov: ubuntu_gcc_pigz_aarch64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Checkout test corpora + uses: actions/checkout@v3 + with: + repository: zlib-ng/corpora + path: test/data/corpora + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' && matrix.packages + run: | + sudo apt-get update + sudo apt-get install -y ${{ matrix.packages }} + + - name: Generate project files + run: | + cmake ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=${{ matrix.build-config || 'Release' }} \ + -DBUILD_SHARED_LIBS=OFF \ + -DZLIB_ROOT=../.. \ + -DWITH_CODE_COVERAGE=ON \ + -DWITH_MAINTAINER_WARNINGS=ON + working-directory: test/pigz + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + LDFLAGS: ${{ matrix.ldflags }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config ${{ matrix.build-config || 'Release' }} + working-directory: test/pigz + + - name: Run test cases + run: ctest --verbose -C Release --output-on-failure --max-width 120 -j ${{ matrix.parallels-jobs || '3' }} + working-directory: test/pigz + + - name: Generate coverage report + if: matrix.codecov + run: | + python3 -u -m pip install --user gcovr==5.0 + python3 -m gcovr -j 3 --verbose \ + --exclude-unreachable-branches \ + --gcov-executable "${{ matrix.gcov-exec || 'gcov' }}" \ + --root . \ + --xml --output coverage.xml + + - name: Upload coverage report + uses: codecov/codecov-action@v3 + if: matrix.codecov && (env.CODECOV_TOKEN != '' || github.repository == 'zlib-ng/zlib-ng') + with: + token: ${{ secrets.CODECOV_TOKEN || 'e4fdf847-f541-4ab1-9d50-3d27e5913906' }} + flags: ${{ matrix.codecov }} + name: ${{ matrix.name }} + verbose: true + fail_ci_if_error: true + env: + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} (cmake) + path: | + **/CMakeFiles/CMakeOutput.log + **/CMakeFiles/CMakeError.log + **/Testing/Temporary/* + coverage.xml + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml new file mode 100644 index 000000000..8888cf37e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/pkgcheck.yml @@ -0,0 +1,176 @@ +name: Package Check +on: [push, pull_request] +jobs: + pkgcheck: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Ubuntu GCC + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + + - name: Ubuntu GCC -m32 + os: ubuntu-latest + compiler: gcc + cxx-compiler: g++ + packages: gcc-multilib g++-multilib + cmake-args: -DCMAKE_C_FLAGS=-m32 -DCMAKE_CXX_FLAGS=-m32 + cflags: -m32 + cxxflags: -m32 + ldflags: -m32 + + - name: Ubuntu GCC ARM HF + os: ubuntu-latest + chost: arm-linux-gnueabihf + compiler: arm-linux-gnueabihf-gcc + cxx-compiler: g++-arm-linux-gnueabihf + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-armhf.cmake + packages: qemu gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf libc6-dev-armhf-cross + + - name: Ubuntu GCC AARCH64 + os: ubuntu-latest + chost: aarch64-linux-gnu + compiler: aarch64-linux-gnu-gcc + cxx-compiler: g++-aarch64-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-aarch64.cmake + packages: qemu gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libc6-dev-arm64-cross + + - name: Ubuntu GCC PPC + os: ubuntu-latest + chost: powerpc-linux-gnu + compiler: powerpc-linux-gnu-gcc + cxx-compiler: g++-powerpc-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc.cmake + packages: qemu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-powerpc-cross + + - name: Ubuntu GCC PPC64LE + os: ubuntu-latest + chost: powerpc64le-linux-gnu + compiler: powerpc64le-linux-gnu-gcc + cxx-compiler: g++-powerpc64le-linux-gnu + cmake-args: -DCMAKE_TOOLCHAIN_FILE=cmake/toolchain-powerpc64le.cmake + packages: qemu gcc-powerpc64le-linux-gnu g++-powerpc64le-linux-gnu libc6-dev-ppc64el-cross + + - name: macOS Clang + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + + - name: macOS Clang Native + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DWITH_NATIVE_INSTRUCTIONS=ON + configure-args: --native + + - name: macOS Clang Symbol Prefix + os: macOS-11 + compiler: clang + cxx-compiler: clang++ + cmake-args: -DZLIB_SYMBOL_PREFIX=zTest_ + configure-args: --sprefix=zTest_ + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Add ubuntu mirrors + if: runner.os == 'Linux' && matrix.packages + run: | + # Github Actions caching proxy is at times unreliable + echo -e 'http://azure.archive.ubuntu.com/ubuntu\tpriority:1\n' | sudo tee /etc/apt/mirrors.txt + curl http://mirrors.ubuntu.com/mirrors.txt | sudo tee --append /etc/apt/mirrors.txt + sudo sed -i 's#http://azure.archive.ubuntu.com/ubuntu/#mirror+file:/etc/apt/mirrors.txt#' /etc/apt/sources.list + + - name: Install packages (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends ${{ matrix.packages }} \ + abigail-tools \ + diffoscope \ + ninja-build + + - name: Install packages (macOS) + if: runner.os == 'macOS' + run: brew install ninja diffoscope ${{ matrix.packages }} + env: + HOMEBREW_NO_INSTALL_CLEANUP: 1 + + - name: Select Xcode version (macOS) + # Use a version of Xcode that supports ZERO_AR_DATE until CMake supports + # AppleClang linking with libtool using -D argument + # https://gitlab.kitware.com/cmake/cmake/-/issues/19852 + if: runner.os == 'macOS' + uses: maxim-lobanov/setup-xcode@v1 + with: + xcode-version: '11.7.0' + + - name: Compare builds + run: sh test/pkgcheck.sh + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Compare builds (compat) + run: sh test/pkgcheck.sh --zlib-compat + env: + CC: ${{ matrix.compiler }} + CFLAGS: ${{ matrix.cflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Check ABI (compat) + # macOS runner does not contain abigail + if: runner.os != 'macOS' + run: sh test/abicheck.sh --zlib-compat --refresh-if + env: + CC: ${{ matrix.compiler }} + CXX: ${{ matrix.cxx-compiler }} + CFLAGS: ${{ matrix.cflags }} + CXXFLAGS: ${{ matrix.cxxflags }} + CHOST: ${{ matrix.chost }} + CMAKE_ARGS: ${{ matrix.cmake-args }} + CONFIGURE_ARGS: ${{ matrix.configure-args }} + LDFLAGS: ${{ matrix.ldflags }} + + - name: Upload build errors + uses: actions/upload-artifact@v3 + if: failure() + with: + name: ${{ matrix.name }} + path: | + **/*.abi + btmp1/configure.log + btmp1/CMakeFiles/CMakeOutput.log + btmp1/CMakeFiles/CMakeError.log + btmp2/configure.log + btmp2/CMakeFiles/CMakeOutput.log + btmp2/CMakeFiles/CMakeError.log + retention-days: 30 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml new file mode 100644 index 000000000..b64933cc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.github/workflows/release.yml @@ -0,0 +1,100 @@ +name: Release +on: + push: + tags: + - '*' +jobs: + release: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - name: Windows MSVC Win32 + os: windows-latest + compiler: cl + cmake-args: -A Win32 + deploy-name: win-x86 + + - name: Windows MSVC Win32 Compat + os: windows-latest + compiler: cl + cmake-args: -A Win32 -DZLIB_COMPAT=ON + deploy-name: win-x86-compat + + - name: Windows MSVC Win64 + os: windows-latest + compiler: cl + cmake-args: -A x64 + deploy-name: win-x86-64 + + - name: Windows MSVC Win64 Compat + os: windows-latest + compiler: cl + cmake-args: -A x64 -DZLIB_COMPAT=ON + deploy-name: win-x86-64-compat + + - name: Windows MSVC ARM + os: windows-latest + compiler: cl + cmake-args: -A ARM + deploy-name: win-arm + + - name: Windows MSVC ARM Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM -DZLIB_COMPAT=ON + deploy-name: win-arm-compat + + - name: Windows MSVC ARM64 + os: windows-latest + compiler: cl + cmake-args: -A ARM64 + deploy-name: win-arm64 + + - name: Windows MSVC ARM64 Compat + os: windows-latest + compiler: cl + cmake-args: -A ARM64 -DZLIB_COMPAT=ON + deploy-name: win-arm64-compat + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Set environment variables + shell: bash + run: echo "tag=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV + + - name: Generate project files + shell: bash + run: | + cmake . ${{ matrix.cmake-args }} \ + -DCMAKE_BUILD_TYPE=Release \ + -DZLIB_ENABLE_TESTS=ON \ + -DCMAKE_INSTALL_PREFIX=out \ + -DINSTALL_UTILS=ON + env: + CC: ${{ matrix.compiler }} + CI: true + + - name: Compile source code + run: cmake --build . -j2 --config Release --target install + + - name: Package release (Windows) + if: runner.os == 'Windows' + run: 7z a -tzip ../zlib-ng-${{ matrix.deploy-name }}.zip bin include lib ../LICENSE.md ../PORTING.md ../README.md + working-directory: out + + - name: Upload release (Windows) + uses: svenstaro/upload-release-action@v2 + if: runner.os == 'Windows' + with: + asset_name: zlib-ng-${{ matrix.deploy-name }}.zip + file: zlib-ng-${{ matrix.deploy-name }}.zip + tag: ${{env.tag}} + repo_token: ${{ secrets.GITHUB_TOKEN }} + overwrite: true + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore b/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore new file mode 100644 index 000000000..cd4a9c3fe --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.gitignore @@ -0,0 +1,97 @@ +*.diff +*.patch +*.orig +*.rej + +*~ +*.a +*.lo +*.o +*.dylib + +*.gcda +*.gcno +*.gcov + +/benchmark_zlib +/example +/example64 +/examplesh +/gtest_zlib +/libz.so* +/libz-ng.so* +/makefixed +/minigzip +/minigzip64 +/minigzipsh +/switchlevels +/zlib.pc +/zlib-ng.pc + +.DS_Store +*_fuzzer +*.obj +*.exe +*.pdb +*.exp +*.lib +*.dll +*.res +foo.gz +*.manifest +*.opensdf +*.sln +*.sdf +*.vcxproj +*.vcxproj.filters +*.vcxproj.user +.vs + +CMakeCache.txt +CMakeFiles +Testing +/*.cmake +*.stackdump +*._h +zconf.h +zconf.h.cmakein +zconf.h.included +zconf-ng.h +zconf-ng.h.cmakein +ztest* +/test/CTestTestfile.cmake +/test/cmake_install.cmake + +configure.log +a.out + +/Makefile +/arch/arm/Makefile +/arch/generic/Makefile +/arch/power/Makefile +/arch/x86/Makefile +.kdev4 +*.kdev4 + +/Debug +/example.dir +/minigzip.dir +/zlib.dir +/zlibstatic.dir +/test/*.dir/ +/build/ +/build[.-]*/ +/btmp[12]/ +/pkgtmp[12]/ + +/.idea +/cmake-build-debug +/x64/Debug/ +/x64/Release/ +/win32/Debug/ +/win32/Release/ +/ARM*/Debug/ +/ARM*/Release/ +MinSizeRel +RelWithDebInfo +/_deps/googletest* diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/.shellcheckrc b/internal-complibs/zlib-ng-2.1.1-beta2/.shellcheckrc new file mode 100644 index 000000000..89a1625ff --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/.shellcheckrc @@ -0,0 +1 @@ +disable=SC2140,SC2086,SC2046,SC2015,SC1097,SC1035,SC1036,SC1007,SC2154,SC2155,SC2000,SC2034,SC2016,SC1091,SC1090,SC2212,SC2143,SC2129,SC2102,SC2069,SC1041,SC1042,SC1044,SC1046,SC1119,SC1110,SC1111,SC1112,SC1102,SC1105,SC1101,SC1004,SC1003,SC1012,SC2068,SC2065,SC2064,SC2063,SC2059,SC2053,SC2048,SC2044,SC2032,SC2031,SC2030,SC2029,SC2025,SC2024,SC2022,SC2018,SC2019,SC2017,SC2014,SC2013,SC2012,SC2009,SC2001,SC2098,SC2096,SC2094,SC2091,SC2092,SC2088,SC2087,SC2076,SC2072,SC2071,SC2223,SC2221,SC2222,SC2217,SC2207,SC2206,SC2205,SC2190,SC2188,SC2187,SC2185,SC2179,SC2178,SC2174,SC2168,SC2167,SC2163,SC2161,SC2160,SC2153,SC2150,SC2148,SC2147,SC2146,SC2142,SC2139,SC2126,SC2123,SC2120,SC2119,SC2117,SC2114,SC1117,SC2164,SC1083,SC2004,SC2125,SC2128,SC2011,SC1008,SC1019,SC2093,SC1132,SC1129,SC2236,SC2237,SC2231,SC2230,SC2229,SC2106,SC2102,SC2243,SC2244,SC2245,SC2247,SC2248,SC2249,SC2250,SC2251,SC2252,SC2181 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/CMakeLists.txt b/internal-complibs/zlib-ng-2.1.1-beta2/CMakeLists.txt new file mode 100644 index 000000000..424fddf61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/CMakeLists.txt @@ -0,0 +1,1268 @@ +cmake_minimum_required(VERSION 3.5.1) +if(CMAKE_VERSION VERSION_LESS 3.12) + cmake_policy(VERSION ${CMAKE_VERSION}) +else() + cmake_policy(VERSION 3.5.1...3.13.2) +endif() +message(STATUS "Using CMake version ${CMAKE_VERSION}") + +# If not specified on the command line, enable C11 as the default +# Configuration items that affect the global compiler environment standards +# should be issued before the "project" command. +if(NOT CMAKE_C_STANDARD) + set(CMAKE_C_STANDARD 11) # The C standard whose features are requested to build this target +endif() +if(NOT CMAKE_C_STANDARD_REQUIRED) + set(CMAKE_C_STANDARD_REQUIRED ON) # Boolean describing whether the value of C_STANDARD is a requirement +endif() +if(NOT CMAKE_C_EXTENSIONS) + set(CMAKE_C_EXTENSIONS OFF) # Boolean specifying whether compiler specific extensions are requested +endif() +set(VALID_C_STANDARDS "99" "11") +if(NOT CMAKE_C_STANDARD IN_LIST VALID_C_STANDARDS) + MESSAGE(FATAL_ERROR "CMAKE_C_STANDARD:STRING=${CMAKE_C_STANDARD} not in known standards list\n ${VALID_C_STANDARDS}") +endif() + +# Parse the full version number from zlib.h and include in ZLIB_FULL_VERSION +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in _zlib_h_contents) +string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([0-9]+.[0-9]+.[0-9]+).*\".*" + "\\1" ZLIB_HEADER_VERSION ${_zlib_h_contents}) +string(REGEX REPLACE ".*#define[ \t]+ZLIBNG_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*" + "\\1" ZLIBNG_HEADER_VERSION ${_zlib_h_contents}) +message(STATUS "ZLIB_HEADER_VERSION: ${ZLIB_HEADER_VERSION}") +message(STATUS "ZLIBNG_HEADER_VERSION: ${ZLIBNG_HEADER_VERSION}") + +project(zlib VERSION ${ZLIB_HEADER_VERSION} LANGUAGES C) + +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckFunctionExists) +include(CheckIncludeFile) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) +include(CheckCCompilerFlag) +include(CMakeDependentOption) +include(FeatureSummary) + +include(cmake/detect-arch.cmake) +include(cmake/detect-install-dirs.cmake) +include(cmake/detect-coverage.cmake) +include(cmake/detect-intrinsics.cmake) +include(cmake/detect-sanitizer.cmake) +include(cmake/fallback-macros.cmake) + +if(CMAKE_TOOLCHAIN_FILE) + message(STATUS "Using CMake toolchain: ${CMAKE_TOOLCHAIN_FILE}") +endif() + +# Make sure we use an appropriate BUILD_TYPE by default, "Release" to be exact +# this should select the maximum generic optimisation on the current platform (i.e. -O3 for gcc/clang) +if(NOT GENERATOR_IS_MULTI_CONFIG) + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING + "Choose the type of build, standard options are: Debug Release RelWithDebInfo MinSizeRel." + FORCE) + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (default)") + else() + add_feature_info(CMAKE_BUILD_TYPE 1 "Build type: ${CMAKE_BUILD_TYPE} (selected)") + endif() +endif() + +# +# Options parsing +# +option(WITH_GZFILEOP "Compile with support for gzFile related functions" ON) +option(ZLIB_COMPAT "Compile with zlib compatible API" OFF) +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +option(ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API" ON) +option(WITH_GTEST "Build gtest_zlib" ON) +option(WITH_FUZZERS "Build test/fuzz" OFF) +option(WITH_BENCHMARKS "Build test/benchmarks" OFF) +option(WITH_BENCHMARK_APPS "Build application benchmarks" OFF) +option(WITH_OPTIM "Build with optimisation" ON) +option(WITH_REDUCED_MEM "Reduced memory usage for special cases (reduces performance)" OFF) +option(WITH_NEW_STRATEGIES "Use new strategies" ON) +option(WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)" OFF) +option(WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings" OFF) +option(WITH_CODE_COVERAGE "Enable code coverage reporting" OFF) +option(WITH_INFLATE_STRICT "Build with strict inflate distance checking" OFF) +option(WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances" OFF) +option(WITH_UNALIGNED "Support unaligned reads on platforms that support it" ON) + +set(ZLIB_SYMBOL_PREFIX "" CACHE STRING "Give this prefix to all publicly exported symbols. +Useful when embedding into a larger library. +Default is no prefix (empty prefix).") + +# Add multi-choice option +set(WITH_SANITIZER AUTO CACHE STRING "Enable sanitizer support") +set_property(CACHE WITH_SANITIZER PROPERTY STRINGS "Memory" "Address" "Undefined" "Thread") + +if(BASEARCH_ARM_FOUND) + option(WITH_ACLE "Build with ACLE" ON) + option(WITH_NEON "Build with NEON intrinsics" ON) +elseif(BASEARCH_PPC_FOUND) + option(WITH_ALTIVEC "Build with AltiVec (VMX) optimisations for PowerPC" ON) + option(WITH_POWER8 "Build with optimisations for POWER8" ON) + option(WITH_POWER9 "Build with optimisations for POWER9" ON) +elseif(BASEARCH_RISCV_FOUND) + option(WITH_RVV "Build with RVV intrinsics" ON) +elseif(BASEARCH_S360_FOUND) + option(WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z" OFF) + option(WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z" OFF) + option(WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z" ON) +elseif(BASEARCH_X86_FOUND) + option(WITH_AVX2 "Build with AVX2" ON) + option(WITH_AVX512 "Build with AVX512" ON) + option(WITH_AVX512VNNI "Build with AVX512 VNNI extensions" ON) + option(WITH_SSE2 "Build with SSE2" ON) + option(WITH_SSSE3 "Build with SSSE3" ON) + option(WITH_SSE42 "Build with SSE42" ON) + option(WITH_PCLMULQDQ "Build with PCLMULQDQ" ON) + option(WITH_VPCLMULQDQ "Build with VPCLMULQDQ" ON) +endif() + +option(INSTALL_UTILS "Copy minigzip and minideflate during install" OFF) + +mark_as_advanced(FORCE + ZLIB_SYMBOL_PREFIX + WITH_REDUCED_MEM + WITH_ACLE WITH_NEON + WITH_DFLTCC_DEFLATE + WITH_DFLTCC_INFLATE + WITH_CRC32_VX + WITH_AVX2 WITH_SSE2 + WITH_SSSE3 WITH_SSE42 + WITH_PCLMULQDQ + WITH_ALTIVEC + WITH_POWER8 + WITH_POWER9 + WITH_RVV + WITH_INFLATE_STRICT + WITH_INFLATE_ALLOW_INVALID_DIST + WITH_UNALIGNED + INSTALL_UTILS + ) + +if(ZLIB_COMPAT) + add_definitions(-DZLIB_COMPAT) + set(WITH_GZFILEOP ON) + set(SUFFIX "") + set(ZLIB_FULL_VERSION ${ZLIB_HEADER_VERSION}.zlib-ng) +else() + set(SUFFIX "-ng") + set(ZLIB_FULL_VERSION ${ZLIBNG_HEADER_VERSION}) +endif() + +if(WITH_GZFILEOP) + add_definitions(-DWITH_GZFILEOP) +endif() + +if(CMAKE_C_COMPILER_ID MATCHES "^Intel") + if(CMAKE_HOST_UNIX) + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wall -Wcheck -Wremarks) + set(WARNFLAGS_DISABLE) + else() + set(WARNFLAGS /Wall) + set(WARNFLAGS_MAINTAINER /W5) + set(WARNFLAGS_DISABLE) + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(MSVC) + # Minimum supported MSVC version is 1800 = Visual Studio 12.0/2013 + # See also https://cmake.org/cmake/help/latest/variable/MSVC_VERSION.html + if(MSVC_VERSION VERSION_LESS 1800) + message(SEND_ERROR "Unsupported Visual Studio compiler version (requires 2013 or later).") + endif() + # TODO. ICC can be used through MSVC. I'm not sure if we'd ever see that combination + # (who'd use cmake from an IDE...) but checking for ICC before checking for MSVC should + # avoid mistakes. + # /Oi ? + set(WARNFLAGS /W3) + set(WARNFLAGS_MAINTAINER /W4) + set(WARNFLAGS_DISABLE) + if(BASEARCH_ARM_FOUND) + add_definitions(-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE) + if(NOT "${ARCH}" MATCHES "aarch64") + set(NEONFLAG "/arch:VFPv4") + endif() + endif() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not supported on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + # Enable warnings in GCC and Clang + set(WARNFLAGS -Wall) + set(WARNFLAGS_MAINTAINER -Wextra) + set(WARNFLAGS_DISABLE) + if(WITH_NATIVE_INSTRUCTIONS) + if(BASEARCH_PPC_FOUND) + set(NATIVEFLAG "-mcpu=native") + else() + set(NATIVEFLAG "-march=native") + endif() + else() + if(BASEARCH_ARM_FOUND) + if("${ARCH}" MATCHES "arm" AND NOT CMAKE_C_FLAGS MATCHES "-mfloat-abi") + # Auto-detect support for ARM floating point ABI + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=softfp) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_SOFTFP) + if(HAVE_FLOATABI_SOFTFP) + set(FLOATABI -mfloat-abi=softfp) + else() + set(CMAKE_REQUIRED_FLAGS -mfloat-abi=hard) + check_c_source_compiles( + "#include + int main() { return 0; }" + HAVE_FLOATABI_HARD) + if(HAVE_FLOATABI_HARD) + set(FLOATABI -mfloat-abi=hard) + endif() + endif() + set(CMAKE_REQUIRED_FLAGS) + if(FLOATABI) + message(STATUS "ARM floating point arch: ${FLOATABI}") + add_compile_options(${FLOATABI}) + else() + message(STATUS "ARM floating point arch not auto-detected") + endif() + endif() + endif() + # Check whether -fno-lto is available + set(CMAKE_REQUIRED_FLAGS "-fno-lto") + check_c_source_compiles( + "int main() { return 0; }" + FNO_LTO_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) + if(FNO_LTO_AVAILABLE) + set(NOLTOFLAG "-fno-lto") + endif() + endif() + if(MINGW) + list(APPEND WARNFLAGS_DISABLE -Wno-pedantic-ms-format) + endif() +else() + if(WITH_NATIVE_INSTRUCTIONS) + message(STATUS "Ignoring WITH_NATIVE_INSTRUCTIONS; not implemented yet on this configuration") + set(WITH_NATIVE_INSTRUCTIONS OFF) + endif() +endif() + +# Disable LTO +if(NOT WITH_NATIVE_INSTRUCTIONS) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF) + foreach(_cfg_name IN LISTS CMAKE_CONFIGURATION_TYPES) + string(TOUPPER "${_cfg_name}" _cfg_name_uc) + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_${_cfg_name_uc} OFF) + endforeach() +endif() + +# Set architecture alignment requirements +if(NOT WITH_UNALIGNED) + add_definitions(-DNO_UNALIGNED) + message(STATUS "Unaligned reads manually disabled") +endif() + +# Apply warning compiler flags +if(WITH_MAINTAINER_WARNINGS) + add_compile_options(${WARNFLAGS} ${WARNFLAGS_MAINTAINER} ${WARNFLAGS_DISABLE}) +else() + add_compile_options(${WARNFLAGS} ${WARNFLAGS_DISABLE}) +endif() + +# Set code coverage compiler flags +if(WITH_CODE_COVERAGE) + add_code_coverage() +endif() + +# Replace optimization level 3 added by default with level 2 +if(NOT WITH_CODE_COVERAGE AND NOT MSVC AND NOT CMAKE_C_FLAGS MATCHES "([\\/\\-]O)3") + string(REGEX REPLACE "([\\/\\-]O)3" "\\12" + CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}") +endif() + +# Set native instruction set compiler flag +if(WITH_NATIVE_INSTRUCTIONS AND DEFINED NATIVEFLAG) + # Apply flag to all source files and compilation checks + add_compile_options(${NATIVEFLAG}) +endif() + +# +# Check for standard/system includes +# +check_include_file(sys/auxv.h HAVE_SYS_AUXV_H) +if(HAVE_SYS_AUXV_H) + add_definitions(-DHAVE_SYS_AUXV_H) +endif() +check_include_file(sys/sdt.h HAVE_SYS_SDT_H) +if(HAVE_SYS_SDT_H) + add_definitions(-DHAVE_SYS_SDT_H) +endif() +check_include_file(unistd.h HAVE_UNISTD_H) + +# +# Check to see if we have large file support +# +set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +check_type_size(off64_t OFF64_T) +if(HAVE_OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) +else() + check_type_size(_off64_t _OFF64_T) + if(HAVE__OFF64_T) + add_definitions(-D_LARGEFILE64_SOURCE=1 -D__USE_LARGEFILE64) + else() + check_type_size(__off64_t __OFF64_T) + endif() +endif() +set(CMAKE_REQUIRED_DEFINITIONS) # clear variable + +# +# Check for fseeko and other optional functions +# +check_function_exists(fseeko HAVE_FSEEKO) +if(NOT HAVE_FSEEKO) + add_definitions(-DNO_FSEEKO) +endif() + +check_function_exists(strerror HAVE_STRERROR) +if(NOT HAVE_STRERROR) + add_definitions(-DNO_STRERROR) +endif() + +set(CMAKE_REQUIRED_DEFINITIONS -D_POSIX_C_SOURCE=200112L) +check_symbol_exists(posix_memalign stdlib.h HAVE_POSIX_MEMALIGN) +if(HAVE_POSIX_MEMALIGN) + add_definitions(-DHAVE_POSIX_MEMALIGN) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +set(CMAKE_REQUIRED_DEFINITIONS -D_ISOC11_SOURCE=1) +check_symbol_exists(aligned_alloc stdlib.h HAVE_ALIGNED_ALLOC) +if(HAVE_ALIGNED_ALLOC) + add_definitions(-DHAVE_ALIGNED_ALLOC) +endif() +set(CMAKE_REQUIRED_DEFINITIONS) + +if(WITH_SANITIZER STREQUAL "Address") + add_address_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Memory") + add_memory_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Thread") + add_thread_sanitizer() +elseif(WITH_SANITIZER STREQUAL "Undefined") + add_undefined_sanitizer() +endif() + +# +# Check whether compiler supports -fno-semantic-interposition parameter +# +check_c_compiler_flag(-fno-semantic-interposition HAVE_NO_INTERPOSITION) + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using hidden +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"hidden\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_HIDDEN FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_HIDDEN) + add_definitions(-DHAVE_VISIBILITY_HIDDEN) +endif() + +# +# Check if we can hide zlib internal symbols that are linked between separate source files using internal +# +check_c_source_compiles( + "#define Z_INTERNAL __attribute__((visibility (\"internal\"))) + int Z_INTERNAL foo; + int main() { + return 0; + }" + HAVE_ATTRIBUTE_VISIBILITY_INTERNAL FAIL_REGEX "visibility") +if(HAVE_ATTRIBUTE_VISIBILITY_INTERNAL) + add_definitions(-DHAVE_VISIBILITY_INTERNAL) +endif() + +# +# Check for __attribute__((aligned(x))) support in the compiler +# +check_c_source_compiles( + "int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; + }" + HAVE_ATTRIBUTE_ALIGNED FAIL_REGEX "aligned") +if(HAVE_ATTRIBUTE_ALIGNED) + add_definitions(-DHAVE_ATTRIBUTE_ALIGNED) +endif() + +# +# check for _Thread_local() support in the compiler +# +check_c_source_compiles( + "_Thread_local int test; + int main(void) { + (void)test; + return 0; + }" + HAVE_THREAD_LOCAL +) +if(HAVE_THREAD_LOCAL) + add_definitions(-DHAVE_THREAD_LOCAL) +endif() + +# +# check for __builtin_ctz() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZ +) +if(HAVE_BUILTIN_CTZ) + add_definitions(-DHAVE_BUILTIN_CTZ) +endif() + +# +# check for __builtin_ctzll() support in the compiler +# +check_c_source_compiles( + "int main(void) { + unsigned int zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; + }" + HAVE_BUILTIN_CTZLL +) +if(HAVE_BUILTIN_CTZLL) + add_definitions(-DHAVE_BUILTIN_CTZLL) +endif() + +# +# check for ptrdiff_t support +# +check_c_source_compiles( + "#include + int main() { + ptrdiff_t *a; + (void)a; + return 0; + }" + HAVE_PTRDIFF_T +) +if(NOT HAVE_PTRDIFF_T) + set(NEED_PTRDIFF_T 1) + + check_type_size("void *" SIZEOF_DATA_PTR) + message(STATUS "sizeof(void *) is ${SIZEOF_DATA_PTR} bytes") + + if(${SIZEOF_DATA_PTR} MATCHES "4") + set(PTRDIFF_TYPE "uint32_t") + elseif(${SIZEOF_DATA_PTR} MATCHES "8") + set(PTRDIFF_TYPE "uint64_t") + else() + message(FATAL_ERROR "sizeof(void *) is neither 32 nor 64 bit") + endif() +endif() + +# Macro to check if source compiles +# (and, when compiling very natively, also runs). +macro(check_c_source_compile_or_run source flag) + if(CMAKE_CROSSCOMPILING OR NOT WITH_NATIVE_INSTRUCTIONS) + check_c_source_compiles("${source}" ${flag}) + else() + check_c_source_runs("${source}" ${flag}) + endif() +endmacro() + +add_compile_options($<$:-DZLIB_DEBUG>) + +if(MSVC) + set(CMAKE_DEBUG_POSTFIX "d") + add_definitions(-D_CRT_SECURE_NO_DEPRECATE) + add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE) +endif() + +if(BASEARCH_X86_FOUND) + # FORCE_SSE2 option will only be shown if HAVE_SSE2_INTRIN is true + if("${ARCH}" MATCHES "i[3-6]86") + cmake_dependent_option(FORCE_SSE2 "Always assume CPU is SSE2 capable" OFF "HAVE_SSE2_INTRIN" OFF) + endif() +endif() + +# +# Enable deflate_quick at level 1 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_QUICK_STRATEGY) +endif() +# +# Enable deflate_medium at level 4-6 +# +if(NOT WITH_NEW_STRATEGIES) + add_definitions(-DNO_MEDIUM_STRATEGY) +endif() +# +# Enable inflate compilation options +# +if(WITH_INFLATE_STRICT) + add_definitions(-DINFLATE_STRICT) + message(STATUS "Inflate strict distance checking enabled") +endif() +if(WITH_INFLATE_ALLOW_INVALID_DIST) + add_definitions(-DINFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR) + message(STATUS "Inflate zero data for invalid distances enabled") +endif() +# +# Enable reduced memory configuration +# +if(WITH_REDUCED_MEM) + add_definitions(-DHASH_SIZE=32768u -DGZBUFSIZE=8192) + message(STATUS "Configured for reduced memory environment") +endif() + + +set(ZLIB_ARCH_SRCS) +set(ZLIB_ARCH_HDRS) +set(ARCHDIR "arch/generic") +if(BASEARCH_ARM_FOUND) + set(ARCHDIR "arch/arm") +elseif(BASEARCH_PPC_FOUND) + set(ARCHDIR "arch/power") +elseif(BASEARCH_RISCV_FOUND) + set(ARCHDIR "arch/riscv") +elseif(BASEARCH_S360_FOUND) + set(ARCHDIR "arch/s390") +elseif(BASEARCH_X86_FOUND) + set(ARCHDIR "arch/x86") + if(NOT ${ARCH} MATCHES "x86_64") + add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") + endif() +else() + message(STATUS "No optimized architecture: using ${ARCHDIR}") +endif() + +if(WITH_OPTIM) + if(BASEARCH_ARM_FOUND) + add_definitions(-DARM_FEATURES) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + check_c_source_compiles( + "#include + #include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_HWCAP_HAS_CRC32 + ) + if (ARM_HWCAP_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP) + else() + message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if(ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if (ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + message(STATUS "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() + endif() + endif() + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/arm_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/arm_features.c) + if(WITH_ACLE AND NOT "${ARCH}" MATCHES "armv[2-7]") + check_acle_compiler_flag() + if(HAVE_ACLE_FLAG) + add_definitions(-DARM_ACLE) + set(ACLE_SRCS ${ARCHDIR}/crc32_acle.c ${ARCHDIR}/insert_string_acle.c) + set_property(SOURCE ${ACLE_SRCS} PROPERTY COMPILE_FLAGS "${ACLEFLAG} ${NOLTOFLAG}") + list(APPEND ZLIB_ARCH_SRCS ${ACLE_SRCS}) + add_feature_info(ACLE_CRC 1 "Support ACLE optimized CRC hash generation, using \"${ACLEFLAG}\"") + else() + set(WITH_ACLE OFF) + endif() + else() + set(WITH_ACLE OFF) + endif() + if(WITH_NEON) + check_neon_compiler_flag() + if(MFPU_NEON_AVAILABLE) + add_definitions(-DARM_NEON) + set(NEON_SRCS ${ARCHDIR}/adler32_neon.c ${ARCHDIR}/chunkset_neon.c + ${ARCHDIR}/compare256_neon.c ${ARCHDIR}/slide_hash_neon.c) + list(APPEND ZLIB_ARCH_SRCS ${NEON_SRCS}) + set_property(SOURCE ${NEON_SRCS} PROPERTY COMPILE_FLAGS "${NEONFLAG} ${NOLTOFLAG}") + if(MSVC) + add_definitions(-D__ARM_NEON__) + endif() + add_feature_info(NEON_ADLER32 1 "Support NEON instructions in adler32, using \"${NEONFLAG}\"") + add_feature_info(NEON_SLIDEHASH 1 "Support NEON instructions in slide_hash, using \"${NEONFLAG}\"") + check_neon_ld4_intrinsics() + if(NEON_HAS_LD4) + add_definitions(-DARM_NEON_HASLD4) + endif() + else() + set(WITH_NEON OFF) + endif() + endif() + elseif(BASEARCH_PPC_FOUND) + # Common arch detection code + if(WITH_ALTIVEC) + check_ppc_intrinsics() + endif() + if(WITH_POWER8) + check_power8_intrinsics() + endif() + if(WITH_POWER9) + check_power9_intrinsics() + endif() + if(HAVE_VMX OR HAVE_POWER8_INTRIN OR HAVE_POWER9_INTRIN) + add_definitions(-DPOWER_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/power_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/power_features.c) + endif() + # VMX specific options and files + if(WITH_ALTIVEC) + if(HAVE_VMX) + add_definitions(-DPPC_FEATURES) + if(HAVE_ALTIVEC) + add_definitions(-DPPC_VMX) + set(PPC_SRCS ${ARCHDIR}/adler32_vmx.c ${ARCHDIR}/slide_hash_vmx.c) + list(APPEND ZLIB_ARCH_SRCS ${PPC_SRCS}) + add_feature_info(ALTIVEC 1 "Support the AltiVec instruction set, using \"-maltivec\"") + set_property(SOURCE ${PPC_SRCS} PROPERTY COMPILE_FLAGS "${PPCFLAGS}") + else() + set(WITH_ALTIVEC OFF) + endif() + endif() + endif() + # Power8 specific options and files + if(WITH_POWER8) + if(HAVE_POWER8_INTRIN) + add_definitions(-DPOWER8_VSX) + set(POWER8_SRCS ${ARCHDIR}/adler32_power8.c ${ARCHDIR}/chunkset_power8.c ${ARCHDIR}/slide_hash_power8.c) + if("${ARCH}" MATCHES "powerpc64(le)?") + add_definitions(-DPOWER8_VSX_CRC32) + list(APPEND POWER8_SRCS ${ARCHDIR}/crc32_power8.c) + endif() + list(APPEND ZLIB_ARCH_SRCS ${POWER8_SRCS}) + set_property(SOURCE ${POWER8_SRCS} PROPERTY COMPILE_FLAGS "${POWER8FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER8 OFF) + endif() + endif() + # Power9 specific options and files + if(WITH_POWER9) + if(HAVE_POWER9_INTRIN) + add_definitions(-DPOWER9) + set(POWER9_SRCS ${ARCHDIR}/compare256_power9.c) + list(APPEND ZLIB_ARCH_SRCS ${POWER9_SRCS}) + set_property(SOURCE ${POWER9_SRCS} PROPERTY COMPILE_FLAGS "${POWER9FLAG} ${NOLTOFLAG}") + else() + set(WITH_POWER9 OFF) + endif() + endif() + elseif(BASEARCH_RISCV_FOUND) + if(WITH_RVV) + check_rvv_intrinsics() + if(HAVE_RVV_INTRIN) + add_definitions(-DRISCV_FEATURES) + add_definitions(-DRISCV_RVV) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/riscv_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/riscv_features.c) + else() + set(WITH_RVV OFF) + endif() + endif() + elseif(BASEARCH_S360_FOUND) + check_s390_intrinsics() + if(HAVE_S390_INTRIN) + add_definitions(-DS390_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/s390_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/s390_features.c) + endif() + if(WITH_DFLTCC_DEFLATE OR WITH_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_common.c) + endif() + if(WITH_DFLTCC_DEFLATE) + add_definitions(-DS390_DFLTCC_DEFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_deflate.c) + endif() + if(WITH_DFLTCC_INFLATE) + add_definitions(-DS390_DFLTCC_INFLATE) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/dfltcc_inflate.c) + endif() + if(WITH_CRC32_VX) + check_vgfma_intrinsics() + if(HAVE_VGFMA_INTRIN) + add_definitions(-DS390_CRC32_VX) + set(CRC32_VX_SRCS ${ARCHDIR}/crc32-vx.c) + list(APPEND ZLIB_ARCH_SRCS ${CRC32_VX_SRCS}) + set_property(SOURCE ${CRC32_VX_SRCS} PROPERTY COMPILE_FLAGS "${VGFMAFLAG} ${NOLTOFLAG}") + else() + set(WITH_CRC32_VX OFF) + endif() + endif() + elseif(BASEARCH_X86_FOUND) + add_definitions(-DX86_FEATURES) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/x86_features.h) + list(APPEND ZLIB_ARCH_SRCS ${ARCHDIR}/x86_features.c) + if(MSVC) + list(APPEND ZLIB_ARCH_HDRS fallback_builtins.h) + endif() + if(WITH_AVX2) + check_avx2_intrinsics() + if(HAVE_AVX2_INTRIN) + add_definitions(-DX86_AVX2) + set(AVX2_SRCS ${ARCHDIR}/slide_hash_avx2.c) + add_feature_info(AVX2_SLIDEHASH 1 "Support AVX2 optimized slide_hash, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/chunkset_avx2.c) + add_feature_info(AVX2_CHUNKSET 1 "Support AVX2 optimized chunkset, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/compare256_avx2.c) + add_feature_info(AVX2_COMPARE256 1 "Support AVX2 optimized compare256, using \"${AVX2FLAG}\"") + list(APPEND AVX2_SRCS ${ARCHDIR}/adler32_avx2.c) + add_feature_info(AVX2_ADLER32 1 "Support AVX2-accelerated adler32, using \"${AVX2FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX2_SRCS}) + set_property(SOURCE ${AVX2_SRCS} PROPERTY COMPILE_FLAGS "${AVX2FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX2 OFF) + endif() + endif() + if(WITH_AVX512) + check_avx512_intrinsics() + if(HAVE_AVX512_INTRIN) + add_definitions(-DX86_AVX512) + list(APPEND AVX512_SRCS ${ARCHDIR}/adler32_avx512.c) + add_feature_info(AVX512_ADLER32 1 "Support AVX512-accelerated adler32, using \"${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${AVX512_SRCS}) + list(APPEND ZLIB_ARCH_HDRS ${ARCHDIR}/adler32_avx512_p.h) + if(HAVE_MASK_INTRIN) + add_definitions(-DX86_MASK_INTRIN) + endif() + set_property(SOURCE ${AVX512_SRCS} PROPERTY COMPILE_FLAGS "${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512 OFF) + endif() + endif() + if(WITH_AVX512VNNI) + check_avx512vnni_intrinsics() + if(HAVE_AVX512VNNI_INTRIN) + add_definitions(-DX86_AVX512VNNI) + add_feature_info(AVX512VNNI_ADLER32 1 "Support AVX512VNNI adler32, using \"${AVX512VNNIFLAG}\"") + list(APPEND AVX512VNNI_SRCS ${ARCHDIR}/adler32_avx512_vnni.c) + list(APPEND ZLIB_ARCH_SRCS ${AVX512VNNI_SRCS}) + set_property(SOURCE ${AVX512VNNI_SRCS} PROPERTY COMPILE_FLAGS "${AVX512VNNIFLAG} ${NOLTOFLAG}") + else() + set(WITH_AVX512VNNI OFF) + endif() + endif() + if(WITH_SSE42) + check_sse42_intrinsics() + if(HAVE_SSE42CRC_INLINE_ASM OR HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42) + set(SSE42_SRCS ${ARCHDIR}/adler32_sse42.c ${ARCHDIR}/insert_string_sse42.c) + add_feature_info(SSE42_CRC 1 "Support SSE4.2 optimized CRC hash generation, using \"${SSE42FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSE42_SRCS}) + set_property(SOURCE ${SSE42_SRCS} PROPERTY COMPILE_FLAGS "${SSE42FLAG} ${NOLTOFLAG}") + if(HAVE_SSE42CRC_INTRIN) + add_definitions(-DX86_SSE42_CRC_INTRIN) + endif() + else() + set(WITH_SSE42 OFF) + endif() + endif() + if(WITH_SSE2) + check_sse2_intrinsics() + if(HAVE_SSE2_INTRIN) + add_definitions(-DX86_SSE2) + set(SSE2_SRCS ${ARCHDIR}/chunkset_sse2.c ${ARCHDIR}/compare256_sse2.c ${ARCHDIR}/slide_hash_sse2.c) + list(APPEND ZLIB_ARCH_SRCS ${SSE2_SRCS}) + if(NOT ${ARCH} MATCHES "x86_64") + set_property(SOURCE ${SSE2_SRCS} PROPERTY COMPILE_FLAGS "${SSE2FLAG} ${NOLTOFLAG}") + add_feature_info(FORCE_SSE2 FORCE_SSE2 "Assume CPU is SSE2 capable") + if(FORCE_SSE2) + add_definitions(-DX86_NOCHECK_SSE2) + endif() + endif() + else() + set(WITH_SSE2 OFF) + endif() + endif() + if(WITH_SSSE3) + check_ssse3_intrinsics() + if(HAVE_SSSE3_INTRIN) + add_definitions(-DX86_SSSE3) + set(SSSE3_SRCS ${ARCHDIR}/adler32_ssse3.c ${ARCHDIR}/chunkset_ssse3.c) + add_feature_info(SSSE3_ADLER32 1 "Support SSSE3-accelerated adler32, using \"${SSSE3FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${SSSE3_SRCS}) + set_property(SOURCE ${SSSE3_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${NOLTOFLAG}") + else() + set(WITH_SSSE3 OFF) + endif() + endif() + if(WITH_PCLMULQDQ AND WITH_SSSE3 AND WITH_SSE42) + check_pclmulqdq_intrinsics() + if(HAVE_PCLMULQDQ_INTRIN AND HAVE_SSSE3_INTRIN) + add_definitions(-DX86_PCLMULQDQ_CRC) + set(PCLMULQDQ_SRCS ${ARCHDIR}/crc32_pclmulqdq.c) + add_feature_info(PCLMUL_CRC 1 "Support CRC hash generation using PCLMULQDQ, using \"${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${PCLMULQDQ_SRCS}) + set_property(SOURCE ${PCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${NOLTOFLAG}") + + if(WITH_VPCLMULQDQ AND WITH_AVX512) + check_vpclmulqdq_intrinsics() + if(HAVE_VPCLMULQDQ_INTRIN AND HAVE_AVX512_INTRIN) + add_definitions(-DX86_VPCLMULQDQ_CRC) + set(VPCLMULQDQ_SRCS ${ARCHDIR}/crc32_vpclmulqdq.c) + add_feature_info(VPCLMUL_CRC 1 "Support CRC hash generation using VPCLMULQDQ, using \"${VPCLMULFLAG} ${AVX512FLAG}\"") + list(APPEND ZLIB_ARCH_SRCS ${VPCLMULQDQ_SRCS}) + set_property(SOURCE ${VPCLMULQDQ_SRCS} PROPERTY COMPILE_FLAGS "${SSSE3FLAG} ${SSE42FLAG} ${PCLMULFLAG} ${VPCLMULFLAG} ${AVX512FLAG} ${NOLTOFLAG}") + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + else() + set(WITH_PCLMULQDQ OFF) + set(WITH_VPCLMULQDQ OFF) + endif() + check_xsave_intrinsics() + if(HAVE_XSAVE_INTRIN) + add_feature_info(XSAVE 1 "Support XSAVE intrinsics using \"${XSAVEFLAG}\"") + set_property(SOURCE ${ARCHDIR}/x86_features.c PROPERTY COMPILE_FLAGS "${XSAVEFLAG}") + endif() + endif() +endif() + +message(STATUS "Architecture-specific source files: ${ZLIB_ARCH_SRCS}") + +#============================================================================ +# zconf.h +#============================================================================ + +macro(generate_cmakein input output) + file(REMOVE ${output}) + file(STRINGS ${input} _lines) + foreach(_line IN LISTS _lines) + string(REGEX REPLACE "#ifdef HAVE_UNISTD_H.*" "@ZCONF_UNISTD_LINE@" _line "${_line}") + string(REGEX REPLACE "#ifdef NEED_PTRDIFF_T.*" "@ZCONF_PTRDIFF_LINE@" _line "${_line}") + if(NEED_PTRDIFF_T) + string(REGEX REPLACE "typedef PTRDIFF_TYPE" "typedef @PTRDIFF_TYPE@" _line "${_line}") + endif() + file(APPEND ${output} "${_line}\n") + endforeach() +endmacro(generate_cmakein) + +generate_cmakein( ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.in ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein ) + +if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR) + # If we're doing an out of source build and the user has a zconf.h + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h") + message(STATUS "to 'zconf${SUFFIX}.h.included' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.included) + endif() + + # If we're doing an out of source build and the user has a zconf.h.cmakein + # in their source tree... + if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein) + message(STATUS "Renaming") + message(STATUS " ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein") + message(STATUS "to 'zconf${SUFFIX}.h.cmakeincluded' because this file is included with zlib") + message(STATUS "but CMake generates it automatically in the build directory.") + file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakein ${CMAKE_CURRENT_SOURCE_DIR}/zconf${SUFFIX}.h.cmakeincluded) + endif() +endif() + +# Refer to prefix symbolically to ease relocation by end user, +# as Makefile-generated .pc file does. +string(FIND "${CMAKE_INSTALL_INCLUDEDIR}" "${CMAKE_INSTALL_PREFIX}/" INCLUDEDIR_POS) +string(FIND "${CMAKE_INSTALL_LIBDIR}" "${CMAKE_INSTALL_PREFIX}/" LIBDIR_POS) +string(LENGTH "${CMAKE_INSTALL_PREFIX}/" INSTALL_PREFIX_LEN) + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(PC_INC_INSTALL_DIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") +elseif(INCLUDEDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_INCLUDEDIR}" "${INSTALL_PREFIX_LEN}" "-1" INCLUDEDIR_RELATIVE) + set(PC_INC_INSTALL_DIR "\${prefix}/${INCLUDEDIR_RELATIVE}") +else() + set(PC_INC_INSTALL_DIR "${CMAKE_INSTALL_INCLUDEDIR}") +endif() + +if(NOT IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") +elseif(LIBDIR_POS EQUAL 0) + string(SUBSTRING "${CMAKE_INSTALL_LIBDIR}" "${INSTALL_PREFIX_LEN}" "-1" LIBDIR_RELATIVE) + set(PC_LIB_INSTALL_DIR "\${exec_prefix}/${LIBDIR_RELATIVE}") +else() + set(PC_LIB_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}") +endif() + +#============================================================================ +# zlib +#============================================================================ + +set(ZLIB_PUBLIC_HDRS + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h +) +set(ZLIB_PRIVATE_HDRS + adler32_p.h + chunkset_tpl.h + compare256_rle.h + cpu_features.h + crc32_braid_p.h + crc32_braid_comb_p.h + crc32_braid_tbl.h + crc32_fold.h + deflate.h + deflate_p.h + functable.h + inffast_tpl.h + inffixed_tbl.h + inflate.h + inflate_p.h + inftrees.h + insert_string_tpl.h + match_tpl.h + trees.h + trees_emit.h + trees_tbl.h + zbuild.h + zendian.h + zutil.h +) +set(ZLIB_SRCS + adler32.c + adler32_fold.c + chunkset.c + compare256.c + compress.c + cpu_features.c + crc32_braid.c + crc32_braid_comb.c + crc32_fold.c + deflate.c + deflate_fast.c + deflate_huff.c + deflate_medium.c + deflate_quick.c + deflate_rle.c + deflate_slow.c + deflate_stored.c + functable.c + infback.c + inflate.c + inftrees.c + insert_string.c + insert_string_roll.c + slide_hash.c + trees.c + uncompr.c + zutil.c +) + +set(ZLIB_GZFILE_PRIVATE_HDRS + gzguts.h +) +set(ZLIB_GZFILE_SRCS + gzlib.c + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c + gzwrite.c +) + +set(ZLIB_ALL_SRCS ${ZLIB_SRCS} ${ZLIB_ARCH_HDRS} ${ZLIB_ARCH_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS}) +if(WITH_GZFILEOP) + list(APPEND ZLIB_ALL_SRCS ${ZLIB_GZFILE_PRIVATE_HDRS} ${ZLIB_GZFILE_SRCS}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set(ZLIB_DLL_SRCS win32/zlib${SUFFIX}1.rc) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS) + add_library(zlib SHARED ${ZLIB_ALL_SRCS} ${ZLIB_DLL_SRCS}) + add_library(zlibstatic STATIC ${ZLIB_ALL_SRCS}) + + set(ZLIB_INSTALL_LIBRARIES zlib zlibstatic) +else() + add_library(zlib ${ZLIB_ALL_SRCS}) + + if(BUILD_SHARED_LIBS) + target_sources(zlib PRIVATE ${ZLIB_DLL_SRCS}) + else() + add_library(zlibstatic ALIAS zlib) + endif() + + set(ZLIB_INSTALL_LIBRARIES zlib) +endif() + +foreach(ZLIB_INSTALL_LIBRARY ${ZLIB_INSTALL_LIBRARIES}) + if(NOT ZLIB_COMPAT) + target_compile_definitions(${ZLIB_INSTALL_LIBRARY} PUBLIC ZLIBNG_NATIVE_API) + endif() + target_include_directories(${ZLIB_INSTALL_LIBRARY} PUBLIC + "$" + "$") +endforeach() + +if(WIN32) + # Shared library + if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlib${SUFFIX}) + endif() + # Static library + if(NOT DEFINED BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlibstatic PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + elseif(NOT BUILD_SHARED_LIBS) + if(MSVC) + set_target_properties(zlib PROPERTIES OUTPUT_NAME zlibstatic${SUFFIX}) + else() + set_target_properties(zlib PROPERTIES OUTPUT_NAME z${SUFFIX}) + endif() + endif() +else() + # On unix-like platforms the library is almost always called libz + set_target_properties(${ZLIB_INSTALL_LIBRARIES} PROPERTIES OUTPUT_NAME z${SUFFIX}) +endif() + +if(NOT DEFINED BUILD_SHARED_LIBS OR BUILD_SHARED_LIBS) + set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL) + + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SOVERSION 1) + else() + set_target_properties(zlib PROPERTIES SOVERSION 2) + endif() + + if(NOT CYGWIN) + # This property causes shared libraries on Linux to have the full version + # encoded into their final filename. We disable this on Cygwin because + # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll + # seems to be the default. + # + # This has no effect with MSVC, on that platform the version info for + # the DLL comes from the resource file win32/zlib1.rc + set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION}) + endif() + + if(UNIX) + if(HAVE_NO_INTERPOSITION) + set_target_properties(zlib PROPERTIES COMPILE_FLAGS "-fno-semantic-interposition") + endif() + if(NOT APPLE) + set_target_properties(zlib PROPERTIES LINK_FLAGS + "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.map\"") + else() + # Match configure/make's behavior (i.e. don't use @rpath on mac). + set_target_properties(zlib PROPERTIES INSTALL_NAME_DIR "${CMAKE_INSTALL_FULL_LIBDIR}") + endif() + endif() + if(MSYS) + # Suppress version number from shared library name + set(CMAKE_SHARED_LIBRARY_NAME_WITH_VERSION 0) + elseif(WIN32) + # Creates zlib1.dll when building shared library version + if(ZLIB_COMPAT) + set_target_properties(zlib PROPERTIES SUFFIX "1.dll") + else() + set_target_properties(zlib PROPERTIES SUFFIX "2.dll") + endif() + endif() +endif() + +if(HAVE_UNISTD_H) + SET(ZCONF_UNISTD_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_UNISTD_LINE "#if 0 /* was set to #if 0 by configure/cmake/etc */") +endif() +if(NEED_PTRDIFF_T) + SET(ZCONF_PTRDIFF_LINE "#if 1 /* was set to #if 1 by configure/cmake/etc */") +else() + SET(ZCONF_PTRDIFF_LINE "#ifdef NEED_PTRDIFF_T /* may be set to #if 1 by configure/cmake/etc */") +endif() + +set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.pc) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein + ${ZLIB_PC} @ONLY) +configure_file(${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h.cmakein + ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h @ONLY) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gzread.c.in + ${CMAKE_CURRENT_BINARY_DIR}/gzread.c @ONLY) + + +if (NOT ZLIB_SYMBOL_PREFIX STREQUAL "") + add_feature_info(ZLIB_SYMBOL_PREFIX ON "Publicly exported symbols have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling${SUFFIX}.h.in + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h @ONLY) +else() + add_feature_info(ZLIB_SYMBOL_PREFIX OFF "Publicly exported symbols DO NOT have a custom prefix") + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/zlib_name_mangling.h.empty + ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h COPYONLY) +endif() +# add_definitions(-DZLIB_SYMBOL_PREFIX=${ZLIB_SYMBOL_PREFIX}) # not needed + + +if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) + install(TARGETS ${ZLIB_INSTALL_LIBRARIES} + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}") +endif() +if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zlib_name_mangling${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zlib_name_mangling${SUFFIX}.h) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/zconf${SUFFIX}.h + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" RENAME zconf${SUFFIX}.h) +endif() +if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL) + install(FILES ${ZLIB_PC} DESTINATION "${PKGCONFIG_INSTALL_DIR}") +endif() + +#============================================================================ +# Example binaries +#============================================================================ + +option(ZLIB_ENABLE_TESTS "Build test binaries" ON) +if(ZLIB_ENABLE_TESTS) + enable_testing() + + if(BUILD_SHARED_LIBS) + if(ZLIBNG_ENABLE_TESTS) + message(STATUS "Disabling zlib-ng tests because shared libraries are enabled") + set(ZLIBNG_ENABLE_TESTS OFF) + endif() + + if(WITH_BENCHMARKS OR WITH_BENCHMARK_APPS) + message(STATUS "Disabling benchmarks because shared libraries are enabled") + set(WITH_BENCHMARKS OFF) + set(WITH_BENCHMARK_APPS OFF) + endif() + endif() + + add_subdirectory(test) +endif() + +add_feature_info(WITH_GZFILEOP WITH_GZFILEOP "Compile with support for gzFile related functions") +add_feature_info(ZLIB_COMPAT ZLIB_COMPAT "Compile with zlib compatible API") +add_feature_info(ZLIB_ENABLE_TESTS ZLIB_ENABLE_TESTS "Build test binaries") +add_feature_info(ZLIBNG_ENABLE_TESTS ZLIBNG_ENABLE_TESTS "Test zlib-ng specific API") +add_feature_info(WITH_SANITIZER WITH_SANITIZER "Enable sanitizer support") +add_feature_info(WITH_GTEST WITH_GTEST "Build gtest_zlib") +add_feature_info(WITH_FUZZERS WITH_FUZZERS "Build test/fuzz") +add_feature_info(WITH_BENCHMARKS WITH_BENCHMARKS "Build test/benchmarks") +add_feature_info(WITH_BENCHMARK_APPS WITH_BENCHMARK_APPS "Build application benchmarks") +add_feature_info(WITH_OPTIM WITH_OPTIM "Build with optimisation") +add_feature_info(WITH_NEW_STRATEGIES WITH_NEW_STRATEGIES "Use new strategies") +add_feature_info(WITH_NATIVE_INSTRUCTIONS WITH_NATIVE_INSTRUCTIONS + "Instruct the compiler to use the full instruction set on this host (gcc/clang -march=native)") +add_feature_info(WITH_MAINTAINER_WARNINGS WITH_MAINTAINER_WARNINGS "Build with project maintainer warnings") +add_feature_info(WITH_CODE_COVERAGE WITH_CODE_COVERAGE "Enable code coverage reporting") +add_feature_info(WITH_INFLATE_STRICT WITH_INFLATE_STRICT "Build with strict inflate distance checking") +add_feature_info(WITH_INFLATE_ALLOW_INVALID_DIST WITH_INFLATE_ALLOW_INVALID_DIST "Build with zero fill for inflate invalid distances") + +if(BASEARCH_ARM_FOUND) + add_feature_info(WITH_ACLE WITH_ACLE "Build with ACLE") + add_feature_info(WITH_NEON WITH_NEON "Build with NEON intrinsics") +elseif(BASEARCH_PPC_FOUND) + add_feature_info(WITH_ALTIVEC WITH_ALTIVEC "Build with AltiVec optimisations") + add_feature_info(WITH_POWER8 WITH_POWER8 "Build with optimisations for POWER8") + add_feature_info(WITH_POWER9 WITH_POWER9 "Build with optimisations for POWER9") +elseif(BASEARCH_RISCV_FOUND) + add_feature_info(WITH_RVV WITH_RVV "Build with RVV intrinsics") +elseif(BASEARCH_S360_FOUND) + add_feature_info(WITH_DFLTCC_DEFLATE WITH_DFLTCC_DEFLATE "Build with DFLTCC intrinsics for compression on IBM Z") + add_feature_info(WITH_DFLTCC_INFLATE WITH_DFLTCC_INFLATE "Build with DFLTCC intrinsics for decompression on IBM Z") + add_feature_info(WITH_CRC32_VX WITH_CRC32_VX "Build with vectorized CRC32 on IBM Z") +elseif(BASEARCH_X86_FOUND) + add_feature_info(WITH_AVX2 WITH_AVX2 "Build with AVX2") + add_feature_info(WITH_AVX512 WITH_AVX512 "Build with AVX512") + add_feature_info(WITH_AVX512VNNI WITH_AVX512VNNI "Build with AVX512 VNNI") + add_feature_info(WITH_SSE2 WITH_SSE2 "Build with SSE2") + add_feature_info(WITH_SSSE3 WITH_SSSE3 "Build with SSSE3") + add_feature_info(WITH_SSE42 WITH_SSE42 "Build with SSE42") + add_feature_info(WITH_PCLMULQDQ WITH_PCLMULQDQ "Build with PCLMULQDQ") + add_feature_info(WITH_VPCLMULQDQ WITH_VPCLMULQDQ "Build with VPCLMULQDQ") +endif() + +add_feature_info(INSTALL_UTILS INSTALL_UTILS "Copy minigzip and minideflate during install") + +FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/FAQ.zlib b/internal-complibs/zlib-ng-2.1.1-beta2/FAQ.zlib new file mode 100644 index 000000000..163160c10 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/FAQ.zlib @@ -0,0 +1,374 @@ +## +# THIS IS AN UNMAINTAINED COPY OF THE ORIGINAL FILE DISTRIBUTED WITH ZLIB 1.2.11 +## + + + + + Frequently Asked Questions about zlib + + +If your question is not there, please check the zlib home page +https://zlib.net/ which may have more recent information. +The latest zlib FAQ is at https://zlib.net/zlib_faq.html + + + 1. Is zlib Y2K-compliant? + + Yes. zlib doesn't handle dates. + + 2. Where can I get a Windows DLL version? + + The zlib sources can be compiled without change to produce a DLL. See the + file win32/DLL_FAQ.txt in the zlib distribution. Pointers to the + precompiled DLL are found in the zlib web site at https://zlib.net/ . + + 3. Where can I get a Visual Basic interface to zlib? + + See + * https://marknelson.us/1997/01/01/zlib-engine/ + * win32/DLL_FAQ.txt in the zlib distribution + + 4. compress() returns Z_BUF_ERROR. + + Make sure that before the call of compress(), the length of the compressed + buffer is equal to the available size of the compressed buffer and not + zero. For Visual Basic, check that this parameter is passed by reference + ("as any"), not by value ("as long"). + + 5. deflate() or inflate() returns Z_BUF_ERROR. + + Before making the call, make sure that avail_in and avail_out are not zero. + When setting the parameter flush equal to Z_FINISH, also make sure that + avail_out is big enough to allow processing all pending input. Note that a + Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be + made with more input or output space. A Z_BUF_ERROR may in fact be + unavoidable depending on how the functions are used, since it is not + possible to tell whether or not there is more output pending when + strm.avail_out returns with zero. See https://zlib.net/zlib_how.html for a + heavily annotated example. + + 6. Where's the zlib documentation (man pages, etc.)? + + It's in zlib.h . Examples of zlib usage are in the files test/example.c + and test/minigzip.c, with more in examples/ . + + 7. Why don't you use GNU autoconf or libtool or ...? + + Because we would like to keep zlib as a very small and simple package. + zlib is rather portable and doesn't need much configuration. + + 8. I found a bug in zlib. + + Most of the time, such problems are due to an incorrect usage of zlib. + Please try to reproduce the problem with a small program and send the + corresponding source to us at zlib@gzip.org . Do not send multi-megabyte + data files without prior agreement. + + 9. Why do I get "undefined reference to gzputc"? + + If "make test" produces something like + + example.o(.text+0x154): undefined reference to `gzputc' + + check that you don't have old files libz.* in /usr/lib, /usr/local/lib or + /usr/X11R6/lib. Remove any old versions, then do "make install". + +10. I need a Delphi interface to zlib. + + See the contrib/delphi directory in the zlib distribution. + +11. Can zlib handle .zip archives? + + Not by itself, no. See the directory contrib/minizip in the zlib + distribution. + +12. Can zlib handle .Z files? + + No, sorry. You have to spawn an uncompress or gunzip subprocess, or adapt + the code of uncompress on your own. + +13. How can I make a Unix shared library? + + By default a shared (and a static) library is built for Unix. So: + + make distclean + ./configure + make + +14. How do I install a shared zlib library on Unix? + + After the above, then: + + make install + + However, many flavors of Unix come with a shared zlib already installed. + Before going to the trouble of compiling a shared version of zlib and + trying to install it, you may want to check if it's already there! If you + can #include , it's there. The -lz option will probably link to + it. You can check the version at the top of zlib.h or with the + ZLIB_VERSION symbol defined in zlib.h . + +15. I have a question about OttoPDF. + + We are not the authors of OttoPDF. The real author is on the OttoPDF web + site: Joel Hainley, jhainley@myndkryme.com. + +16. Can zlib decode Flate data in an Adobe PDF file? + + Yes. See https://www.pdflib.com/ . To modify PDF forms, see + https://sourceforge.net/projects/acroformtool/ . + +17. Why am I getting this "register_frame_info not found" error on Solaris? + + After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib + generates an error such as: + + ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so: + symbol __register_frame_info: referenced symbol not found + + The symbol __register_frame_info is not part of zlib, it is generated by + the C compiler (cc or gcc). You must recompile applications using zlib + which have this problem. This problem is specific to Solaris. See + http://www.sunfreeware.com/ for Solaris versions of zlib and applications + using zlib. + +18. Why does gzip give an error on a file I make with compress/deflate? + + The compress and deflate functions produce data in the zlib format, which + is different and incompatible with the gzip format. The gz* functions in + zlib on the other hand use the gzip format. Both the zlib and gzip formats + use the same compressed data format internally, but have different headers + and trailers around the compressed data. + +19. Ok, so why are there two different formats? + + The gzip format was designed to retain the directory information about a + single file, such as the name and last modification date. The zlib format + on the other hand was designed for in-memory and communication channel + applications, and has a much more compact header and trailer and uses a + faster integrity check than gzip. + +20. Well that's nice, but how do I make a gzip file in memory? + + You can request that deflate write the gzip format instead of the zlib + format using deflateInit2(). You can also request that inflate decode the + gzip format using inflateInit2(). Read zlib.h for more details. + +21. Is zlib thread-safe? + + Yes. However any library routines that zlib uses and any application- + provided memory allocation routines must also be thread-safe. zlib's gz* + functions use stdio library routines, and most of zlib's functions use the + library memory allocation routines by default. zlib's *Init* functions + allow for the application to provide custom memory allocation routines. + + Of course, you should only operate on any given zlib or gzip stream from a + single thread at a time. + +22. Can I use zlib in my commercial application? + + Yes. Please read the license in zlib.h. + +23. Is zlib under the GNU license? + + No. Please read the license in zlib.h. + +24. The license says that altered source versions must be "plainly marked". So + what exactly do I need to do to meet that requirement? + + You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h. In + particular, the final version number needs to be changed to "f", and an + identification string should be appended to ZLIB_VERSION. Version numbers + x.x.x.f are reserved for modifications to zlib by others than the zlib + maintainers. For example, if the version of the base zlib you are altering + is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and + ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3". You can also + update the version strings in deflate.c and inftrees.c. + + For altered source distributions, you should also note the origin and + nature of the changes in zlib.h, as well as in ChangeLog and README, along + with the dates of the alterations. The origin should include at least your + name (or your company's name), and an email address to contact for help or + issues with the library. + + Note that distributing a compiled zlib library along with zlib.h and + zconf.h is also a source distribution, and so you should change + ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes + in zlib.h as you would for a full source distribution. + +25. Will zlib work on a big-endian or little-endian architecture, and can I + exchange compressed data between them? + + Yes and yes. + +26. Will zlib work on a 64-bit machine? + + Yes. It has been tested on 64-bit machines, and has no dependence on any + data types being limited to 32-bits in length. If you have any + difficulties, please provide a complete problem report to zlib@gzip.org + +27. Will zlib decompress data from the PKWare Data Compression Library? + + No. The PKWare DCL uses a completely different compressed data format than + does PKZIP and zlib. However, you can look in zlib's contrib/blast + directory for a possible solution to your problem. + +28. Can I access data randomly in a compressed stream? + + No, not without some preparation. If when compressing you periodically use + Z_FULL_FLUSH, carefully write all the pending data at those points, and + keep an index of those locations, then you can start decompression at those + points. You have to be careful to not use Z_FULL_FLUSH too often, since it + can significantly degrade compression. Alternatively, you can scan a + deflate stream once to generate an index, and then use that index for + random access. See examples/zran.c . + +29. Does zlib work on MVS, OS/390, CICS, etc.? + + It has in the past, but we have not heard of any recent evidence. There + were working ports of zlib 1.1.4 to MVS, but those links no longer work. + If you know of recent, successful applications of zlib on these operating + systems, please let us know. Thanks. + +30. Is there some simpler, easier to read version of inflate I can look at to + understand the deflate format? + + First off, you should read RFC 1951. Second, yes. Look in zlib's + contrib/puff directory. + +31. Does zlib infringe on any patents? + + As far as we know, no. In fact, that was originally the whole point behind + zlib. Look here for some more information: + + https://www.gzip.org/#faq11 + +32. Can zlib work with greater than 4 GB of data? + + Yes. inflate() and deflate() will process any amount of data correctly. + Each call of inflate() or deflate() is limited to input and output chunks + of the maximum value that can be stored in the compiler's "unsigned int" + type, but there is no limit to the number of chunks. Note however that the + strm.total_in and strm_total_out counters may be limited to 4 GB. These + counters are provided as a convenience and are not used internally by + inflate() or deflate(). The application can easily set up its own counters + updated after each call of inflate() or deflate() to count beyond 4 GB. + compress() and uncompress() may be limited to 4 GB, since they operate in a + single call. gzseek() and gztell() may be limited to 4 GB depending on how + zlib is compiled. See the zlibCompileFlags() function in zlib.h. + + The word "may" appears several times above since there is a 4 GB limit only + if the compiler's "long" type is 32 bits. If the compiler's "long" type is + 64 bits, then the limit is 16 exabytes. + +33. Does zlib have any security vulnerabilities? + + The only one that we are aware of is potentially in gzprintf(). If zlib is + compiled to use sprintf() or vsprintf(), then there is no protection + against a buffer overflow of an 8K string space (or other value as set by + gzbuffer()), other than the caller of gzprintf() assuring that the output + will not exceed 8K. On the other hand, if zlib is compiled to use + snprintf() or vsnprintf(), which should normally be the case, then there is + no vulnerability. The ./configure script will display warnings if an + insecure variation of sprintf() will be used by gzprintf(). Also the + zlibCompileFlags() function will return information on what variant of + sprintf() is used by gzprintf(). + + If you don't have snprintf() or vsnprintf() and would like one, you can + find a portable implementation here: + + https://www.ijs.si/software/snprintf/ + + Note that you should be using the most recent version of zlib. Versions + 1.1.3 and before were subject to a double-free vulnerability, and versions + 1.2.1 and 1.2.2 were subject to an access exception when decompressing + invalid compressed data. + +34. Is there a Java version of zlib? + + Probably what you want is to use zlib in Java. zlib is already included + as part of the Java SDK in the java.util.zip package. If you really want + a version of zlib written in the Java language, look on the zlib home + page for links: https://zlib.net/ . + +35. I get this or that compiler or source-code scanner warning when I crank it + up to maximally-pedantic. Can't you guys write proper code? + + Many years ago, we gave up attempting to avoid warnings on every compiler + in the universe. It just got to be a waste of time, and some compilers + were downright silly as well as contradicted each other. So now, we simply + make sure that the code always works. + +36. Valgrind (or some similar memory access checker) says that deflate is + performing a conditional jump that depends on an uninitialized value. + Isn't that a bug? + + No. That is intentional for performance reasons, and the output of deflate + is not affected. This only started showing up recently since zlib 1.2.x + uses malloc() by default for allocations, whereas earlier versions used + calloc(), which zeros out the allocated memory. Even though the code was + correct, versions 1.2.4 and later was changed to not stimulate these + checkers. + +37. Will zlib read the (insert any ancient or arcane format here) compressed + data format? + + Probably not. Look in the comp.compression FAQ for pointers to various + formats and associated software. + +38. How can I encrypt/decrypt zip files with zlib? + + zlib doesn't support encryption. The original PKZIP encryption is very + weak and can be broken with freely available programs. To get strong + encryption, use GnuPG, https://www.gnupg.org/ , which already includes zlib + compression. For PKZIP compatible "encryption", look at + http://infozip.sourceforge.net/ + +39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings? + + "gzip" is the gzip format, and "deflate" is the zlib format. They should + probably have called the second one "zlib" instead to avoid confusion with + the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 + correctly points to the zlib specification in RFC 1950 for the "deflate" + transfer encoding, there have been reports of servers and browsers that + incorrectly produce or expect raw deflate data per the deflate + specification in RFC 1951, most notably Microsoft. So even though the + "deflate" transfer encoding using the zlib format would be the more + efficient approach (and in fact exactly what the zlib format was designed + for), using the "gzip" transfer encoding is probably more reliable due to + an unfortunate choice of name on the part of the HTTP 1.1 authors. + + Bottom line: use the gzip format for HTTP 1.1 encoding. + +40. Does zlib support the new "Deflate64" format introduced by PKWare? + + No. PKWare has apparently decided to keep that format proprietary, since + they have not documented it as they have previous compression formats. In + any case, the compression improvements are so modest compared to other more + modern approaches, that it's not worth the effort to implement. + +41. I'm having a problem with the zip functions in zlib, can you help? + + There are no zip functions in zlib. You are probably using minizip by + Giles Vollant, which is found in the contrib directory of zlib. It is not + part of zlib. In fact none of the stuff in contrib is part of zlib. The + files in there are not supported by the zlib authors. You need to contact + the authors of the respective contribution for help. + +42. The match.asm code in contrib is under the GNU General Public License. + Since it's part of zlib, doesn't that mean that all of zlib falls under the + GNU GPL? + + No. The files in contrib are not part of zlib. They were contributed by + other authors and are provided as a convenience to the user within the zlib + distribution. Each item in contrib has its own license. + +43. Is zlib subject to export controls? What is its ECCN? + + zlib is not subject to export controls, and so is classified as EAR99. + +44. Can you please sign these lengthy legal documents and fax them back to us + so that we can use your software in our product? + + No. Go away. Shoo. diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/INDEX.md b/internal-complibs/zlib-ng-2.1.1-beta2/INDEX.md new file mode 100644 index 000000000..22fd470e6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/INDEX.md @@ -0,0 +1,36 @@ +Contents +-------- + +| Name | Description | +|:-----------------|:---------------------------------------------------------------| +| arch/ | Architecture-specific code | +| doc/ | Documentation for formats and algorithms | +| test/example.c | Zlib usages examples for build testing | +| test/minigzip.c | Minimal gzip-like functionality for build testing | +| test/infcover.c | Inflate code coverage for build testing | +| win32/ | Shared library version resources for Windows | +| CMakeLists.txt | Cmake build script | +| configure | Bash configure/build script | +| adler32.c | Compute the Adler-32 checksum of a data stream | +| chunkset.* | Inline functions to copy small data chunks | +| compress.c | Compress a memory buffer | +| deflate.* | Compress data using the deflate algorithm | +| deflate_fast.c | Compress data using the deflate algorithm with fast strategy | +| deflate_medium.c | Compress data using the deflate algorithm with medium strategy | +| deflate_slow.c | Compress data using the deflate algorithm with slow strategy | +| functable.* | Struct containing function pointers to optimized functions | +| gzguts.h | Internal definitions for gzip operations | +| gzlib.c | Functions common to reading and writing gzip files | +| gzread.c | Read gzip files | +| gzwrite.c | Write gzip files | +| infback.* | Inflate using a callback interface | +| inflate.* | Decompress data | +| inffast.* | Decompress data with speed optimizations | +| inffixed_tbl.h | Table for decoding fixed codes | +| inftrees.h | Generate Huffman trees for efficient decoding | +| trees.* | Output deflated data using Huffman coding | +| uncompr.c | Decompress a memory buffer | +| zconf.h.cmakein | zconf.h template for cmake | +| zendian.h | BYTE_ORDER for endian tests | +| zlib.map | Linux symbol information | +| zlib.pc.in | Pkg-config template | diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/LICENSE.md b/internal-complibs/zlib-ng-2.1.1-beta2/LICENSE.md new file mode 100644 index 000000000..adb48d472 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/LICENSE.md @@ -0,0 +1,19 @@ +(C) 1995-2013 Jean-loup Gailly and Mark Adler + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +3. This notice may not be removed or altered from any source distribution. diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/Makefile.in new file mode 100644 index 000000000..902613e23 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/Makefile.in @@ -0,0 +1,395 @@ +# Makefile for zlib +# Copyright (C) 1995-2016 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +# To compile and test, type: +# ./configure; make test +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static + +# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type: +# make install +# To install in $HOME instead of /usr/local, use: +# make install prefix=$HOME + +CC=cc + +CFLAGS=-O +#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 +#CFLAGS=-g -DZLIB_DEBUG +#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \ +# -Wstrict-prototypes -Wmissing-prototypes + +SFLAGS=-O +LDFLAGS=-L. +LIBNAME1=libz-ng +LIBNAME2=zlib-ng +SUFFIX=-ng +TEST_LIBS=$(LIBNAME1).a +LDSHARED=$(CC) +LDSHAREDFLAGS=-shared + +VER=2.1.1.beta2 +VER1=2 + +STATICLIB=$(LIBNAME1).a +SHAREDLIB=$(LIBNAME1).so +SHAREDLIBV=$(LIBNAME1).so.$(VER) +SHAREDLIBM=$(LIBNAME1).so.$(VER1) +IMPORTLIB= +SHAREDTARGET=$(LIBNAME1).so.$(VER) +PKGFILE=$(LIBNAME2).pc + +LIBS=$(STATICLIB) $(SHAREDTARGET) + +AR=ar +ARFLAGS=rc +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +RANLIB=ranlib +LDCONFIG=ldconfig +LDSHAREDLIBC= +EXE= + +SRCDIR=. +INCLUDES=-I$(SRCDIR) + +BUILDDIR=. + +ARCHDIR=arch/generic +ARCH_STATIC_OBJS= +ARCH_SHARED_OBJS= + +prefix = /usr/local +exec_prefix = ${prefix} +bindir = ${exec_prefix}/bin +libdir = ${exec_prefix}/lib +sharedlibdir = ${libdir} +includedir = ${prefix}/include +mandir = ${prefix}/share/man +man3dir = ${mandir}/man3 +pkgconfigdir = ${libdir}/pkgconfig + +OBJZ = \ + adler32.o \ + adler32_fold.o \ + chunkset.o \ + compare256.o \ + compress.o \ + cpu_features.o \ + crc32_braid.o \ + crc32_braid_comb.o \ + crc32_fold.o \ + deflate.o \ + deflate_fast.o \ + deflate_huff.o \ + deflate_medium.o \ + deflate_quick.o \ + deflate_rle.o \ + deflate_slow.o \ + deflate_stored.o \ + functable.o \ + infback.o \ + inflate.o \ + inftrees.o \ + insert_string.o \ + insert_string_roll.o \ + slide_hash.o \ + trees.o \ + uncompr.o \ + zutil.o \ + $(ARCH_STATIC_OBJS) + +OBJG = \ + gzlib.o \ + gzread.o \ + gzwrite.o + +TESTOBJG = +OBJC = $(OBJZ) $(OBJG) + +PIC_OBJZ = \ + adler32.lo \ + adler32_fold.lo \ + chunkset.lo \ + compare256.lo \ + compress.lo \ + cpu_features.lo \ + crc32_braid.lo \ + crc32_braid_comb.lo \ + crc32_fold.lo \ + deflate.lo \ + deflate_fast.lo \ + deflate_huff.lo \ + deflate_medium.lo \ + deflate_quick.lo \ + deflate_rle.lo \ + deflate_slow.lo \ + deflate_stored.lo \ + functable.lo \ + infback.lo \ + inflate.lo \ + inftrees.lo \ + insert_string.lo \ + insert_string_roll.lo \ + slide_hash.lo \ + trees.lo \ + uncompr.lo \ + zutil.lo \ + $(ARCH_SHARED_OBJS) + +PIC_OBJG = \ + gzlib.lo \ + gzread.lo \ + gzwrite.lo + +PIC_TESTOBJG = +PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG) + +OBJS = $(OBJC) + +PIC_OBJS = $(PIC_OBJC) + +all: static shared + +static: example$(EXE) minigzip$(EXE) makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) + +shared: examplesh$(EXE) minigzipsh$(EXE) + +check: test + +.SECONDARY: + +$(ARCHDIR)/%.o: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +$(ARCHDIR)/%.lo: $(SRCDIR)/$(ARCHDIR)/%.c + $(MAKE) -C $(ARCHDIR) $(notdir $@) + +%.o: $(ARCHDIR)/%.o + -cp $< $@ + +%.lo: $(ARCHDIR)/%.lo + -cp $< $@ + +test: all + $(MAKE) -C test + +infcover.o: $(SRCDIR)/test/infcover.c zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/test/infcover.c + +infcover$(EXE): infcover.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ infcover.o $(STATICLIB) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +cover: infcover$(EXE) + rm -f *.gcda + ./infcover + gcov inf*.c + +$(STATICLIB): $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + -@ ($(RANLIB) $@ || true) >/dev/null 2>&1 + +example.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/example.c + +minigzip.o: + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $(SRCDIR)/test/minigzip.c + +makefixed.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makefixed.c + +maketrees.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/maketrees.c + +makecrct.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/tools/makecrct.c + +zlibrc.o: $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + $(RC) $(RCFLAGS) -o $@ $(SRCDIR)/win32/zlib$(SUFFIX)1.rc + +.SUFFIXES: .lo + +%.o: $(SRCDIR)/%.c + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $< + +%.lo: $(SRCDIR)/%.c + $(CC) $(SFLAGS) -DPIC $(INCLUDES) -c -o $@ $< + +gzlib.o: $(SRCDIR)/gzlib.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzlib.lo: $(SRCDIR)/gzlib.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.o: gzread.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzread.lo: gzread.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.o: $(SRCDIR)/gzwrite.c + $(CC) $(CFLAGS) -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +gzwrite.lo: $(SRCDIR)/gzwrite.c + $(CC) $(SFLAGS) -DPIC -DWITH_GZFILEOP $(INCLUDES) -c -o $@ $< + +$(SHAREDTARGET): $(PIC_OBJS) $(DEFFILE) $(RCOBJS) +ifneq ($(SHAREDTARGET),) + $(LDSHARED) $(CFLAGS) $(LDSHAREDFLAGS) $(LDFLAGS) -o $@ $(DEFFILE) $(PIC_OBJS) $(RCOBJS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(SHAREDLIB) $(SHAREDLIBM) + ln -s $@ $(SHAREDLIB) + ln -s $@ $(SHAREDLIBM) +endif +endif + +example$(EXE): example.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzip$(EXE): minigzip.o $(TESTOBJG) $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(TESTOBJG) $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +minigzipsh$(EXE): minigzip.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ minigzip.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + + +examplesh$(EXE): example.o $(PIC_TESTOBJG) $(SHAREDTARGET) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ example.o $(PIC_TESTOBJG) $(SHAREDLIB) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makefixed$(EXE): makefixed.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makefixed.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +maketrees$(EXE): maketrees.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ maketrees.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +makecrct$(EXE): makecrct.o $(STATICLIB) + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ makecrct.o $(TEST_LIBS) $(LDSHAREDLIBC) +ifneq ($(STRIP),) + $(STRIP) $@ +endif + +install-shared: $(SHAREDTARGET) +ifneq ($(SHAREDTARGET),) + -@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) + cp $(SHAREDTARGET) $(DESTDIR)$(sharedlibdir) + chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDTARGET) +ifneq ($(SHAREDLIB),$(SHAREDTARGET)) + rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) + ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM) + ($(LDCONFIG) || true) >/dev/null 2>&1 +# ldconfig is for Linux +endif +ifneq ($(IMPORTLIB),) + cp $(IMPORTLIB) $(DESTDIR)$(sharedlibdir) + chmod 644 $(DESTDIR)$(sharedlibdir)/$(IMPORTLIB) +endif +endif + +install-static: $(STATICLIB) + -@if [ ! -d $(DESTDIR)$(libdir) ]; then mkdir -p $(DESTDIR)$(libdir); fi + rm -f $(DESTDIR)$(libdir)/$(STATICLIB) + cp $(STATICLIB) $(DESTDIR)$(libdir) + chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB) + -@($(RANLIB) $(DESTDIR)$(libdir)/$(STATICLIB) || true) >/dev/null 2>&1 +# The ranlib in install-static is needed on NeXTSTEP which checks file times + +install-libs: install-shared install-static + -@if [ ! -d $(DESTDIR)$(man3dir) ]; then mkdir -p $(DESTDIR)$(man3dir); fi + -@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi + rm -f $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + cp $(PKGFILE) $(DESTDIR)$(pkgconfigdir) + chmod 644 $(DESTDIR)$(pkgconfigdir)/$(PKGFILE) + +install: install-libs + -@if [ ! -d $(DESTDIR)$(includedir) ]; then mkdir -p $(DESTDIR)$(includedir); fi + rm -f $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + cp zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zlib$(SUFFIX).h + cp zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h + cp zlib_name_mangling$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + chmod 644 $(DESTDIR)$(includedir)/zlib$(SUFFIX).h $(DESTDIR)$(includedir)/zconf$(SUFFIX).h $(DESTDIR)$(includedir)/zlib_name_mangling$(SUFFIX).h + +uninstall-static: + cd $(DESTDIR)$(libdir) && rm -f $(STATICLIB) + +uninstall-shared: +ifneq ($(SHAREDLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM) +endif +ifneq ($(IMPORTLIB),) + cd $(DESTDIR)$(sharedlibdir) && rm -f $(IMPORTLIB) +endif + +uninstall: uninstall-static uninstall-shared + cd $(DESTDIR)$(includedir) && rm -f zlib$(SUFFIX).h zconf$(SUFFIX).h zlib_name_mangling$(SUFFIX).h + cd $(DESTDIR)$(pkgconfigdir) && rm -f $(PKGFILE) + +mostlyclean: clean +clean: + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) clean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test clean; fi + rm -f *.o *.lo *~ \ + example$(EXE) minigzip$(EXE) minigzipsh$(EXE) \ + infcover makefixed$(EXE) maketrees$(EXE) makecrct$(EXE) \ + $(STATICLIB) $(IMPORTLIB) $(SHAREDLIB) $(SHAREDLIBV) $(SHAREDLIBM) \ + foo.gz so_locations \ + _match.s maketree + rm -rf objs + rm -f *.gcda *.gcno *.gcov + rm -f a.out a.exe + rm -f *._h + rm -rf btmp1 btmp2 pkgtmp1 pkgtmp2 + +maintainer-clean: distclean +distclean: clean + @if [ -f $(ARCHDIR)/Makefile ]; then $(MAKE) -C $(ARCHDIR) distclean; fi + @if [ -f test/Makefile ]; then $(MAKE) -C test distclean; fi + rm -f $(PKGFILE) configure.log zconf.h zconf.h.cmakein zlib$(SUFFIX).h zlib_name_mangling$(SUFFIX)}.h *.pc + -@rm -f .DS_Store +# Reset Makefile if building inside source tree + @if [ -f Makefile.in ]; then \ + printf 'all:\n\t-@echo "Please use ./configure first. Thank you."\n' > Makefile ; \ + printf '\ndistclean:\n\t$(MAKE) -f Makefile.in distclean\n' >> Makefile ; \ + touch -r $(SRCDIR)/Makefile.in Makefile ; fi +# Reset zconf.h and zconf.h.cmakein if building inside source tree + @if [ -f zconf.h.in ]; then \ + cp -p $(SRCDIR)/zconf.h.in zconf.h ; \ + grep -v '^#cmakedefine' $(SRCDIR)/zconf.h.in > zconf.h.cmakein &&\ + touch -r $(SRCDIR)/zconf.h.in zconf.h.cmakein ; fi +# Cleanup these files if building outside source tree + @if [ ! -f README.md ]; then rm -f Makefile; fi +# Remove arch and test directory if building outside source tree + @if [ ! -f $(ARCHDIR)/Makefile.in ]; then rm -rf arch; fi + @if [ ! -f test/Makefile.in ]; then rm -rf test; fi + +tags: + etags $(SRCDIR)/*.[ch] diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/PORTING.md b/internal-complibs/zlib-ng-2.1.1-beta2/PORTING.md new file mode 100644 index 000000000..c48522e3a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/PORTING.md @@ -0,0 +1,79 @@ +Porting applications to use zlib-ng +=================================== + +Zlib-ng can be used/compiled in two different modes, that require some +consideration by the application developer. + +zlib-compat mode +---------------- +Zlib-ng can be compiled in zlib-compat mode, suitable for zlib-replacement +in a single application or system-wide. + +Please note that zlib-ng in zlib-compat mode tries to maintain both API and +ABI compatibility with the original zlib. Any issues regarding compatibility +can be reported as bugs. + +In certain instances you may not be able to simply replace the zlib library/dll +files and expect the application to work. The application may need to be +recompiled against the zlib-ng headers and libs to ensure full compatibility. + +It is also possible for the deflate output stream to differ from the original +zlib due to algorithmic differences between the two libraries. Any tests or +applications that depend on the exact length of the deflate stream being a +certain value will need to be updated. + +**Advantages:** +- Easy to port to, since it only requires a recompile of the application and + no changes to the application code. + +**Disadvantages:** +- Can conflict with a system-installed zlib, as that can often be linked in + by another library you are linking into your application. This can cause + crashes or incorrect output. +- If your application is pre-allocating a memory buffer and you are providing + deflate/inflate init with your own allocator that allocates from that buffer + (looking at you nginx), you should be aware that zlib-ng needs to allocate + more memory than stock zlib needs. The same problem exists with Intel’s and + Cloudflare’s zlib forks. Doing this is not recommended since it makes it + very hard to maintain compatibility over time. + +**Build Considerations:** +- Compile against the *zlib.h* provided by zlib-ng +- Configuration header is named *zconf.h* +- Static library is *libz.a* on Unix and macOS, or *zlib.lib* on Windows +- Shared library is *libz.so* on Unix, *libz.dylib* on macOS, or *zlib1.dll* + on Windows +- Type `z_size_t` is *unsigned __int64* on 64-bit Windows, and *unsigned long* on 32-bit Windows, Unix and macOS +- Type `z_uintmax_t` is *unsigned long* in zlib-compat mode, and *size_t* with zlib-ng API + +zlib-ng native mode +------------------- +Zlib-ng in native mode is suitable for co-existing with the standard zlib +library, allowing applications to implement support and testing separately. + +The zlib-ng native has implemented some modernization and simplifications +in its API, intended to make life easier for application developers. + +**Advantages:** +- Does not conflict with other zlib implementations, and can co-exist as a + system library along with zlib. +- In certain places zlib-ng native uses more appropriate data types, removing + the need for some workarounds in the API compared to zlib. + +**Disadvantages:** +- Requires minor changes to applications to use the prefixed zlib-ng + function calls and structs. Usually this means a small prefix `zng_` has to be added. + +**Build Considerations:** +- Compile against *zlib-ng.h* +- Configuration header is named *zconf-ng.h* +- Static library is *libz-ng.a* on Unix and macOS, or *zlib-ng.lib* on Windows +- Shared library is *libz-ng.so* on Unix, *libz-ng.dylib* on macOS, or + *zlib-ng2.dll* on Windows +- Type `z_size_t` is *size_t* + +zlib-ng compile-time detection +------------------------------ + +To distinguish zlib-ng from other zlib implementations at compile-time check for the +existence of `ZLIBNG_VERSION` defined in the zlib header. diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/README.md b/internal-complibs/zlib-ng-2.1.1-beta2/README.md new file mode 100644 index 000000000..75b716b60 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/README.md @@ -0,0 +1,216 @@ +| CI | Stable | Develop | +|:---|:-------|:--------| +| GitHub Actions | [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20CMake/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20Configure/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Stable Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20NMake/badge.svg?branch=stable)](https://github.com/zlib-ng/zlib-ng/actions) | [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20CMake/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20Configure/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions)
    [![Develop Status](https://github.com/zlib-ng/zlib-ng/workflows/CI%20NMake/badge.svg?branch=develop)](https://github.com/zlib-ng/zlib-ng/actions) | +| CodeFactor | [![CodeFactor](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/badge/stable)](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/overview/stable) | [![CodeFactor](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/badge/develop)](https://www.codefactor.io/repository/github/zlib-ng/zlib-ng/overview/develop) | +| OSS-Fuzz | [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/zlib-ng.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zlib-ng) | [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/zlib-ng.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:zlib-ng) | +| Codecov | [![codecov](https://codecov.io/github/zlib-ng/zlib-ng/branch/stable/graph/badge.svg?token=uKsgK9LIuC)](https://codecov.io/github/zlib-ng/zlib-ng/tree/stable) | [![codecov](https://codecov.io/github/zlib-ng/zlib-ng/branch/develop/graph/badge.svg?token=uKsgK9LIuC)](https://codecov.io/github/zlib-ng/zlib-ng/tree/develop) | + +## zlib-ng +*zlib data compression library for the next generation systems* + +Maintained by Hans Kristian Rosbach + aka Dead2 (zlib-ng àt circlestorm dót org) + +Features +-------- + +* Zlib compatible API with support for dual-linking +* Modernized native API based on zlib API for ease of porting +* Modern C11 syntax and a clean code layout +* Deflate medium and quick algorithms based on Intel’s zlib fork +* Support for CPU intrinsics when available + * Adler32 implementation using SSSE3, AVX2, AVX512, AVX512-VNNI, Neon, VMX & VSX + * CRC32-B implementation using PCLMULQDQ, VPCLMULQDQ, ACLE, & IBM Z + * Hash table implementation using CRC32-C intrinsics on x86 and ARM + * Slide hash implementations using SSE2, AVX2, Neon, VMX & VSX + * Compare256 implementations using SSE2, AVX2, Neon, & POWER9 + * Inflate chunk copying using SSE2, SSSE3, AVX, Neon & VSX + * Support for hardware-accelerated deflate using IBM Z DFLTCC +* Unaligned memory read/writes and large bit buffer improvements +* Includes improvements from Cloudflare and Intel forks +* Configure, CMake, and NMake build system support +* Comprehensive set of CMake unit tests +* Code sanitizers, fuzzing, and coverage +* GitHub Actions continuous integration on Windows, macOS, and Linux + * Emulated CI for ARM, AARCH64, PPC, PPC64, RISCV, SPARC64, S390x using qemu + + +History +------- + +The motivation for this fork was seeing several 3rd party contributions with new optimizations not getting +implemented into the official zlib repository. + +Mark Adler has been maintaining zlib for a very long time, and he has done a great job and hopefully he will continue +for a long time yet. The idea of zlib-ng is not to replace zlib, but to co-exist as a drop-in replacement with a +lower threshold for code change. + +zlib has a long history and is incredibly portable, even supporting many systems that predate the Internet.
    +That is great, but it can complicate further development and maintainability. The zlib code contains many workarounds +for really old compilers or to accommodate systems with limitations such as operating in a 16-bit environment. + +Many of these workarounds are only maintenance burdens, some of them are pretty huge code-wise. With many workarounds +cluttered throughout the code, it makes it harder for new programmers with an idea/interest for zlib to contribute. + +I decided to make a fork, merge all the Intel optimizations, some of the Cloudflare optimizations, plus a couple other +smaller patches. Then started cleaning out workarounds, various dead code, all contrib and example code.
    +The result is a better performing and easier to maintain zlib-ng. + +A lot of improvements have gone into zlib-ng since its start, and numerous people and companies have contributed both +small and big improvements, or valuable testing. + + +Build +----- +Please read LICENSE.md, it is very simple and very liberal. + +There are two ways to build zlib-ng: + +### Cmake + +To build zlib-ng using the cross-platform makefile generator cmake. + +``` +cmake . +cmake --build . --config Release +ctest --verbose -C Release +``` + +Alternatively, you can use the cmake configuration GUI tool ccmake: + +``` +ccmake . +``` + +### Configure + +To build zlib-ng using the bash configure script: + +``` +./configure +make +make test +``` + +Build Options +------------- + +| CMake | configure | Description | Default | +|:-------------------------|:-------------------------|:--------------------------------------------------------------------------------------|---------| +| ZLIB_COMPAT | --zlib-compat | Compile with zlib compatible API | OFF | +| ZLIB_ENABLE_TESTS | | Build test binaries | ON | +| WITH_GZFILEOP | --without-gzfileops | Compile with support for gzFile related functions | ON | +| WITH_OPTIM | --without-optimizations | Build with optimisations | ON | +| WITH_NEW_STRATEGIES | --without-new-strategies | Use new strategies | ON | +| WITH_NATIVE_INSTRUCTIONS | --native | Compiles with full instruction set supported on this host (gcc/clang -march=native) | OFF | +| WITH_SANITIZER | | Build with sanitizer (memory, address, undefined) | OFF | +| WITH_GTEST | | Build gtest_zlib | ON | +| WITH_FUZZERS | | Build test/fuzz | OFF | +| WITH_BENCHMARKS | | Build test/benchmarks | OFF | +| WITH_MAINTAINER_WARNINGS | | Build with project maintainer warnings | OFF | +| WITH_CODE_COVERAGE | | Enable code coverage reporting | OFF | + + +Install +------- + +WARNING: We do not recommend manually installing unless you really know what you are doing, because this can +potentially override the system default zlib library, and any incompatibility or wrong configuration of zlib-ng +can make the whole system unusable, requiring recovery or reinstall. +If you still want a manual install, we recommend using the /opt/ path prefix. + +For Linux distros, an alternative way to use zlib-ng (if compiled in zlib-compat mode) instead of zlib, is through +the use of the _LD_PRELOAD_ environment variable. If the program is dynamically linked with zlib, then the program +will temporarily attempt to use zlib-ng instead, without risking system-wide instability. + +``` +LD_PRELOAD=/opt/zlib-ng/libz.so.1.2.13.zlib-ng /usr/bin/program +``` + +### Cmake + +To install zlib-ng system-wide using cmake: + +``` +cmake --build . --target install +``` + +### Configure + +To install zlib-ng system-wide using the configure script: + +``` +make install +``` + +### Vcpkg + +Alternatively, you can build and install zlib-ng using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager: + +```sh or powershell +git clone https://github.com/Microsoft/vcpkg.git +cd vcpkg +./bootstrap-vcpkg.sh # "./bootstrap-vcpkg.bat" for powershell +./vcpkg integrate install +./vcpkg install zlib-ng +``` + +The zlib-ng port in vcpkg is kept up to date by Microsoft team members and community contributors. +If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository. + +Contributing +------------ + +Zlib-ng is aiming to be open to contributions, and we would be delighted to receive pull requests on github. +Help with testing and reviewing pull requests etc is also very much appreciated. + +Please check the Wiki for more info: [Contributing](https://github.com/zlib-ng/zlib-ng/wiki/Contributing) + +Acknowledgments +---------------- + +Thanks go out to all the people and companies who have taken the time to contribute +code reviews, testing and/or patches. Zlib-ng would not have been nearly as good without you. + +The deflate format used by zlib was defined by Phil Katz.
    +The deflate and zlib specifications were written by L. Peter Deutsch. + +zlib was originally created by Jean-loup Gailly (compression) and Mark Adler (decompression). + + +Advanced Build Options +---------------------- + +| CMake | configure | Description | Default | +|:--------------------------------|:----------------------|:--------------------------------------------------------------------|------------------------| +| FORCE_SSE2 | --force-sse2 | Skip runtime check for SSE2 instructions (Always on for x86_64) | OFF (x86) | +| WITH_AVX2 | | Build with AVX2 intrinsics | ON | +| WITH_AVX512 | | Build with AVX512 intrinsics | ON | +| WITH_AVX512VNNI | | Build with AVX512VNNI intrinsics | ON | +| WITH_SSE2 | | Build with SSE2 intrinsics | ON | +| WITH_SSSE3 | | Build with SSSE3 intrinsics | ON | +| WITH_SSE42 | | Build with SSE42 intrinsics | ON | +| WITH_PCLMULQDQ | | Build with PCLMULQDQ intrinsics | ON | +| WITH_VPCLMULQDQ | --without-vpclmulqdq | Build with VPCLMULQDQ intrinsics | ON | +| WITH_ACLE | --without-acle | Build with ACLE intrinsics | ON | +| WITH_NEON | --without-neon | Build with NEON intrinsics | ON | +| WITH_ALTIVEC | --without-altivec | Build with AltiVec (VMX) intrinsics | ON | +| WITH_POWER8 | --without-power8 | Build with POWER8 optimisations | ON | +| WITH_RVV | | Build with RVV intrinsics | ON | +| WITH_CRC32_VX | --without-crc32-vx | Build with vectorized CRC32 on IBM Z | ON | +| WITH_DFLTCC_DEFLATE | --with-dfltcc-deflate | Build with DFLTCC intrinsics for compression on IBM Z | OFF | +| WITH_DFLTCC_INFLATE | --with-dfltcc-inflate | Build with DFLTCC intrinsics for decompression on IBM Z | OFF | +| WITH_UNALIGNED | --without-unaligned | Allow optimizations that use unaligned reads if safe on current arch| ON | +| WITH_INFLATE_STRICT | | Build with strict inflate distance checking | OFF | +| WITH_INFLATE_ALLOW_INVALID_DIST | | Build with zero fill for inflate invalid distances | OFF | +| INSTALL_UTILS | | Copy minigzip and minideflate during install | OFF | +| ZLIBNG_ENABLE_TESTS | | Test zlib-ng specific API | ON | + + +Related Projects +---------------- + +* Fork of the popular minizip https://github.com/zlib-ng/minizip-ng +* Python tool to benchmark minigzip/minideflate https://github.com/zlib-ng/deflatebench +* Python tool to benchmark pigz https://github.com/zlib-ng/pigzbench +* 3rd party patches for zlib-ng compatibility https://github.com/zlib-ng/patches diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/adler32.c b/internal-complibs/zlib-ng-2.1.1-beta2/adler32.c new file mode 100644 index 000000000..95ac13c30 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/adler32.c @@ -0,0 +1,115 @@ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_p.h" + +/* ========================================================================= */ +Z_INTERNAL uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + unsigned n; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) { + len -= NMAX; +#ifdef UNROLL_MORE + n = NMAX / 16; /* NMAX is divisible by 16 */ +#else + n = NMAX / 8; /* NMAX is divisible by 8 */ +#endif + do { +#ifdef UNROLL_MORE + DO16(adler, sum2, buf); /* 16 sums unrolled */ + buf += 16; +#else + DO8(adler, sum2, buf, 0); /* 8 sums unrolled */ + buf += 8; +#endif + } while (--n); + adler %= BASE; + sum2 %= BASE; + } + + /* do remaining bytes (less than NMAX, still just one modulo) */ + return adler32_len_64(adler, buf, len, sum2); +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_z)(unsigned long adler, const unsigned char *buf, size_t len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32_z)(uint32_t adler, const unsigned char *buf, size_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32)(unsigned long adler, const unsigned char *buf, unsigned int len) { + return (unsigned long)functable.adler32((uint32_t)adler, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(adler32)(uint32_t adler, const unsigned char *buf, uint32_t len) { + return functable.adler32(adler, buf, len); +} +#endif + +/* ========================================================================= */ +static uint32_t adler32_combine_(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + uint32_t sum1; + uint32_t sum2; + unsigned rem; + + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffff; + + /* the derivation of this formula is left as an exercise for the reader */ + len2 %= BASE; /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + sum2 %= BASE; + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= ((unsigned long)BASE << 1)) sum2 -= ((unsigned long)BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); +} + +/* ========================================================================= */ +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} + +unsigned long Z_EXPORT PREFIX4(adler32_combine)(unsigned long adler1, unsigned long adler2, z_off64_t len2) { + return (unsigned long)adler32_combine_((uint32_t)adler1, (uint32_t)adler2, len2); +} +#else +uint32_t Z_EXPORT PREFIX4(adler32_combine)(uint32_t adler1, uint32_t adler2, z_off64_t len2) { + return adler32_combine_(adler1, adler2, len2); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.c b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.c new file mode 100644 index 000000000..e2f6f9ac7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.c @@ -0,0 +1,16 @@ +/* adler32_fold.c -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "functable.h" +#include "adler32_fold.h" + +#include + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + adler = functable.adler32(adler, src, len); + memcpy(dst, src, len); + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.h b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.h new file mode 100644 index 000000000..20aa1c740 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_fold.h @@ -0,0 +1,11 @@ +/* adler32_fold.h -- adler32 folding interface + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_FOLD_H_ +#define ADLER32_FOLD_H_ + +Z_INTERNAL uint32_t adler32_fold_copy_c(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/adler32_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_p.h new file mode 100644 index 000000000..38ba2ad72 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/adler32_p.h @@ -0,0 +1,70 @@ +/* adler32_p.h -- Private inline functions and macros shared with + * different computation of the Adler-32 checksum + * of a data stream. + * Copyright (C) 1995-2011, 2016 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_P_H +#define ADLER32_P_H + +#define BASE 65521U /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(sum1, sum2, buf, i) {(sum1) += buf[(i)]; (sum2) += (sum1);} +#define DO2(sum1, sum2, buf, i) {DO1(sum1, sum2, buf, i); DO1(sum1, sum2, buf, i+1);} +#define DO4(sum1, sum2, buf, i) {DO2(sum1, sum2, buf, i); DO2(sum1, sum2, buf, i+2);} +#define DO8(sum1, sum2, buf, i) {DO4(sum1, sum2, buf, i); DO4(sum1, sum2, buf, i+4);} +#define DO16(sum1, sum2, buf) {DO8(sum1, sum2, buf, 0); DO8(sum1, sum2, buf, 8);} + +static inline uint32_t adler32_len_1(uint32_t adler, const uint8_t *buf, uint32_t sum2) { + adler += buf[0]; + adler %= BASE; + sum2 += adler; + sum2 %= BASE; + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_16(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { + while (len) { + --len; + adler += *buf++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_copy_len_16(uint32_t adler, const uint8_t *buf, uint8_t *dst, size_t len, uint32_t sum2) { + while (len--) { + *dst = *buf++; + adler += *dst++; + sum2 += adler; + } + adler %= BASE; + sum2 %= BASE; /* only added so many BASE's */ + /* return recombined sums */ + return adler | (sum2 << 16); +} + +static inline uint32_t adler32_len_64(uint32_t adler, const uint8_t *buf, size_t len, uint32_t sum2) { +#ifdef UNROLL_MORE + while (len >= 16) { + len -= 16; + DO16(adler, sum2, buf); + buf += 16; +#else + while (len >= 8) { + len -= 8; + DO8(adler, sum2, buf, 0); + buf += 8; +#endif + } + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif /* ADLER32_P_H */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/.gitignore b/internal-complibs/zlib-ng-2.1.1-beta2/arch/.gitignore new file mode 100644 index 000000000..2c3af0a08 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/.gitignore @@ -0,0 +1,2 @@ +# ignore Makefiles; they're all automatically generated +Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/Makefile.in new file mode 100644 index 000000000..abf6193fc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/Makefile.in @@ -0,0 +1,77 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +ACLEFLAG= +NEONFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + adler32_neon.o adler32_neon.lo \ + arm_features.o arm_features.lo \ + chunkset_neon.o chunkset_neon.lo \ + compare256_neon.o compare256_neon.lo \ + crc32_acle.o crc32_acle.lo \ + slide_hash_neon.o slide_hash_neon.lo \ + insert_string_acle.o insert_string_acle.lo + +adler32_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +adler32_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_neon.c + +arm_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +arm_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/arm_features.c + +chunkset_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +chunkset_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_neon.c + +compare256_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +compare256_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_neon.c + +crc32_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +crc32_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_acle.c + +slide_hash_neon.o: + $(CC) $(CFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +slide_hash_neon.lo: + $(CC) $(SFLAGS) $(NEONFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_neon.c + +insert_string_acle.o: + $(CC) $(CFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +insert_string_acle.lo: + $(CC) $(SFLAGS) $(ACLEFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_acle.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/adler32_neon.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/adler32_neon.c new file mode 100644 index 000000000..f1c43ff04 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/adler32_neon.c @@ -0,0 +1,215 @@ +/* Copyright (C) 1995-2011, 2016 Mark Adler + * Copyright (C) 2017 ARM Holdings Inc. + * Authors: + * Adenilson Cavalcanti + * Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../adler32_p.h" + +static void NEON_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + static const uint16_t ALIGNED_(16) taps[64] = { + 64, 63, 62, 61, 60, 59, 58, 57, + 56, 55, 54, 53, 52, 51, 50, 49, + 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, 35, 34, 33, + 32, 31, 30, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1 }; + + uint32x4_t adacc = vdupq_n_u32(0); + uint32x4_t s2acc = vdupq_n_u32(0); + uint32x4_t s2acc_0 = vdupq_n_u32(0); + uint32x4_t s2acc_1 = vdupq_n_u32(0); + uint32x4_t s2acc_2 = vdupq_n_u32(0); + + adacc = vsetq_lane_u32(s[0], adacc, 0); + s2acc = vsetq_lane_u32(s[1], s2acc, 0); + + uint32x4_t s3acc = vdupq_n_u32(0); + uint32x4_t adacc_prev = adacc; + + uint16x8_t s2_0, s2_1, s2_2, s2_3; + s2_0 = s2_1 = s2_2 = s2_3 = vdupq_n_u16(0); + + uint16x8_t s2_4, s2_5, s2_6, s2_7; + s2_4 = s2_5 = s2_6 = s2_7 = vdupq_n_u16(0); + + size_t num_iter = len >> 2; + int rem = len & 3; + + for (size_t i = 0; i < num_iter; ++i) { + uint8x16x4_t d0_d3 = vld1q_u8_x4(buf); + + /* Unfortunately it doesn't look like there's a direct sum 8 bit to 32 + * bit instruction, we'll have to make due summing to 16 bits first */ + uint16x8x2_t hsum, hsum_fold; + hsum.val[0] = vpaddlq_u8(d0_d3.val[0]); + hsum.val[1] = vpaddlq_u8(d0_d3.val[1]); + + hsum_fold.val[0] = vpadalq_u8(hsum.val[0], d0_d3.val[2]); + hsum_fold.val[1] = vpadalq_u8(hsum.val[1], d0_d3.val[3]); + + adacc = vpadalq_u16(adacc, hsum_fold.val[0]); + s3acc = vaddq_u32(s3acc, adacc_prev); + adacc = vpadalq_u16(adacc, hsum_fold.val[1]); + + /* If we do straight widening additions to the 16 bit values, we don't incur + * the usual penalties of a pairwise add. We can defer the multiplications + * until the very end. These will not overflow because we are incurring at + * most 408 loop iterations (NMAX / 64), and a given lane is only going to be + * summed into once. This means for the maximum input size, the largest value + * we will see is 255 * 102 = 26010, safely under uint16 max */ + s2_0 = vaddw_u8(s2_0, vget_low_u8(d0_d3.val[0])); + s2_1 = vaddw_high_u8(s2_1, d0_d3.val[0]); + s2_2 = vaddw_u8(s2_2, vget_low_u8(d0_d3.val[1])); + s2_3 = vaddw_high_u8(s2_3, d0_d3.val[1]); + s2_4 = vaddw_u8(s2_4, vget_low_u8(d0_d3.val[2])); + s2_5 = vaddw_high_u8(s2_5, d0_d3.val[2]); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0_d3.val[3])); + s2_7 = vaddw_high_u8(s2_7, d0_d3.val[3]); + + adacc_prev = adacc; + buf += 64; + } + + s3acc = vshlq_n_u32(s3acc, 6); + + if (rem) { + uint32x4_t s3acc_0 = vdupq_n_u32(0); + while (rem--) { + uint8x16_t d0 = vld1q_u8(buf); + uint16x8_t adler; + adler = vpaddlq_u8(d0); + s2_6 = vaddw_u8(s2_6, vget_low_u8(d0)); + s2_7 = vaddw_high_u8(s2_7, d0); + adacc = vpadalq_u16(adacc, adler); + s3acc_0 = vaddq_u32(s3acc_0, adacc_prev); + adacc_prev = adacc; + buf += 16; + } + + s3acc_0 = vshlq_n_u32(s3acc_0, 4); + s3acc = vaddq_u32(s3acc_0, s3acc); + } + + uint16x8x4_t t0_t3 = vld1q_u16_x4(taps); + uint16x8x4_t t4_t7 = vld1q_u16_x4(taps + 32); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[0], s2_0); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[0]), vget_low_u16(s2_0)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[1], s2_1); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[1]), vget_low_u16(s2_1)); + + s2acc = vmlal_high_u16(s2acc, t0_t3.val[2], s2_2); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t0_t3.val[2]), vget_low_u16(s2_2)); + s2acc_1 = vmlal_high_u16(s2acc_1, t0_t3.val[3], s2_3); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t0_t3.val[3]), vget_low_u16(s2_3)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[0], s2_4); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[0]), vget_low_u16(s2_4)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[1], s2_5); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[1]), vget_low_u16(s2_5)); + + s2acc = vmlal_high_u16(s2acc, t4_t7.val[2], s2_6); + s2acc_0 = vmlal_u16(s2acc_0, vget_low_u16(t4_t7.val[2]), vget_low_u16(s2_6)); + s2acc_1 = vmlal_high_u16(s2acc_1, t4_t7.val[3], s2_7); + s2acc_2 = vmlal_u16(s2acc_2, vget_low_u16(t4_t7.val[3]), vget_low_u16(s2_7)); + + s2acc = vaddq_u32(s2acc_0, s2acc); + s2acc_2 = vaddq_u32(s2acc_1, s2acc_2); + s2acc = vaddq_u32(s2acc, s2acc_2); + + uint32x2_t adacc2, s2acc2, as; + s2acc = vaddq_u32(s2acc, s3acc); + adacc2 = vpadd_u32(vget_low_u32(adacc), vget_high_u32(adacc)); + s2acc2 = vpadd_u32(vget_low_u32(s2acc), vget_high_u32(s2acc)); + as = vpadd_u32(adacc2, s2acc2); + s[0] = vget_lane_u32(as, 0); + s[1] = vget_lane_u32(as, 1); +} + +static void NEON_handle_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +Z_INTERNAL uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len) { + /* split Adler-32 into component sums */ + uint32_t sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == NULL) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) + return adler32_len_16(adler, buf, len, sum2); + + uint32_t pair[2]; + int n = NMAX; + unsigned int done = 0; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + pair[0] = adler; + pair[1] = sum2; + + /* If memory is not SIMD aligned, do scalar sums to an aligned + * offset, provided that doing so doesn't completely eliminate + * SIMD operation. Aligned loads are still faster on ARM, even + * though there's no explicit aligned load instruction */ + unsigned int align_offset = ((uintptr_t)buf & 15); + unsigned int align_adj = (align_offset) ? 16 - align_offset : 0; + + if (align_offset && len >= (16 + align_adj)) { + NEON_handle_tail(pair, buf, align_adj); + n -= align_adj; + done += align_adj; + + } else { + /* If here, we failed the len criteria test, it wouldn't be + * worthwhile to do scalar aligning sums */ + align_adj = 0; + } + + while (done < len) { + int remaining = (int)(len - done); + n = MIN(remaining, (done == align_adj) ? n : NMAX); + + if (n < 16) + break; + + NEON_accum32(pair, buf + done, n >> 4); + pair[0] %= BASE; + pair[1] %= BASE; + + int actual_nsums = (n >> 4) << 4; + done += actual_nsums; + } + + /* Handle the tail elements. */ + if (done < len) { + NEON_handle_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.c new file mode 100644 index 000000000..7394351fa --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.c @@ -0,0 +1,82 @@ +#include "../../zbuild.h" +#include "arm_features.h" + +#if defined(__linux__) && defined(HAVE_SYS_AUXV_H) +# include +# ifdef ARM_ASM_HWCAP +# include +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) +# include +# ifndef ID_AA64ISAR0_CRC32_VAL +# define ID_AA64ISAR0_CRC32_VAL ID_AA64ISAR0_CRC32 +# endif +#elif defined(__APPLE__) +# if !defined(_DARWIN_C_SOURCE) +# define _DARWIN_C_SOURCE /* enable types aliases (eg u_int) */ +# endif +# include +#elif defined(_WIN32) +# include +#endif + +static int arm_has_crc32() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_CRC32) +# ifdef HWCAP_CRC32 + return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif +#elif defined(__FreeBSD__) && defined(__aarch64__) + return getenv("QEMU_EMULATING") == NULL + && ID_AA64ISAR0_CRC32_VAL(READ_SPECIALREG(id_aa64isar0_el1)) >= ID_AA64ISAR0_CRC32_BASE; +#elif defined(__APPLE__) + int hascrc32; + size_t size = sizeof(hascrc32); + return sysctlbyname("hw.optional.armv8_crc32", &hascrc32, &size, NULL, 0) == 0 + && hascrc32 == 1; +#elif defined(_WIN32) + return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); +#elif defined(ARM_NOCHECK_ACLE) + return 1; +#else + return 0; +#endif +} + +/* AArch64 has neon. */ +#if !defined(__aarch64__) && !defined(_M_ARM64) +static inline int arm_has_neon() { +#if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) +# ifdef HWCAP_ARM_NEON + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +# else + return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# endif +#elif defined(__APPLE__) + int hasneon; + size_t size = sizeof(hasneon); + return sysctlbyname("hw.optional.neon", &hasneon, &size, NULL, 0) == 0 + && hasneon == 1; +#elif defined(_M_ARM) && defined(WINAPI_FAMILY_PARTITION) +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) + return 1; /* Always supported */ +# endif +#endif + +#if defined(ARM_NOCHECK_NEON) + return 1; +#else + return 0; +#endif +} +#endif + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features) { +#if defined(__aarch64__) || defined(_M_ARM64) + features->has_neon = 1; /* always available */ +#else + features->has_neon = arm_has_neon(); +#endif + features->has_crc32 = arm_has_crc32(); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.h new file mode 100644 index 000000000..6fcd8d3eb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/arm_features.h @@ -0,0 +1,15 @@ +/* arm_features.h -- check for ARM features. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ARM_H_ +#define ARM_H_ + +struct arm_cpu_features { + int has_neon; + int has_crc32; +}; + +void Z_INTERNAL arm_check_features(struct arm_cpu_features *features); + +#endif /* ARM_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/chunkset_neon.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/chunkset_neon.c new file mode 100644 index 000000000..1890c9135 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/chunkset_neon.c @@ -0,0 +1,101 @@ +/* chunkset_neon.c -- NEON inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../generic/chunk_permute_table.h" + +typedef uint8x16_t chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u16(vdupq_n_u16(tmp)); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u32(vdupq_n_u32(tmp)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = vreinterpretq_u8_u64(vdupq_n_u64(tmp)); +} + +#define CHUNKSIZE chunksize_neon +#define CHUNKCOPY chunkcopy_neon +#define CHUNKUNROLL chunkunroll_neon +#define CHUNKMEMSET chunkmemset_neon +#define CHUNKMEMSET_SAFE chunkmemset_safe_neon + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vld1q_u8(s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vst1q_u8(out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + + /* This version of table is only available on aarch64 */ +#if defined(_M_ARM64) || defined(__aarch64__) + uint8x16_t ret_vec = vld1q_u8(buf); + + uint8x16_t perm_vec = vld1q_u8(permute_table + lut_rem.idx); + return vqtbl1q_u8(ret_vec, perm_vec); +#else + uint8x8_t ret0, ret1, a, b, perm_vec0, perm_vec1; + perm_vec0 = vld1_u8(permute_table + lut_rem.idx); + perm_vec1 = vld1_u8(permute_table + lut_rem.idx + 8); + a = vld1_u8(buf); + b = vld1_u8(buf + 8); + ret0 = vtbl1_u8(a, perm_vec0); + uint8x8x2_t ab = {{a, b}}; + ret1 = vtbl2_u8(ab, perm_vec1); + return vcombine_u8(ret0, ret1); +#endif +} + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_neon + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/compare256_neon.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/compare256_neon.c new file mode 100644 index 000000000..7daeba411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/compare256_neon.c @@ -0,0 +1,59 @@ +/* compare256_neon.c - NEON version of compare256 + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +#include "neon_intrins.h" + +static inline uint32_t compare256_neon_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint8x16_t a, b, cmp; + uint64_t lane; + + a = vld1q_u8(src0); + b = vld1q_u8(src1); + + cmp = veorq_u8(a, b); + + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 0); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + lane = vgetq_lane_u64(vreinterpretq_u64_u8(cmp), 1); + if (lane) { + uint32_t match_byte = (uint32_t)__builtin_ctzll(lane) / 8; + return len + match_byte; + } + len += 8; + + src0 += 16, src1 += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1) { + return compare256_neon_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_neon +#define COMPARE256 compare256_neon_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/crc32_acle.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/crc32_acle.c new file mode 100644 index 000000000..a4e54d718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/crc32_acle.c @@ -0,0 +1,98 @@ +/* crc32_acle.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler + * Copyright (C) 2016 Yang Zhang + * For conditions of distribution and use, see copyright notice in zlib.h + * +*/ + +#ifdef ARM_ACLE +#ifdef _MSC_VER +# include +#else +# include +#endif +#include "../../zbuild.h" + +Z_INTERNAL uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + Z_REGISTER const uint16_t *buf2; + Z_REGISTER const uint32_t *buf4; + + c = ~crc; + if (len && ((ptrdiff_t)buf & 1)) { + c = __crc32b(c, *buf++); + len--; + } + + if ((len >= sizeof(uint16_t)) && ((ptrdiff_t)buf & sizeof(uint16_t))) { + buf2 = (const uint16_t *) buf; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf4 = (const uint32_t *) buf2; + } else { + buf4 = (const uint32_t *) buf; + } + +#if defined(__aarch64__) || defined(_M_ARM64) + if ((len >= sizeof(uint32_t)) && ((ptrdiff_t)buf & sizeof(uint32_t))) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len == 0) { + c = ~c; + return c; + } + + const uint64_t *buf8 = (const uint64_t *) buf4; + + while (len >= sizeof(uint64_t)) { + c = __crc32d(c, *buf8++); + len -= sizeof(uint64_t); + } + + if (len >= sizeof(uint32_t)) { + buf4 = (const uint32_t *) buf8; + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + buf2 = (const uint16_t *) buf4; + } else { + buf2 = (const uint16_t *) buf8; + } + + if (len >= sizeof(uint16_t)) { + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + } + + buf = (const unsigned char *) buf2; +#else /* __aarch64__ */ + + if (len == 0) { + c = ~c; + return c; + } + + while (len >= sizeof(uint32_t)) { + c = __crc32w(c, *buf4++); + len -= sizeof(uint32_t); + } + + if (len >= sizeof(uint16_t)) { + buf2 = (const uint16_t *) buf4; + c = __crc32h(c, *buf2++); + len -= sizeof(uint16_t); + buf = (const unsigned char *) buf2; + } else { + buf = (const unsigned char *) buf4; + } +#endif /* __aarch64__ */ + + if (len) { + c = __crc32b(c, *buf); + } + + c = ~c; + return c; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/insert_string_acle.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/insert_string_acle.c new file mode 100644 index 000000000..9ac3ccb42 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/insert_string_acle.c @@ -0,0 +1,26 @@ +/* insert_string_acle.c -- insert_string integer hash variant using ACLE's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifdef ARM_ACLE +#ifndef _MSC_VER +# include +#endif +#include "../../zbuild.h" +#include "../../deflate.h" + +#define HASH_CALC(s, h, val) \ + h = __crc32w(0, val) + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_acle +#define INSERT_STRING insert_string_acle +#define QUICK_INSERT_STRING quick_insert_string_acle + +#include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/neon_intrins.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/neon_intrins.h new file mode 100644 index 000000000..d6b57f641 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/neon_intrins.h @@ -0,0 +1,57 @@ +#ifndef ARM_NEON_INTRINS_H +#define ARM_NEON_INTRINS_H + +#ifdef _M_ARM64 +# include +#else +# include +#endif + +#if defined(ARM_NEON) && !defined(__aarch64__) && !defined(_M_ARM64) +/* Compatibility shim for the _high family of functions */ +#define vmull_high_u8(a, b) vmull_u8(vget_high_u8(a), vget_high_u8(b)) +#define vmlal_high_u8(a, b, c) vmlal_u8(a, vget_high_u8(b), vget_high_u8(c)) +#define vmlal_high_u16(a, b, c) vmlal_u16(a, vget_high_u16(b), vget_high_u16(c)) +#define vaddw_high_u8(a, b) vaddw_u8(a, vget_high_u8(b)) +#endif + +#ifdef ARM_NEON + +#define vqsubq_u16_x4_x1(out, a, b) do { \ + out.val[0] = vqsubq_u16(a.val[0], b); \ + out.val[1] = vqsubq_u16(a.val[1], b); \ + out.val[2] = vqsubq_u16(a.val[2], b); \ + out.val[3] = vqsubq_u16(a.val[3], b); \ +} while (0) + + +# ifndef ARM_NEON_HASLD4 + +static inline uint16x8x4_t vld1q_u16_x4(uint16_t const *a) { + uint16x8x4_t ret = (uint16x8x4_t) {{ + vld1q_u16(a), + vld1q_u16(a+8), + vld1q_u16(a+16), + vld1q_u16(a+24)}}; + return ret; +} + +static inline uint8x16x4_t vld1q_u8_x4(uint8_t const *a) { + uint8x16x4_t ret = (uint8x16x4_t) {{ + vld1q_u8(a), + vld1q_u8(a+16), + vld1q_u8(a+32), + vld1q_u8(a+48)}}; + return ret; +} + +static inline void vst1q_u16_x4(uint16_t *p, uint16x8x4_t a) { + vst1q_u16(p, a.val[0]); + vst1q_u16(p + 8, a.val[1]); + vst1q_u16(p + 16, a.val[2]); + vst1q_u16(p + 24, a.val[3]); +} +# endif // HASLD4 check +#endif + +#endif // include guard ARM_NEON_INTRINS_H diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/slide_hash_neon.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/slide_hash_neon.c new file mode 100644 index 000000000..a96ca1179 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/arm/slide_hash_neon.c @@ -0,0 +1,46 @@ +/* slide_hash_neon.c -- Optimized hash table shifting for ARM with support for NEON instructions + * Copyright (C) 2017-2020 Mika T. Lindqvist + * + * Authors: + * Mika T. Lindqvist + * Jun He + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef ARM_NEON +#include "neon_intrins.h" +#include "../../zbuild.h" +#include "../../deflate.h" + +/* SIMD version of hash_chain rebase */ +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + Z_REGISTER uint16x8_t v; + uint16x8x4_t p0, p1; + Z_REGISTER size_t n; + + size_t size = entries*sizeof(table[0]); + Assert((size % sizeof(uint16x8_t) * 8 == 0), "hash table size err"); + + Assert(sizeof(Pos) == 2, "Wrong Pos size"); + v = vdupq_n_u16(wsize); + + n = size / (sizeof(uint16x8_t) * 8); + do { + p0 = vld1q_u16_x4(table); + p1 = vld1q_u16_x4(table+32); + vqsubq_u16_x4_x1(p0, p0, v); + vqsubq_u16_x4_x1(p1, p1, v); + vst1q_u16_x4(table, p0); + vst1q_u16_x4(table+32, p1); + table += 64; + } while (--n); +} + +Z_INTERNAL void slide_hash_neon(deflate_state *s) { + unsigned int wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/Makefile.in new file mode 100644 index 000000000..be8c18545 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/Makefile.in @@ -0,0 +1,21 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: + + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ \ + rm -rf objs + rm -f *.gcda *.gcno *.gcov diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/chunk_permute_table.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/chunk_permute_table.h new file mode 100644 index 000000000..bad66ccc7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/generic/chunk_permute_table.h @@ -0,0 +1,53 @@ +/* chunk_permute_table.h - shared AVX/SSSE3 permutation table for use with chunkmemset family of functions. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CHUNK_PERMUTE_TABLE_H_ +#define CHUNK_PERMUTE_TABLE_H_ + +#include "zbuild.h" + +/* Need entries for all numbers not an even modulus for 1, 2, 4, 8, 16 & 32 */ +static const ALIGNED_(32) uint8_t permute_table[26*32] = { + 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, /* dist 3 */ + 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, /* dist 5 */ + 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0, 1, /* dist 6 */ + 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 3, /* dist 7 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, /* dist 9 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, /* dist 10 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 11 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 12 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 1, 2, 3, 4, 5, /* dist 13 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0, 1, 2, 3, /* dist 14 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 1, /* dist 15 */ + + /* Beyond dists of 15 means we have to permute from a vector > len(m128i). Because AVX couldn't permute + * beyond 128 bit lanes until AVX512 for sub 4-byte sequences, we have to do some math here for an eventual + * blend with a comparison. That means we need to wrap the indices with yet another derived table. For simplicity, + * we'll use absolute indexing here to derive a blend vector. This is actually a lot simpler with ARM's TBL, but, + * this is what we're dealt. + */ + + 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* dist 17 */ + 16, 17, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, /* dist 18 */ + 16, 17, 18, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, /* dist 19 */ + 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* dist 20 */ + 16, 17, 18, 19, 20, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, /* dist 21 */ + 16, 17, 18, 19, 20, 21, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* dist 22 */ + 16, 17, 18, 19, 20, 21, 22, 0, 1, 2, 3, 4, 5, 6, 7, 8, /* dist 23 */ + 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, /* dist 24 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 0, 1, 2, 3, 4, 5, 6, /* dist 25 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 1, 2, 3, 4, 5, /* dist 26 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 0, 1, 2, 3, 4, /* dist 27 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 0, 1, 2, 3, /* dist 28 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 0, 1, 2, /* dist 29 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 0, 1, /* dist 30 */ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 0, /* dist 31 */ +}; + +typedef struct lut_rem_pair_s { + uint16_t idx; + uint16_t remval; +} lut_rem_pair; + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/Makefile.in new file mode 100644 index 000000000..e9be6dddb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/Makefile.in @@ -0,0 +1,93 @@ +# Makefile for POWER-specific files +# Copyright (C) 2020 Matheus Castanho , IBM +# Copyright (C) 2021 Mika T. Lindqvist +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +P8FLAGS=-mcpu=power8 +P9FLAGS=-mcpu=power9 +PPCFLAGS=-maltivec +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: power_features.o \ + power_features.lo \ + adler32_power8.o \ + adler32_power8.lo \ + adler32_vmx.o \ + adler32_vmx.lo \ + chunkset_power8.o \ + chunkset_power8.lo \ + compare256_power9.o \ + compare256_power9.lo \ + crc32_power8.o \ + crc32_power8.lo \ + slide_hash_power8.o \ + slide_hash_power8.lo \ + slide_hash_vmx.o \ + slide_hash_vmx.lo + +power_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +power_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/power_features.c + +adler32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_power8.c + +adler32_vmx.o: + $(CC) $(CFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +adler32_vmx.lo: + $(CC) $(SFLAGS) $(PPCFLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_vmx.c + +chunkset_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +chunkset_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_power8.c + +compare256_power9.o: + $(CC) $(CFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +compare256_power9.lo: + $(CC) $(SFLAGS) $(P9FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_power9.c + +crc32_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +crc32_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_power8.c + +slide_hash_power8.o: + $(CC) $(CFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_power8.lo: + $(CC) $(SFLAGS) $(P8FLAGS) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_power8.c + +slide_hash_vmx.o: + $(CC) $(CFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +slide_hash_vmx.lo: + $(CC) $(SFLAGS) ${PPCFLAGS} $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_vmx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_power8.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_power8.c new file mode 100644 index 000000000..4aaea9f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_power8.c @@ -0,0 +1,153 @@ +/* Adler32 for POWER8 using VSX instructions. + * Copyright (C) 2020 IBM Corporation + * Author: Rogerio Alves + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate adler32 checksum for 16 bytes at once using POWER8+ VSX (vector) + * instructions. + * + * If adler32 do 1 byte at time on the first iteration s1 is s1_0 (_n means + * iteration n) is the initial value of adler - at start _0 is 1 unless + * adler initial value is different than 1. So s1_1 = s1_0 + c[0] after + * the first calculation. For the iteration s1_2 = s1_1 + c[1] and so on. + * Hence, for iteration N, s1_N = s1_(N-1) + c[N] is the value of s1 on + * after iteration N. + * + * Therefore, for s2 and iteration N, s2_N = s2_0 + N*s1_N + N*c[0] + + * N-1*c[1] + ... + c[N] + * + * In a more general way: + * + * s1_N = s1_0 + sum(i=1 to N)c[i] + * s2_N = s2_0 + N*s1 + sum (i=1 to N)(N-i+1)*c[i] + * + * Where s1_N, s2_N are the values for s1, s2 after N iterations. So if we + * can process N-bit at time we can do this at once. + * + * Since VSX can support 16-bit vector instructions, we can process + * 16-bit at time using N = 16 we have: + * + * s1 = s1_16 = s1_(16-1) + c[16] = s1_0 + sum(i=1 to 16)c[i] + * s2 = s2_16 = s2_0 + 16*s1 + sum(i=1 to 16)(16-i+1)*c[i] + * + * After the first iteration we calculate the adler32 checksum for 16 bytes. + * + * For more background about adler32 please check the RFC: + * https://www.ietf.org/rfc/rfc1950.txt + */ + +#ifdef POWER8_VSX + +#include +#include "zbuild.h" +#include "adler32_p.h" + +/* Vector across sum unsigned int (saturate). */ +static inline vector unsigned int vec_sumsu(vector unsigned int __a, vector unsigned int __b) { + __b = vec_sld(__a, __a, 8); + __b = vec_add(__b, __a); + __a = vec_sld(__b, __b, 4); + __a = vec_add(__a, __b); + + return __a; +} + +Z_INTERNAL uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t s1 = adler & 0xffff; + uint32_t s2 = (adler >> 16) & 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(s1, buf, s2); + + /* If buffer is empty or len=0 we need to return adler initial value. */ + if (UNLIKELY(buf == NULL)) + return 1; + + /* This is faster than VSX code for len < 64. */ + if (len < 64) + return adler32_len_64(s1, buf, len, s2); + + /* Use POWER VSX instructions for len >= 64. */ + const vector unsigned int v_zeros = { 0 }; + const vector unsigned char v_mul = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, + 6, 5, 4, 3, 2, 1}; + const vector unsigned char vsh = vec_splat_u8(4); + const vector unsigned int vmask = {0xffffffff, 0x0, 0x0, 0x0}; + vector unsigned int vs1 = { 0 }; + vector unsigned int vs2 = { 0 }; + vector unsigned int vs1_save = { 0 }; + vector unsigned int vsum1, vsum2; + vector unsigned char vbuf; + int n; + + vs1[0] = s1; + vs2[0] = s2; + + /* Do length bigger than NMAX in blocks of NMAX size. */ + while (len >= NMAX) { + len -= NMAX; + n = NMAX / 16; + do { + vbuf = vec_xl(0, (unsigned char *) buf); + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } while (--n); + /* Once each block of NMAX size. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + + /* vs1[0] = (s1_i + sum(i=1 to 16)buf[i]) mod 65521. */ + vs1[0] = vs1[0] % BASE; + /* vs2[0] = s2_i + 16*s1_save + + sum(i=1 to 16)(16-i+1)*buf[i] mod 65521. */ + vs2[0] = vs2[0] % BASE; + + vs1 = vec_and(vs1, vmask); + vs2 = vec_and(vs2, vmask); + vs1_save = v_zeros; + } + + /* len is less than NMAX one modulo is needed. */ + if (len >= 16) { + while (len >= 16) { + len -= 16; + + vbuf = vec_xl(0, (unsigned char *) buf); + + vsum1 = vec_sum4s(vbuf, v_zeros); /* sum(i=1 to 16) buf[i]. */ + /* sum(i=1 to 16) buf[i]*(16-i+1). */ + vsum2 = vec_msum(vbuf, v_mul, v_zeros); + /* Save vs1. */ + vs1_save = vec_add(vs1_save, vs1); + /* Accumulate the sums. */ + vs1 = vec_add(vsum1, vs1); + vs2 = vec_add(vsum2, vs2); + + buf += 16; + } + /* Since the size will be always less than NMAX we do this once. */ + vs1 = vec_sumsu(vs1, vsum1); + vs1_save = vec_sll(vs1_save, vsh); /* 16*vs1_save. */ + vs2 = vec_add(vs1_save, vs2); + vs2 = vec_sumsu(vs2, vsum2); + } + /* Copy result back to s1, s2 (mod 65521). */ + s1 = vs1[0] % BASE; + s2 = vs2[0] % BASE; + + /* Process tail (len < 16). */ + return adler32_len_16(s1, buf, len, s2); +} + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_vmx.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_vmx.c new file mode 100644 index 000000000..ef1649b58 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/adler32_vmx.c @@ -0,0 +1,181 @@ +/* adler32_vmx.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Copyright (C) 2017-2021 Mika T. Lindqvist + * Copyright (C) 2021 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef PPC_VMX +#include +#include "zbuild.h" +#include "adler32_p.h" + +#define vmx_zero() (vec_splat_u32(0)) + +static inline void vmx_handle_head_or_tail(uint32_t *pair, const uint8_t *buf, size_t len) { + unsigned int i; + for (i = 0; i < len; ++i) { + pair[0] += buf[i]; + pair[1] += pair[0]; + } +} + +static void vmx_accum32(uint32_t *s, const uint8_t *buf, size_t len) { + /* Different taps for the separable components of sums */ + const vector unsigned char t0 = {64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49}; + const vector unsigned char t1 = {48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33}; + const vector unsigned char t2 = {32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17}; + const vector unsigned char t3 = {16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; + /* As silly and inefficient as it seems, creating 1 permutation vector to permute + * a 2 element vector from a single load + a subsequent shift is just barely faster + * than doing 2 indexed insertions into zero initialized vectors from unaligned memory. */ + const vector unsigned char s0_perm = {0, 1, 2, 3, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + const vector unsigned char shift_vec = vec_sl(vec_splat_u8(8), vec_splat_u8(2)); + vector unsigned int adacc, s2acc; + vector unsigned int pair_vec = vec_ld(0, s); + adacc = vec_perm(pair_vec, pair_vec, s0_perm); + s2acc = vec_slo(pair_vec, shift_vec); + + vector unsigned int zero = vmx_zero(); + vector unsigned int s3acc = zero; + vector unsigned int s3acc_0 = zero; + vector unsigned int adacc_prev = adacc; + vector unsigned int adacc_prev_0 = zero; + + vector unsigned int s2acc_0 = zero; + vector unsigned int s2acc_1 = zero; + vector unsigned int s2acc_2 = zero; + + /* Maintain a running sum of a second half, this might help use break yet another + * data dependency bubble in the sum */ + vector unsigned int adacc_0 = zero; + + int num_iter = len / 4; + int rem = len & 3; + + for (int i = 0; i < num_iter; ++i) { + vector unsigned char d0 = vec_ld(0, buf); + vector unsigned char d1 = vec_ld(16, buf); + vector unsigned char d2 = vec_ld(32, buf); + vector unsigned char d3 = vec_ld(48, buf); + + /* The core operation of the loop, basically + * what is being unrolled below */ + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s3acc_0 = vec_add(s3acc_0, adacc_prev_0); + s2acc = vec_msum(t0, d0, s2acc); + + /* interleave dependent sums in here */ + adacc_0 = vec_sum4s(d1, adacc_0); + s2acc_0 = vec_msum(t1, d1, s2acc_0); + adacc = vec_sum4s(d2, adacc); + s2acc_1 = vec_msum(t2, d2, s2acc_1); + s2acc_2 = vec_msum(t3, d3, s2acc_2); + adacc_0 = vec_sum4s(d3, adacc_0); + + adacc_prev = adacc; + adacc_prev_0 = adacc_0; + buf += 64; + } + + adacc = vec_add(adacc, adacc_0); + s3acc = vec_add(s3acc, s3acc_0); + s3acc = vec_sl(s3acc, vec_splat_u32(6)); + + if (rem) { + adacc_prev = vec_add(adacc_prev_0, adacc_prev); + adacc_prev = vec_sl(adacc_prev, vec_splat_u32(4)); + while (rem--) { + vector unsigned char d0 = vec_ld(0, buf); + adacc = vec_sum4s(d0, adacc); + s3acc = vec_add(s3acc, adacc_prev); + s2acc = vec_msum(t3, d0, s2acc); + adacc_prev = vec_sl(adacc, vec_splat_u32(4)); + buf += 16; + } + } + + + /* Sum up independent second sums */ + s2acc = vec_add(s2acc, s2acc_0); + s2acc_2 = vec_add(s2acc_1, s2acc_2); + s2acc = vec_add(s2acc, s2acc_2); + + s2acc = vec_add(s2acc, s3acc); + + adacc = vec_add(adacc, vec_sld(adacc, adacc, 8)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 8)); + adacc = vec_add(adacc, vec_sld(adacc, adacc, 4)); + s2acc = vec_add(s2acc, vec_sld(s2acc, s2acc, 4)); + + vec_ste(adacc, 0, s); + vec_ste(s2acc, 0, s+1); +} + +Z_INTERNAL uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + uint32_t pair[16] ALIGNED_(16); + memset(&pair[2], 0, 14); + int n = NMAX; + unsigned int done = 0, i; + + /* Split Adler-32 into component sums, it can be supplied by + * the caller sites (e.g. in a PNG file). + */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + pair[0] = adler; + pair[1] = sum2; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + // Align buffer + unsigned int al = 0; + if ((uintptr_t)buf & 0xf) { + al = 16-((uintptr_t)buf & 0xf); + if (al > len) { + al=len; + } + vmx_handle_head_or_tail(pair, buf, al); + + done += al; + /* Rather than rebasing, we can reduce the max sums for the + * first round only */ + n -= al; + } + for (i = al; i < len; i += n) { + int remaining = (int)(len-i); + n = MIN(remaining, (i == al) ? n : NMAX); + + if (n < 16) + break; + + vmx_accum32(pair, buf + i, n / 16); + pair[0] %= BASE; + pair[1] %= BASE; + + done += (n / 16) * 16; + } + + /* Handle the tail elements. */ + if (done < len) { + vmx_handle_head_or_tail(pair, (buf + done), len - done); + pair[0] %= BASE; + pair[1] %= BASE; + } + + /* D = B * 65536 + A, see: https://en.wikipedia.org/wiki/Adler-32. */ + return (pair[1] << 16) | pair[0]; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/chunkset_power8.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/chunkset_power8.c new file mode 100644 index 000000000..443aae92f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/chunkset_power8.c @@ -0,0 +1,55 @@ +/* chunkset_power8.c -- VSX inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX +#include +#include "../../zbuild.h" + +typedef vector unsigned char chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + uint16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + uint64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = (vector unsigned char)vec_splats(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = vec_xl(0, s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + vec_xst(*chunk, 0, out); +} + +#define CHUNKSIZE chunksize_power8 +#define CHUNKCOPY chunkcopy_power8 +#define CHUNKUNROLL chunkunroll_power8 +#define CHUNKMEMSET chunkmemset_power8 +#define CHUNKMEMSET_SAFE chunkmemset_safe_power8 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_power8 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/compare256_power9.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/compare256_power9.c new file mode 100644 index 000000000..9b3e61701 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/compare256_power9.c @@ -0,0 +1,66 @@ +/* compare256_power9.c - Power9 version of compare256 + * Copyright (C) 2019 Matheus Castanho , IBM + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER9 +#include +#include "../../zbuild.h" +#include "../../zendian.h" + +/* Older versions of GCC misimplemented semantics for these bit counting builtins. + * https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;h=3f30f2d1dbb3228b8468b26239fe60c2974ce2ac */ +#if defined(__GNUC__) && (__GNUC__ < 12) +# define zng_vec_vctzlsbb(vc, len) __asm__ volatile("vctzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +# define zng_vec_vclzlsbb(vc, len) __asm__ volatile("vclzlsbb %0, %1\n\t" : "=r" (len) : "v" (vc)) +#else +# define zng_vec_vctzlsbb(vc, len) len = __builtin_vec_vctzlsbb(vc) +# define zng_vec_vclzlsbb(vc, len) len = __builtin_vec_vclzlsbb(vc) +#endif + +static inline uint32_t compare256_power9_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0, cmplen; + + do { + vector unsigned char vsrc0, vsrc1, vc; + + vsrc0 = *((vector unsigned char *)src0); + vsrc1 = *((vector unsigned char *)src1); + + /* Compare 16 bytes at a time. Each byte of vc will be either + * all ones or all zeroes, depending on the result of the comparison. */ + vc = (vector unsigned char)vec_cmpne(vsrc0, vsrc1); + + /* Since the index of matching bytes will contain only zeroes + * on vc (since we used cmpne), counting the number of consecutive + * bytes where LSB == 0 is the same as counting the length of the match. */ +#if BYTE_ORDER == LITTLE_ENDIAN + zng_vec_vctzlsbb(vc, cmplen); +#else + zng_vec_vclzlsbb(vc, cmplen); +#endif + if (cmplen != 16) + return len + cmplen; + + src0 += 16, src1 += 16, len += 16; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1) { + return compare256_power9_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_power9 +#define COMPARE256 compare256_power9_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_constants.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_constants.h new file mode 100644 index 000000000..8c8f2153b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_constants.h @@ -0,0 +1,1123 @@ +/* Constants table used by crc32_power8.c + * Copyright (C) 2021 IBM Corporation + * + * This file was automatically generated, DO NOT EDIT IT MANUALLY. + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zendian.h" +#include "zbuild.h" + +/* Reduce 262144 kbits to 1024 bits */ +static const __vector unsigned long long vcrc_const[255] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x0000000099ea94a8, 0x00000001651797d2 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x00000000945a8420, 0x0000000021e0d56c }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x0000000030762706, 0x000000000f95ecaa }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001a52fc582, 0x00000001ebd224ac }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x00000001a4a7167a, 0x000000000ccb97ca }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x000000000c18249a, 0x00000001006ec8a8 }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x00000000a924ae7c, 0x000000014f58f196 }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001e12ccc12, 0x00000001a7192ca6 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x00000000a0b9d4ac, 0x000000019a64bab2 }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000095e8ddfe, 0x0000000014f4ed2e }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x00000000233fddc4, 0x000000011092b6a2 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000001b4529b62, 0x00000000c8a1629c }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x00000001a7fa0e64, 0x000000017bf32e8e }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001b5334592, 0x00000001f8cc6582 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000011f8ee1b4, 0x000000008631ddf0 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000006252e632, 0x000000007e5a76d0 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x00000000ab973e84, 0x000000002b09b31c }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x000000007734f5ec, 0x00000001b2df1f84 }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x000000007c547798, 0x00000001d6f56afc }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x000000007ec40210, 0x00000001b9b5e70c }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x00000001ab1695a8, 0x0000000034b626d2 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x0000000090494bba, 0x000000014c53479a }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001123fb816, 0x00000001a6d179a4 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x00000001e188c74c, 0x000000015abd16b4 }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000001c2d3451c, 0x00000000018f9852 }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x00000000f55cf1ca, 0x000000001fb3084a }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000001a0531540, 0x00000000c53dfb04 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x0000000132cd7ebc, 0x00000000e10c9ad6 }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000073ab7f36, 0x0000000025aa994a }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x0000000041aed1c2, 0x00000000fa3a74c4 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000136c53800, 0x0000000033eb3f40 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x0000000126835a30, 0x000000017193f296 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x000000006241b502, 0x0000000043f6c86a }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x00000000d5196ad4, 0x000000016b513ec6 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x000000009cfa769a, 0x00000000c8f25b4e }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000000920e5df4, 0x00000001a45048ec }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x0000000169dc310e, 0x000000000c441004 }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x0000000009fc331c, 0x000000000e17cad6 }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x000000010d94a81e, 0x00000001253ae964 }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x0000000027a20ab2, 0x00000001d7c88ebc }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x0000000114f87504, 0x00000001e7ca913a }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x000000004b076d96, 0x0000000033ed078a }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000da4d1e74, 0x00000000e1839c78 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x000000001b81f672, 0x00000001322b267e }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x000000009367c988, 0x00000000638231b6 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001717214ca, 0x00000001ee7f16f4 }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x000000009f47d820, 0x0000000117d9924a }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x000000010d9a47d2, 0x00000000e1a9e0c4 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000000a696c58c, 0x00000001403731dc }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x000000002aa28ec6, 0x00000001a5ea9682 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x00000001fe18fd9a, 0x0000000101c5c578 }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x000000019d4fc1ae, 0x00000000dddf6494 }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000001ba0e3dea, 0x00000000f1c3db28 }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x0000000074b59a5e, 0x000000013112fb9c }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000f2b5ea98, 0x00000000b680b906 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x0000000187132676, 0x000000001a282932 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x000000010a8c6ad4, 0x0000000089406e7e }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001e21dfe70, 0x00000001def6be8c }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x00000001da0050e4, 0x0000000075258728 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x00000000772172ae, 0x000000019536090a }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000e47724aa, 0x00000000f2455bfc }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000003cd63ac4, 0x000000018c40baf4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x00000001bf47d352, 0x000000004cd390d4 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x000000018dc1d708, 0x00000001e4ece95a }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000002d4620a4, 0x000000001a3ee918 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x0000000058fd1740, 0x000000007c652fb8 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x00000000dadd9bfc, 0x000000011c67842c }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000001ea2140be, 0x00000000254f759c }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000009de128ba, 0x000000007ece94ca }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x000000013ac3aa8e, 0x0000000038f258c2 }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x0000000099980562, 0x00000001cdf17b00 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x00000001c1579c86, 0x000000011f882c16 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000068dbbf94, 0x0000000100093fc8 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x000000004509fb04, 0x00000001cd684f16 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x00000001202f6398, 0x000000004bc6a70a }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000013aea243e, 0x000000004fc7e8e4 }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x00000001b4052ae6, 0x0000000130103f1c }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x00000001cd2a0ae8, 0x0000000111b0024c }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x00000001fe4aa8b4, 0x000000010b3079da }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x00000001d1559a42, 0x000000010192bcc2 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x00000001f3e05ecc, 0x0000000074838d50 }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x0000000104ddd2cc, 0x000000001b20f520 }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x000000015393153c, 0x0000000050c3590a }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x0000000057e942c6, 0x00000000b41cac8e }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000012c633850, 0x000000000c72cc78 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x00000000ebcaae4c, 0x0000000030cdb032 }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013ee532a6, 0x000000013e09fc32 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x00000001bf0cbc7e, 0x000000001ed624d2 }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000d50b7a5a, 0x00000000781aee1a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x0000000002fca6e8, 0x00000001c4d8348c }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x000000007af40044, 0x0000000057a40336 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000016178744, 0x0000000085544940 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000014c177458, 0x000000019cd21e80 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000011b6ddf04, 0x000000013eb95bc0 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001f3e29ccc, 0x00000001dfc9fdfc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x0000000135ae7562, 0x00000000cd028bc2 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000190ef812c, 0x0000000090db8c44 }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x0000000067a2c786, 0x000000010010a4ce }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x0000000048b9496c, 0x00000001c8f4c72c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000015a422de6, 0x000000001c26170c }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000001ef0e3640, 0x00000000e3fccf68 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000001006d2d26, 0x00000000d513ed24 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000001170d56d6, 0x00000000141beada }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x00000000a5fb613c, 0x000000011071aea0 }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x0000000040bbf7fc, 0x000000012e19080a }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x000000016ac3a5b2, 0x0000000100ecf826 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x00000000abf16230, 0x0000000069b09412 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x00000001ebe23fac, 0x0000000122297bac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x000000008b6a0894, 0x00000000e9e4b068 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x00000001288ea478, 0x000000004b38651a }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x000000016619c442, 0x00000001468360e2 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x0000000086230038, 0x00000000121c2408 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x000000017746a756, 0x00000000da7e7d08 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x0000000191b8f8f8, 0x00000001058d7652 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000008e167708, 0x000000014a098a90 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000148b22d54, 0x0000000020dbe72e }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x0000000044ba2c3c, 0x000000011e7323e8 }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000b54d2b52, 0x00000000d5d4bf94 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000005a4fd8a, 0x0000000199d8746c }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x0000000139f9fc46, 0x00000000ce9ca8a0 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x000000015a1fa824, 0x00000000136edece }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000000a61ae4c, 0x000000019b92a068 }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000145e9113e, 0x0000000071d62206 }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x000000006a348448, 0x00000000dfc50158 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x000000004d80a08c, 0x00000001517626bc }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x000000014b6837a0, 0x0000000148d1e4fa }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x000000016896a7fc, 0x0000000094d8266e }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x000000014f187140, 0x00000000606c5e34 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019581b9da, 0x000000019766beaa }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001091bc984, 0x00000001d80c506c }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001067223c, 0x000000001e73837c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x00000001ab16ea02, 0x0000000064d587de }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x000000013c4598a8, 0x00000000f4a507b0 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x00000000b3735430, 0x0000000040e342fc }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001bb3fc0c0, 0x00000001d5ad9c3a }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x00000001570ae19c, 0x0000000094a691a4 }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001ea910712, 0x00000001271ecdfa }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x0000000167127128, 0x000000009e54475a }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x0000000019e790a2, 0x00000000c9c099ee }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000003788f710, 0x000000009a2f736c }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000001682a160e, 0x00000000bb9f4996 }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x000000007f0ebd2e, 0x00000001db688050 }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x000000002b032080, 0x00000000e9b10af4 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x00000000cfd1664a, 0x000000012d4545e4 }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x00000000aa1181c2, 0x000000000361139c }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000000ddd08002, 0x00000001a5a1a3a8 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x00000000e8dd0446, 0x000000006844e0b0 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000001bbd94a00, 0x00000000c3762f28 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000000ab6cd180, 0x00000001d26287a2 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x0000000031803ce2, 0x00000001f6f0bba8 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x0000000024f40b0c, 0x000000002ffabd62 }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000001ba1d9834, 0x00000000fb4516b8 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x0000000104de61aa, 0x000000018cfa961c }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x0000000113e40d46, 0x000000019e588d52 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001415598a0, 0x00000001180f0bbc }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000bf6c8c90, 0x00000000e1d9177a }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x00000001788b0504, 0x0000000105abc27c }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x0000000038385d02, 0x00000000972e4a58 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x00000001b6c83844, 0x0000000183499a5e }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x0000000051061a8a, 0x00000001c96a8cca }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x000000017351388a, 0x00000001a1a5b60c }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x0000000132928f92, 0x00000000e4b6ac9c }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000000e6b4f48a, 0x00000001807e7f5a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x0000000039d15e90, 0x000000017a7e3bc8 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000312d6074, 0x00000000d73975da }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017bbb2cc4, 0x000000017375d038 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x000000016ded3e18, 0x00000000193680bc }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000f1638b16, 0x00000000999b06f6 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001d38b9ecc, 0x00000001f685d2b8 }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x000000018b8d09dc, 0x00000001f4ecbed2 }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000e7bc27d2, 0x00000000ba16f1a0 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x00000000275e1e96, 0x0000000115aceac4 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000000e2e3031e, 0x00000001aeff6292 }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x00000001041c84d8, 0x000000009640124c }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x00000000706ce672, 0x0000000114f41f02 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000015d5070da, 0x000000009c5f3586 }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x0000000038f9493a, 0x00000001878275fa }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000a3348a76, 0x00000000ddc42ce8 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x00000001ad0aab92, 0x0000000181d2c73a }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x000000019e85f712, 0x0000000141c9320a }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000005a871e76, 0x000000015235719a }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x000000017249c662, 0x00000000be27d804 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000003a084712, 0x000000006242d45a }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x00000000ed438478, 0x000000009a53638e }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000000abac34cc, 0x00000001001ecfb6 }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000005f35ef3e, 0x000000016d7c2d64 }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x0000000047d6608c, 0x00000001d0ce46c0 }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x000000002d01470e, 0x0000000124c907b4 }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000158bbc7b0, 0x0000000018a555ca }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x00000000c0a23e8e, 0x000000006b0980bc }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x00000001ebd85c88, 0x000000008bbba964 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x000000019ee20bb2, 0x00000001070a5a1e }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x00000001acabf2d6, 0x000000002204322a }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000001b7963d56, 0x00000000a27524d0 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x000000017bffa1fe, 0x0000000020b1e4ba }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x000000001f15333e, 0x0000000032cc27fc }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x000000018593129e, 0x0000000044dd22b8 }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x000000019cb32602, 0x00000000dffc9e0a }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x0000000142b05cc8, 0x00000001b7a0ed14 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000001be49e7a4, 0x00000000c7842488 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x0000000108f69d6c, 0x00000001c02a4fee }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000006c0971f0, 0x000000003c273778 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x000000005b16467a, 0x00000001d63f8894 }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x00000001551a628e, 0x000000006be557d6 }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000019e42ea92, 0x000000006a7806ea }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000012fa83ff2, 0x000000016155aa0c }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x000000011ca9cde0, 0x00000000908650ac }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000c8e5cd74, 0x00000000aa5a8084 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000096c27f0c, 0x0000000191bb500a }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x000000002baed926, 0x0000000064e9bed0 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000017c8de8d2, 0x000000009444f302 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x00000000d43d6068, 0x000000019db07d3c }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000000cb2c4b26, 0x00000001359e3e6e }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x0000000145b8da26, 0x00000001e4f10dd2 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x000000018fff4b08, 0x0000000124f5735e }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000150b58ed0, 0x0000000124760a4c }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x00000001549f39bc, 0x000000000f1fc186 }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000ef4d2f42, 0x00000000150e4cc4 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x00000001b1468572, 0x000000002a6204e8 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x000000013d7403b2, 0x00000000beb1d432 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x00000001a4681842, 0x0000000135f3f1f0 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000167714492, 0x0000000074fe2232 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x00000001e599099a, 0x000000001ac6e2ba }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x00000000fe128194, 0x0000000013fca91e }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000077e8b990, 0x0000000183f4931e }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000001a267f63a, 0x00000000b6d9b4e4 }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000001945c245a, 0x00000000b5188656 }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000149002e76, 0x0000000027a81a84 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x00000001bb8310a4, 0x0000000125699258 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x000000019ec60bcc, 0x00000001b23de796 }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x000000012d8590ae, 0x00000000fe4365dc }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x0000000065b00684, 0x00000000c68f497a }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x000000015e5aeadc, 0x00000000fbf521ee }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x00000000b77ff2b0, 0x000000015eac3378 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000188da2ff6, 0x0000000134914b90 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000063da929a, 0x0000000016335cfe }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x00000001389caa80, 0x000000010372d10c }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000013db599d2, 0x000000015097b908 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x0000000122505a86, 0x00000001227a7572 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000016bd72746, 0x000000009a8f75c0 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000001c3faf1d4, 0x00000000682c77a2 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000001111c826c, 0x00000000231f091c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x00000000153e9fb2, 0x000000007d4439f2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000002b1f7b60, 0x000000017e221efc }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x00000000b1dba570, 0x0000000167457c38 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000001f6397b76, 0x00000000bdf081c4 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x0000000156335214, 0x000000016286d6b0 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000001d70e3986, 0x00000000c84f001c }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x000000003701a774, 0x0000000064efe7c0 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x00000000ac81ef72, 0x000000000ac2d904 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x0000000133212464, 0x00000000fd226d14 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x00000000e4e45610, 0x000000011cfd42e0 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000000c1bd370, 0x000000016e5a5678 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001a7b9e7a6, 0x00000001d888fe22 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x000000007d657a10, 0x00000001af77fcd4 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^261120 mod p(x)` << 1, x^261184 mod p(x)` << 1 */ + { 0x00000001651797d2, 0x0000000099ea94a8 }, + /* x^260096 mod p(x)` << 1, x^260160 mod p(x)` << 1 */ + { 0x0000000021e0d56c, 0x00000000945a8420 }, + /* x^259072 mod p(x)` << 1, x^259136 mod p(x)` << 1 */ + { 0x000000000f95ecaa, 0x0000000030762706 }, + /* x^258048 mod p(x)` << 1, x^258112 mod p(x)` << 1 */ + { 0x00000001ebd224ac, 0x00000001a52fc582 }, + /* x^257024 mod p(x)` << 1, x^257088 mod p(x)` << 1 */ + { 0x000000000ccb97ca, 0x00000001a4a7167a }, + /* x^256000 mod p(x)` << 1, x^256064 mod p(x)` << 1 */ + { 0x00000001006ec8a8, 0x000000000c18249a }, + /* x^254976 mod p(x)` << 1, x^255040 mod p(x)` << 1 */ + { 0x000000014f58f196, 0x00000000a924ae7c }, + /* x^253952 mod p(x)` << 1, x^254016 mod p(x)` << 1 */ + { 0x00000001a7192ca6, 0x00000001e12ccc12 }, + /* x^252928 mod p(x)` << 1, x^252992 mod p(x)` << 1 */ + { 0x000000019a64bab2, 0x00000000a0b9d4ac }, + /* x^251904 mod p(x)` << 1, x^251968 mod p(x)` << 1 */ + { 0x0000000014f4ed2e, 0x0000000095e8ddfe }, + /* x^250880 mod p(x)` << 1, x^250944 mod p(x)` << 1 */ + { 0x000000011092b6a2, 0x00000000233fddc4 }, + /* x^249856 mod p(x)` << 1, x^249920 mod p(x)` << 1 */ + { 0x00000000c8a1629c, 0x00000001b4529b62 }, + /* x^248832 mod p(x)` << 1, x^248896 mod p(x)` << 1 */ + { 0x000000017bf32e8e, 0x00000001a7fa0e64 }, + /* x^247808 mod p(x)` << 1, x^247872 mod p(x)` << 1 */ + { 0x00000001f8cc6582, 0x00000001b5334592 }, + /* x^246784 mod p(x)` << 1, x^246848 mod p(x)` << 1 */ + { 0x000000008631ddf0, 0x000000011f8ee1b4 }, + /* x^245760 mod p(x)` << 1, x^245824 mod p(x)` << 1 */ + { 0x000000007e5a76d0, 0x000000006252e632 }, + /* x^244736 mod p(x)` << 1, x^244800 mod p(x)` << 1 */ + { 0x000000002b09b31c, 0x00000000ab973e84 }, + /* x^243712 mod p(x)` << 1, x^243776 mod p(x)` << 1 */ + { 0x00000001b2df1f84, 0x000000007734f5ec }, + /* x^242688 mod p(x)` << 1, x^242752 mod p(x)` << 1 */ + { 0x00000001d6f56afc, 0x000000007c547798 }, + /* x^241664 mod p(x)` << 1, x^241728 mod p(x)` << 1 */ + { 0x00000001b9b5e70c, 0x000000007ec40210 }, + /* x^240640 mod p(x)` << 1, x^240704 mod p(x)` << 1 */ + { 0x0000000034b626d2, 0x00000001ab1695a8 }, + /* x^239616 mod p(x)` << 1, x^239680 mod p(x)` << 1 */ + { 0x000000014c53479a, 0x0000000090494bba }, + /* x^238592 mod p(x)` << 1, x^238656 mod p(x)` << 1 */ + { 0x00000001a6d179a4, 0x00000001123fb816 }, + /* x^237568 mod p(x)` << 1, x^237632 mod p(x)` << 1 */ + { 0x000000015abd16b4, 0x00000001e188c74c }, + /* x^236544 mod p(x)` << 1, x^236608 mod p(x)` << 1 */ + { 0x00000000018f9852, 0x00000001c2d3451c }, + /* x^235520 mod p(x)` << 1, x^235584 mod p(x)` << 1 */ + { 0x000000001fb3084a, 0x00000000f55cf1ca }, + /* x^234496 mod p(x)` << 1, x^234560 mod p(x)` << 1 */ + { 0x00000000c53dfb04, 0x00000001a0531540 }, + /* x^233472 mod p(x)` << 1, x^233536 mod p(x)` << 1 */ + { 0x00000000e10c9ad6, 0x0000000132cd7ebc }, + /* x^232448 mod p(x)` << 1, x^232512 mod p(x)` << 1 */ + { 0x0000000025aa994a, 0x0000000073ab7f36 }, + /* x^231424 mod p(x)` << 1, x^231488 mod p(x)` << 1 */ + { 0x00000000fa3a74c4, 0x0000000041aed1c2 }, + /* x^230400 mod p(x)` << 1, x^230464 mod p(x)` << 1 */ + { 0x0000000033eb3f40, 0x0000000136c53800 }, + /* x^229376 mod p(x)` << 1, x^229440 mod p(x)` << 1 */ + { 0x000000017193f296, 0x0000000126835a30 }, + /* x^228352 mod p(x)` << 1, x^228416 mod p(x)` << 1 */ + { 0x0000000043f6c86a, 0x000000006241b502 }, + /* x^227328 mod p(x)` << 1, x^227392 mod p(x)` << 1 */ + { 0x000000016b513ec6, 0x00000000d5196ad4 }, + /* x^226304 mod p(x)` << 1, x^226368 mod p(x)` << 1 */ + { 0x00000000c8f25b4e, 0x000000009cfa769a }, + /* x^225280 mod p(x)` << 1, x^225344 mod p(x)` << 1 */ + { 0x00000001a45048ec, 0x00000000920e5df4 }, + /* x^224256 mod p(x)` << 1, x^224320 mod p(x)` << 1 */ + { 0x000000000c441004, 0x0000000169dc310e }, + /* x^223232 mod p(x)` << 1, x^223296 mod p(x)` << 1 */ + { 0x000000000e17cad6, 0x0000000009fc331c }, + /* x^222208 mod p(x)` << 1, x^222272 mod p(x)` << 1 */ + { 0x00000001253ae964, 0x000000010d94a81e }, + /* x^221184 mod p(x)` << 1, x^221248 mod p(x)` << 1 */ + { 0x00000001d7c88ebc, 0x0000000027a20ab2 }, + /* x^220160 mod p(x)` << 1, x^220224 mod p(x)` << 1 */ + { 0x00000001e7ca913a, 0x0000000114f87504 }, + /* x^219136 mod p(x)` << 1, x^219200 mod p(x)` << 1 */ + { 0x0000000033ed078a, 0x000000004b076d96 }, + /* x^218112 mod p(x)` << 1, x^218176 mod p(x)` << 1 */ + { 0x00000000e1839c78, 0x00000000da4d1e74 }, + /* x^217088 mod p(x)` << 1, x^217152 mod p(x)` << 1 */ + { 0x00000001322b267e, 0x000000001b81f672 }, + /* x^216064 mod p(x)` << 1, x^216128 mod p(x)` << 1 */ + { 0x00000000638231b6, 0x000000009367c988 }, + /* x^215040 mod p(x)` << 1, x^215104 mod p(x)` << 1 */ + { 0x00000001ee7f16f4, 0x00000001717214ca }, + /* x^214016 mod p(x)` << 1, x^214080 mod p(x)` << 1 */ + { 0x0000000117d9924a, 0x000000009f47d820 }, + /* x^212992 mod p(x)` << 1, x^213056 mod p(x)` << 1 */ + { 0x00000000e1a9e0c4, 0x000000010d9a47d2 }, + /* x^211968 mod p(x)` << 1, x^212032 mod p(x)` << 1 */ + { 0x00000001403731dc, 0x00000000a696c58c }, + /* x^210944 mod p(x)` << 1, x^211008 mod p(x)` << 1 */ + { 0x00000001a5ea9682, 0x000000002aa28ec6 }, + /* x^209920 mod p(x)` << 1, x^209984 mod p(x)` << 1 */ + { 0x0000000101c5c578, 0x00000001fe18fd9a }, + /* x^208896 mod p(x)` << 1, x^208960 mod p(x)` << 1 */ + { 0x00000000dddf6494, 0x000000019d4fc1ae }, + /* x^207872 mod p(x)` << 1, x^207936 mod p(x)` << 1 */ + { 0x00000000f1c3db28, 0x00000001ba0e3dea }, + /* x^206848 mod p(x)` << 1, x^206912 mod p(x)` << 1 */ + { 0x000000013112fb9c, 0x0000000074b59a5e }, + /* x^205824 mod p(x)` << 1, x^205888 mod p(x)` << 1 */ + { 0x00000000b680b906, 0x00000000f2b5ea98 }, + /* x^204800 mod p(x)` << 1, x^204864 mod p(x)` << 1 */ + { 0x000000001a282932, 0x0000000187132676 }, + /* x^203776 mod p(x)` << 1, x^203840 mod p(x)` << 1 */ + { 0x0000000089406e7e, 0x000000010a8c6ad4 }, + /* x^202752 mod p(x)` << 1, x^202816 mod p(x)` << 1 */ + { 0x00000001def6be8c, 0x00000001e21dfe70 }, + /* x^201728 mod p(x)` << 1, x^201792 mod p(x)` << 1 */ + { 0x0000000075258728, 0x00000001da0050e4 }, + /* x^200704 mod p(x)` << 1, x^200768 mod p(x)` << 1 */ + { 0x000000019536090a, 0x00000000772172ae }, + /* x^199680 mod p(x)` << 1, x^199744 mod p(x)` << 1 */ + { 0x00000000f2455bfc, 0x00000000e47724aa }, + /* x^198656 mod p(x)` << 1, x^198720 mod p(x)` << 1 */ + { 0x000000018c40baf4, 0x000000003cd63ac4 }, + /* x^197632 mod p(x)` << 1, x^197696 mod p(x)` << 1 */ + { 0x000000004cd390d4, 0x00000001bf47d352 }, + /* x^196608 mod p(x)` << 1, x^196672 mod p(x)` << 1 */ + { 0x00000001e4ece95a, 0x000000018dc1d708 }, + /* x^195584 mod p(x)` << 1, x^195648 mod p(x)` << 1 */ + { 0x000000001a3ee918, 0x000000002d4620a4 }, + /* x^194560 mod p(x)` << 1, x^194624 mod p(x)` << 1 */ + { 0x000000007c652fb8, 0x0000000058fd1740 }, + /* x^193536 mod p(x)` << 1, x^193600 mod p(x)` << 1 */ + { 0x000000011c67842c, 0x00000000dadd9bfc }, + /* x^192512 mod p(x)` << 1, x^192576 mod p(x)` << 1 */ + { 0x00000000254f759c, 0x00000001ea2140be }, + /* x^191488 mod p(x)` << 1, x^191552 mod p(x)` << 1 */ + { 0x000000007ece94ca, 0x000000009de128ba }, + /* x^190464 mod p(x)` << 1, x^190528 mod p(x)` << 1 */ + { 0x0000000038f258c2, 0x000000013ac3aa8e }, + /* x^189440 mod p(x)` << 1, x^189504 mod p(x)` << 1 */ + { 0x00000001cdf17b00, 0x0000000099980562 }, + /* x^188416 mod p(x)` << 1, x^188480 mod p(x)` << 1 */ + { 0x000000011f882c16, 0x00000001c1579c86 }, + /* x^187392 mod p(x)` << 1, x^187456 mod p(x)` << 1 */ + { 0x0000000100093fc8, 0x0000000068dbbf94 }, + /* x^186368 mod p(x)` << 1, x^186432 mod p(x)` << 1 */ + { 0x00000001cd684f16, 0x000000004509fb04 }, + /* x^185344 mod p(x)` << 1, x^185408 mod p(x)` << 1 */ + { 0x000000004bc6a70a, 0x00000001202f6398 }, + /* x^184320 mod p(x)` << 1, x^184384 mod p(x)` << 1 */ + { 0x000000004fc7e8e4, 0x000000013aea243e }, + /* x^183296 mod p(x)` << 1, x^183360 mod p(x)` << 1 */ + { 0x0000000130103f1c, 0x00000001b4052ae6 }, + /* x^182272 mod p(x)` << 1, x^182336 mod p(x)` << 1 */ + { 0x0000000111b0024c, 0x00000001cd2a0ae8 }, + /* x^181248 mod p(x)` << 1, x^181312 mod p(x)` << 1 */ + { 0x000000010b3079da, 0x00000001fe4aa8b4 }, + /* x^180224 mod p(x)` << 1, x^180288 mod p(x)` << 1 */ + { 0x000000010192bcc2, 0x00000001d1559a42 }, + /* x^179200 mod p(x)` << 1, x^179264 mod p(x)` << 1 */ + { 0x0000000074838d50, 0x00000001f3e05ecc }, + /* x^178176 mod p(x)` << 1, x^178240 mod p(x)` << 1 */ + { 0x000000001b20f520, 0x0000000104ddd2cc }, + /* x^177152 mod p(x)` << 1, x^177216 mod p(x)` << 1 */ + { 0x0000000050c3590a, 0x000000015393153c }, + /* x^176128 mod p(x)` << 1, x^176192 mod p(x)` << 1 */ + { 0x00000000b41cac8e, 0x0000000057e942c6 }, + /* x^175104 mod p(x)` << 1, x^175168 mod p(x)` << 1 */ + { 0x000000000c72cc78, 0x000000012c633850 }, + /* x^174080 mod p(x)` << 1, x^174144 mod p(x)` << 1 */ + { 0x0000000030cdb032, 0x00000000ebcaae4c }, + /* x^173056 mod p(x)` << 1, x^173120 mod p(x)` << 1 */ + { 0x000000013e09fc32, 0x000000013ee532a6 }, + /* x^172032 mod p(x)` << 1, x^172096 mod p(x)` << 1 */ + { 0x000000001ed624d2, 0x00000001bf0cbc7e }, + /* x^171008 mod p(x)` << 1, x^171072 mod p(x)` << 1 */ + { 0x00000000781aee1a, 0x00000000d50b7a5a }, + /* x^169984 mod p(x)` << 1, x^170048 mod p(x)` << 1 */ + { 0x00000001c4d8348c, 0x0000000002fca6e8 }, + /* x^168960 mod p(x)` << 1, x^169024 mod p(x)` << 1 */ + { 0x0000000057a40336, 0x000000007af40044 }, + /* x^167936 mod p(x)` << 1, x^168000 mod p(x)` << 1 */ + { 0x0000000085544940, 0x0000000016178744 }, + /* x^166912 mod p(x)` << 1, x^166976 mod p(x)` << 1 */ + { 0x000000019cd21e80, 0x000000014c177458 }, + /* x^165888 mod p(x)` << 1, x^165952 mod p(x)` << 1 */ + { 0x000000013eb95bc0, 0x000000011b6ddf04 }, + /* x^164864 mod p(x)` << 1, x^164928 mod p(x)` << 1 */ + { 0x00000001dfc9fdfc, 0x00000001f3e29ccc }, + /* x^163840 mod p(x)` << 1, x^163904 mod p(x)` << 1 */ + { 0x00000000cd028bc2, 0x0000000135ae7562 }, + /* x^162816 mod p(x)` << 1, x^162880 mod p(x)` << 1 */ + { 0x0000000090db8c44, 0x0000000190ef812c }, + /* x^161792 mod p(x)` << 1, x^161856 mod p(x)` << 1 */ + { 0x000000010010a4ce, 0x0000000067a2c786 }, + /* x^160768 mod p(x)` << 1, x^160832 mod p(x)` << 1 */ + { 0x00000001c8f4c72c, 0x0000000048b9496c }, + /* x^159744 mod p(x)` << 1, x^159808 mod p(x)` << 1 */ + { 0x000000001c26170c, 0x000000015a422de6 }, + /* x^158720 mod p(x)` << 1, x^158784 mod p(x)` << 1 */ + { 0x00000000e3fccf68, 0x00000001ef0e3640 }, + /* x^157696 mod p(x)` << 1, x^157760 mod p(x)` << 1 */ + { 0x00000000d513ed24, 0x00000001006d2d26 }, + /* x^156672 mod p(x)` << 1, x^156736 mod p(x)` << 1 */ + { 0x00000000141beada, 0x00000001170d56d6 }, + /* x^155648 mod p(x)` << 1, x^155712 mod p(x)` << 1 */ + { 0x000000011071aea0, 0x00000000a5fb613c }, + /* x^154624 mod p(x)` << 1, x^154688 mod p(x)` << 1 */ + { 0x000000012e19080a, 0x0000000040bbf7fc }, + /* x^153600 mod p(x)` << 1, x^153664 mod p(x)` << 1 */ + { 0x0000000100ecf826, 0x000000016ac3a5b2 }, + /* x^152576 mod p(x)` << 1, x^152640 mod p(x)` << 1 */ + { 0x0000000069b09412, 0x00000000abf16230 }, + /* x^151552 mod p(x)` << 1, x^151616 mod p(x)` << 1 */ + { 0x0000000122297bac, 0x00000001ebe23fac }, + /* x^150528 mod p(x)` << 1, x^150592 mod p(x)` << 1 */ + { 0x00000000e9e4b068, 0x000000008b6a0894 }, + /* x^149504 mod p(x)` << 1, x^149568 mod p(x)` << 1 */ + { 0x000000004b38651a, 0x00000001288ea478 }, + /* x^148480 mod p(x)` << 1, x^148544 mod p(x)` << 1 */ + { 0x00000001468360e2, 0x000000016619c442 }, + /* x^147456 mod p(x)` << 1, x^147520 mod p(x)` << 1 */ + { 0x00000000121c2408, 0x0000000086230038 }, + /* x^146432 mod p(x)` << 1, x^146496 mod p(x)` << 1 */ + { 0x00000000da7e7d08, 0x000000017746a756 }, + /* x^145408 mod p(x)` << 1, x^145472 mod p(x)` << 1 */ + { 0x00000001058d7652, 0x0000000191b8f8f8 }, + /* x^144384 mod p(x)` << 1, x^144448 mod p(x)` << 1 */ + { 0x000000014a098a90, 0x000000008e167708 }, + /* x^143360 mod p(x)` << 1, x^143424 mod p(x)` << 1 */ + { 0x0000000020dbe72e, 0x0000000148b22d54 }, + /* x^142336 mod p(x)` << 1, x^142400 mod p(x)` << 1 */ + { 0x000000011e7323e8, 0x0000000044ba2c3c }, + /* x^141312 mod p(x)` << 1, x^141376 mod p(x)` << 1 */ + { 0x00000000d5d4bf94, 0x00000000b54d2b52 }, + /* x^140288 mod p(x)` << 1, x^140352 mod p(x)` << 1 */ + { 0x0000000199d8746c, 0x0000000005a4fd8a }, + /* x^139264 mod p(x)` << 1, x^139328 mod p(x)` << 1 */ + { 0x00000000ce9ca8a0, 0x0000000139f9fc46 }, + /* x^138240 mod p(x)` << 1, x^138304 mod p(x)` << 1 */ + { 0x00000000136edece, 0x000000015a1fa824 }, + /* x^137216 mod p(x)` << 1, x^137280 mod p(x)` << 1 */ + { 0x000000019b92a068, 0x000000000a61ae4c }, + /* x^136192 mod p(x)` << 1, x^136256 mod p(x)` << 1 */ + { 0x0000000071d62206, 0x0000000145e9113e }, + /* x^135168 mod p(x)` << 1, x^135232 mod p(x)` << 1 */ + { 0x00000000dfc50158, 0x000000006a348448 }, + /* x^134144 mod p(x)` << 1, x^134208 mod p(x)` << 1 */ + { 0x00000001517626bc, 0x000000004d80a08c }, + /* x^133120 mod p(x)` << 1, x^133184 mod p(x)` << 1 */ + { 0x0000000148d1e4fa, 0x000000014b6837a0 }, + /* x^132096 mod p(x)` << 1, x^132160 mod p(x)` << 1 */ + { 0x0000000094d8266e, 0x000000016896a7fc }, + /* x^131072 mod p(x)` << 1, x^131136 mod p(x)` << 1 */ + { 0x00000000606c5e34, 0x000000014f187140 }, + /* x^130048 mod p(x)` << 1, x^130112 mod p(x)` << 1 */ + { 0x000000019766beaa, 0x000000019581b9da }, + /* x^129024 mod p(x)` << 1, x^129088 mod p(x)` << 1 */ + { 0x00000001d80c506c, 0x00000001091bc984 }, + /* x^128000 mod p(x)` << 1, x^128064 mod p(x)` << 1 */ + { 0x000000001e73837c, 0x000000001067223c }, + /* x^126976 mod p(x)` << 1, x^127040 mod p(x)` << 1 */ + { 0x0000000064d587de, 0x00000001ab16ea02 }, + /* x^125952 mod p(x)` << 1, x^126016 mod p(x)` << 1 */ + { 0x00000000f4a507b0, 0x000000013c4598a8 }, + /* x^124928 mod p(x)` << 1, x^124992 mod p(x)` << 1 */ + { 0x0000000040e342fc, 0x00000000b3735430 }, + /* x^123904 mod p(x)` << 1, x^123968 mod p(x)` << 1 */ + { 0x00000001d5ad9c3a, 0x00000001bb3fc0c0 }, + /* x^122880 mod p(x)` << 1, x^122944 mod p(x)` << 1 */ + { 0x0000000094a691a4, 0x00000001570ae19c }, + /* x^121856 mod p(x)` << 1, x^121920 mod p(x)` << 1 */ + { 0x00000001271ecdfa, 0x00000001ea910712 }, + /* x^120832 mod p(x)` << 1, x^120896 mod p(x)` << 1 */ + { 0x000000009e54475a, 0x0000000167127128 }, + /* x^119808 mod p(x)` << 1, x^119872 mod p(x)` << 1 */ + { 0x00000000c9c099ee, 0x0000000019e790a2 }, + /* x^118784 mod p(x)` << 1, x^118848 mod p(x)` << 1 */ + { 0x000000009a2f736c, 0x000000003788f710 }, + /* x^117760 mod p(x)` << 1, x^117824 mod p(x)` << 1 */ + { 0x00000000bb9f4996, 0x00000001682a160e }, + /* x^116736 mod p(x)` << 1, x^116800 mod p(x)` << 1 */ + { 0x00000001db688050, 0x000000007f0ebd2e }, + /* x^115712 mod p(x)` << 1, x^115776 mod p(x)` << 1 */ + { 0x00000000e9b10af4, 0x000000002b032080 }, + /* x^114688 mod p(x)` << 1, x^114752 mod p(x)` << 1 */ + { 0x000000012d4545e4, 0x00000000cfd1664a }, + /* x^113664 mod p(x)` << 1, x^113728 mod p(x)` << 1 */ + { 0x000000000361139c, 0x00000000aa1181c2 }, + /* x^112640 mod p(x)` << 1, x^112704 mod p(x)` << 1 */ + { 0x00000001a5a1a3a8, 0x00000000ddd08002 }, + /* x^111616 mod p(x)` << 1, x^111680 mod p(x)` << 1 */ + { 0x000000006844e0b0, 0x00000000e8dd0446 }, + /* x^110592 mod p(x)` << 1, x^110656 mod p(x)` << 1 */ + { 0x00000000c3762f28, 0x00000001bbd94a00 }, + /* x^109568 mod p(x)` << 1, x^109632 mod p(x)` << 1 */ + { 0x00000001d26287a2, 0x00000000ab6cd180 }, + /* x^108544 mod p(x)` << 1, x^108608 mod p(x)` << 1 */ + { 0x00000001f6f0bba8, 0x0000000031803ce2 }, + /* x^107520 mod p(x)` << 1, x^107584 mod p(x)` << 1 */ + { 0x000000002ffabd62, 0x0000000024f40b0c }, + /* x^106496 mod p(x)` << 1, x^106560 mod p(x)` << 1 */ + { 0x00000000fb4516b8, 0x00000001ba1d9834 }, + /* x^105472 mod p(x)` << 1, x^105536 mod p(x)` << 1 */ + { 0x000000018cfa961c, 0x0000000104de61aa }, + /* x^104448 mod p(x)` << 1, x^104512 mod p(x)` << 1 */ + { 0x000000019e588d52, 0x0000000113e40d46 }, + /* x^103424 mod p(x)` << 1, x^103488 mod p(x)` << 1 */ + { 0x00000001180f0bbc, 0x00000001415598a0 }, + /* x^102400 mod p(x)` << 1, x^102464 mod p(x)` << 1 */ + { 0x00000000e1d9177a, 0x00000000bf6c8c90 }, + /* x^101376 mod p(x)` << 1, x^101440 mod p(x)` << 1 */ + { 0x0000000105abc27c, 0x00000001788b0504 }, + /* x^100352 mod p(x)` << 1, x^100416 mod p(x)` << 1 */ + { 0x00000000972e4a58, 0x0000000038385d02 }, + /* x^99328 mod p(x)` << 1, x^99392 mod p(x)` << 1 */ + { 0x0000000183499a5e, 0x00000001b6c83844 }, + /* x^98304 mod p(x)` << 1, x^98368 mod p(x)` << 1 */ + { 0x00000001c96a8cca, 0x0000000051061a8a }, + /* x^97280 mod p(x)` << 1, x^97344 mod p(x)` << 1 */ + { 0x00000001a1a5b60c, 0x000000017351388a }, + /* x^96256 mod p(x)` << 1, x^96320 mod p(x)` << 1 */ + { 0x00000000e4b6ac9c, 0x0000000132928f92 }, + /* x^95232 mod p(x)` << 1, x^95296 mod p(x)` << 1 */ + { 0x00000001807e7f5a, 0x00000000e6b4f48a }, + /* x^94208 mod p(x)` << 1, x^94272 mod p(x)` << 1 */ + { 0x000000017a7e3bc8, 0x0000000039d15e90 }, + /* x^93184 mod p(x)` << 1, x^93248 mod p(x)` << 1 */ + { 0x00000000d73975da, 0x00000000312d6074 }, + /* x^92160 mod p(x)` << 1, x^92224 mod p(x)` << 1 */ + { 0x000000017375d038, 0x000000017bbb2cc4 }, + /* x^91136 mod p(x)` << 1, x^91200 mod p(x)` << 1 */ + { 0x00000000193680bc, 0x000000016ded3e18 }, + /* x^90112 mod p(x)` << 1, x^90176 mod p(x)` << 1 */ + { 0x00000000999b06f6, 0x00000000f1638b16 }, + /* x^89088 mod p(x)` << 1, x^89152 mod p(x)` << 1 */ + { 0x00000001f685d2b8, 0x00000001d38b9ecc }, + /* x^88064 mod p(x)` << 1, x^88128 mod p(x)` << 1 */ + { 0x00000001f4ecbed2, 0x000000018b8d09dc }, + /* x^87040 mod p(x)` << 1, x^87104 mod p(x)` << 1 */ + { 0x00000000ba16f1a0, 0x00000000e7bc27d2 }, + /* x^86016 mod p(x)` << 1, x^86080 mod p(x)` << 1 */ + { 0x0000000115aceac4, 0x00000000275e1e96 }, + /* x^84992 mod p(x)` << 1, x^85056 mod p(x)` << 1 */ + { 0x00000001aeff6292, 0x00000000e2e3031e }, + /* x^83968 mod p(x)` << 1, x^84032 mod p(x)` << 1 */ + { 0x000000009640124c, 0x00000001041c84d8 }, + /* x^82944 mod p(x)` << 1, x^83008 mod p(x)` << 1 */ + { 0x0000000114f41f02, 0x00000000706ce672 }, + /* x^81920 mod p(x)` << 1, x^81984 mod p(x)` << 1 */ + { 0x000000009c5f3586, 0x000000015d5070da }, + /* x^80896 mod p(x)` << 1, x^80960 mod p(x)` << 1 */ + { 0x00000001878275fa, 0x0000000038f9493a }, + /* x^79872 mod p(x)` << 1, x^79936 mod p(x)` << 1 */ + { 0x00000000ddc42ce8, 0x00000000a3348a76 }, + /* x^78848 mod p(x)` << 1, x^78912 mod p(x)` << 1 */ + { 0x0000000181d2c73a, 0x00000001ad0aab92 }, + /* x^77824 mod p(x)` << 1, x^77888 mod p(x)` << 1 */ + { 0x0000000141c9320a, 0x000000019e85f712 }, + /* x^76800 mod p(x)` << 1, x^76864 mod p(x)` << 1 */ + { 0x000000015235719a, 0x000000005a871e76 }, + /* x^75776 mod p(x)` << 1, x^75840 mod p(x)` << 1 */ + { 0x00000000be27d804, 0x000000017249c662 }, + /* x^74752 mod p(x)` << 1, x^74816 mod p(x)` << 1 */ + { 0x000000006242d45a, 0x000000003a084712 }, + /* x^73728 mod p(x)` << 1, x^73792 mod p(x)` << 1 */ + { 0x000000009a53638e, 0x00000000ed438478 }, + /* x^72704 mod p(x)` << 1, x^72768 mod p(x)` << 1 */ + { 0x00000001001ecfb6, 0x00000000abac34cc }, + /* x^71680 mod p(x)` << 1, x^71744 mod p(x)` << 1 */ + { 0x000000016d7c2d64, 0x000000005f35ef3e }, + /* x^70656 mod p(x)` << 1, x^70720 mod p(x)` << 1 */ + { 0x00000001d0ce46c0, 0x0000000047d6608c }, + /* x^69632 mod p(x)` << 1, x^69696 mod p(x)` << 1 */ + { 0x0000000124c907b4, 0x000000002d01470e }, + /* x^68608 mod p(x)` << 1, x^68672 mod p(x)` << 1 */ + { 0x0000000018a555ca, 0x0000000158bbc7b0 }, + /* x^67584 mod p(x)` << 1, x^67648 mod p(x)` << 1 */ + { 0x000000006b0980bc, 0x00000000c0a23e8e }, + /* x^66560 mod p(x)` << 1, x^66624 mod p(x)` << 1 */ + { 0x000000008bbba964, 0x00000001ebd85c88 }, + /* x^65536 mod p(x)` << 1, x^65600 mod p(x)` << 1 */ + { 0x00000001070a5a1e, 0x000000019ee20bb2 }, + /* x^64512 mod p(x)` << 1, x^64576 mod p(x)` << 1 */ + { 0x000000002204322a, 0x00000001acabf2d6 }, + /* x^63488 mod p(x)` << 1, x^63552 mod p(x)` << 1 */ + { 0x00000000a27524d0, 0x00000001b7963d56 }, + /* x^62464 mod p(x)` << 1, x^62528 mod p(x)` << 1 */ + { 0x0000000020b1e4ba, 0x000000017bffa1fe }, + /* x^61440 mod p(x)` << 1, x^61504 mod p(x)` << 1 */ + { 0x0000000032cc27fc, 0x000000001f15333e }, + /* x^60416 mod p(x)` << 1, x^60480 mod p(x)` << 1 */ + { 0x0000000044dd22b8, 0x000000018593129e }, + /* x^59392 mod p(x)` << 1, x^59456 mod p(x)` << 1 */ + { 0x00000000dffc9e0a, 0x000000019cb32602 }, + /* x^58368 mod p(x)` << 1, x^58432 mod p(x)` << 1 */ + { 0x00000001b7a0ed14, 0x0000000142b05cc8 }, + /* x^57344 mod p(x)` << 1, x^57408 mod p(x)` << 1 */ + { 0x00000000c7842488, 0x00000001be49e7a4 }, + /* x^56320 mod p(x)` << 1, x^56384 mod p(x)` << 1 */ + { 0x00000001c02a4fee, 0x0000000108f69d6c }, + /* x^55296 mod p(x)` << 1, x^55360 mod p(x)` << 1 */ + { 0x000000003c273778, 0x000000006c0971f0 }, + /* x^54272 mod p(x)` << 1, x^54336 mod p(x)` << 1 */ + { 0x00000001d63f8894, 0x000000005b16467a }, + /* x^53248 mod p(x)` << 1, x^53312 mod p(x)` << 1 */ + { 0x000000006be557d6, 0x00000001551a628e }, + /* x^52224 mod p(x)` << 1, x^52288 mod p(x)` << 1 */ + { 0x000000006a7806ea, 0x000000019e42ea92 }, + /* x^51200 mod p(x)` << 1, x^51264 mod p(x)` << 1 */ + { 0x000000016155aa0c, 0x000000012fa83ff2 }, + /* x^50176 mod p(x)` << 1, x^50240 mod p(x)` << 1 */ + { 0x00000000908650ac, 0x000000011ca9cde0 }, + /* x^49152 mod p(x)` << 1, x^49216 mod p(x)` << 1 */ + { 0x00000000aa5a8084, 0x00000000c8e5cd74 }, + /* x^48128 mod p(x)` << 1, x^48192 mod p(x)` << 1 */ + { 0x0000000191bb500a, 0x0000000096c27f0c }, + /* x^47104 mod p(x)` << 1, x^47168 mod p(x)` << 1 */ + { 0x0000000064e9bed0, 0x000000002baed926 }, + /* x^46080 mod p(x)` << 1, x^46144 mod p(x)` << 1 */ + { 0x000000009444f302, 0x000000017c8de8d2 }, + /* x^45056 mod p(x)` << 1, x^45120 mod p(x)` << 1 */ + { 0x000000019db07d3c, 0x00000000d43d6068 }, + /* x^44032 mod p(x)` << 1, x^44096 mod p(x)` << 1 */ + { 0x00000001359e3e6e, 0x00000000cb2c4b26 }, + /* x^43008 mod p(x)` << 1, x^43072 mod p(x)` << 1 */ + { 0x00000001e4f10dd2, 0x0000000145b8da26 }, + /* x^41984 mod p(x)` << 1, x^42048 mod p(x)` << 1 */ + { 0x0000000124f5735e, 0x000000018fff4b08 }, + /* x^40960 mod p(x)` << 1, x^41024 mod p(x)` << 1 */ + { 0x0000000124760a4c, 0x0000000150b58ed0 }, + /* x^39936 mod p(x)` << 1, x^40000 mod p(x)` << 1 */ + { 0x000000000f1fc186, 0x00000001549f39bc }, + /* x^38912 mod p(x)` << 1, x^38976 mod p(x)` << 1 */ + { 0x00000000150e4cc4, 0x00000000ef4d2f42 }, + /* x^37888 mod p(x)` << 1, x^37952 mod p(x)` << 1 */ + { 0x000000002a6204e8, 0x00000001b1468572 }, + /* x^36864 mod p(x)` << 1, x^36928 mod p(x)` << 1 */ + { 0x00000000beb1d432, 0x000000013d7403b2 }, + /* x^35840 mod p(x)` << 1, x^35904 mod p(x)` << 1 */ + { 0x0000000135f3f1f0, 0x00000001a4681842 }, + /* x^34816 mod p(x)` << 1, x^34880 mod p(x)` << 1 */ + { 0x0000000074fe2232, 0x0000000167714492 }, + /* x^33792 mod p(x)` << 1, x^33856 mod p(x)` << 1 */ + { 0x000000001ac6e2ba, 0x00000001e599099a }, + /* x^32768 mod p(x)` << 1, x^32832 mod p(x)` << 1 */ + { 0x0000000013fca91e, 0x00000000fe128194 }, + /* x^31744 mod p(x)` << 1, x^31808 mod p(x)` << 1 */ + { 0x0000000183f4931e, 0x0000000077e8b990 }, + /* x^30720 mod p(x)` << 1, x^30784 mod p(x)` << 1 */ + { 0x00000000b6d9b4e4, 0x00000001a267f63a }, + /* x^29696 mod p(x)` << 1, x^29760 mod p(x)` << 1 */ + { 0x00000000b5188656, 0x00000001945c245a }, + /* x^28672 mod p(x)` << 1, x^28736 mod p(x)` << 1 */ + { 0x0000000027a81a84, 0x0000000149002e76 }, + /* x^27648 mod p(x)` << 1, x^27712 mod p(x)` << 1 */ + { 0x0000000125699258, 0x00000001bb8310a4 }, + /* x^26624 mod p(x)` << 1, x^26688 mod p(x)` << 1 */ + { 0x00000001b23de796, 0x000000019ec60bcc }, + /* x^25600 mod p(x)` << 1, x^25664 mod p(x)` << 1 */ + { 0x00000000fe4365dc, 0x000000012d8590ae }, + /* x^24576 mod p(x)` << 1, x^24640 mod p(x)` << 1 */ + { 0x00000000c68f497a, 0x0000000065b00684 }, + /* x^23552 mod p(x)` << 1, x^23616 mod p(x)` << 1 */ + { 0x00000000fbf521ee, 0x000000015e5aeadc }, + /* x^22528 mod p(x)` << 1, x^22592 mod p(x)` << 1 */ + { 0x000000015eac3378, 0x00000000b77ff2b0 }, + /* x^21504 mod p(x)` << 1, x^21568 mod p(x)` << 1 */ + { 0x0000000134914b90, 0x0000000188da2ff6 }, + /* x^20480 mod p(x)` << 1, x^20544 mod p(x)` << 1 */ + { 0x0000000016335cfe, 0x0000000063da929a }, + /* x^19456 mod p(x)` << 1, x^19520 mod p(x)` << 1 */ + { 0x000000010372d10c, 0x00000001389caa80 }, + /* x^18432 mod p(x)` << 1, x^18496 mod p(x)` << 1 */ + { 0x000000015097b908, 0x000000013db599d2 }, + /* x^17408 mod p(x)` << 1, x^17472 mod p(x)` << 1 */ + { 0x00000001227a7572, 0x0000000122505a86 }, + /* x^16384 mod p(x)` << 1, x^16448 mod p(x)` << 1 */ + { 0x000000009a8f75c0, 0x000000016bd72746 }, + /* x^15360 mod p(x)` << 1, x^15424 mod p(x)` << 1 */ + { 0x00000000682c77a2, 0x00000001c3faf1d4 }, + /* x^14336 mod p(x)` << 1, x^14400 mod p(x)` << 1 */ + { 0x00000000231f091c, 0x00000001111c826c }, + /* x^13312 mod p(x)` << 1, x^13376 mod p(x)` << 1 */ + { 0x000000007d4439f2, 0x00000000153e9fb2 }, + /* x^12288 mod p(x)` << 1, x^12352 mod p(x)` << 1 */ + { 0x000000017e221efc, 0x000000002b1f7b60 }, + /* x^11264 mod p(x)` << 1, x^11328 mod p(x)` << 1 */ + { 0x0000000167457c38, 0x00000000b1dba570 }, + /* x^10240 mod p(x)` << 1, x^10304 mod p(x)` << 1 */ + { 0x00000000bdf081c4, 0x00000001f6397b76 }, + /* x^9216 mod p(x)` << 1, x^9280 mod p(x)` << 1 */ + { 0x000000016286d6b0, 0x0000000156335214 }, + /* x^8192 mod p(x)` << 1, x^8256 mod p(x)` << 1 */ + { 0x00000000c84f001c, 0x00000001d70e3986 }, + /* x^7168 mod p(x)` << 1, x^7232 mod p(x)` << 1 */ + { 0x0000000064efe7c0, 0x000000003701a774 }, + /* x^6144 mod p(x)` << 1, x^6208 mod p(x)` << 1 */ + { 0x000000000ac2d904, 0x00000000ac81ef72 }, + /* x^5120 mod p(x)` << 1, x^5184 mod p(x)` << 1 */ + { 0x00000000fd226d14, 0x0000000133212464 }, + /* x^4096 mod p(x)` << 1, x^4160 mod p(x)` << 1 */ + { 0x000000011cfd42e0, 0x00000000e4e45610 }, + /* x^3072 mod p(x)` << 1, x^3136 mod p(x)` << 1 */ + { 0x000000016e5a5678, 0x000000000c1bd370 }, + /* x^2048 mod p(x)` << 1, x^2112 mod p(x)` << 1 */ + { 0x00000001d888fe22, 0x00000001a7b9e7a6 }, + /* x^1024 mod p(x)` << 1, x^1088 mod p(x)` << 1 */ + { 0x00000001af77fcd4, 0x000000007d657a10 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Reduce final 1024-2048 bits to 64 bits, shifting 32 bits to include the trailing 32 bits of zeros */ + +static const __vector unsigned long long vcrc_short_const[16] ALIGNED_(16) = { +#if BYTE_ORDER == LITTLE_ENDIAN + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0x99168a18ec447f11, 0xed837b2613e8221e }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xe23e954e8fd2cd3c, 0xc8acdd8147b9ce5a }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0x92f8befe6b1d2b53, 0xd9ad6d87d4277e25 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xf38a3556291ea462, 0xc10ec5e033fbca3b }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0x974ac56262b6ca4b, 0xc0b55b0e82e02e2f }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x855712b3784d2a56, 0x71aa1df0e172334d }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xa5abe9f80eaee722, 0xfee3053e3969324d }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0x1fa0943ddb54814c, 0xf44779b93eb2bd08 }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xa53ff440d7bbfe6a, 0xf5449b3f00cc3374 }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0xebe7e3566325605c, 0x6f8346e1d777606e }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xc65a272ce5b592b8, 0xe3ab4f2ac0b95347 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0x5705a9ca4721589f, 0xaa2215ea329ecc11 }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0xe3720acb88d14467, 0x1ed8f66ed95efd26 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0xba1aca0315141c31, 0x78ed02d5a700e96a }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xad2a31b3ed627dae, 0xba8ccbe832b39da3 }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0x6655004fa06a2517, 0xedb88320b1e6b092 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + /* x^1952 mod p(x) , x^1984 mod p(x) , x^2016 mod p(x) , x^2048 mod p(x) */ + { 0xed837b2613e8221e, 0x99168a18ec447f11 }, + /* x^1824 mod p(x) , x^1856 mod p(x) , x^1888 mod p(x) , x^1920 mod p(x) */ + { 0xc8acdd8147b9ce5a, 0xe23e954e8fd2cd3c }, + /* x^1696 mod p(x) , x^1728 mod p(x) , x^1760 mod p(x) , x^1792 mod p(x) */ + { 0xd9ad6d87d4277e25, 0x92f8befe6b1d2b53 }, + /* x^1568 mod p(x) , x^1600 mod p(x) , x^1632 mod p(x) , x^1664 mod p(x) */ + { 0xc10ec5e033fbca3b, 0xf38a3556291ea462 }, + /* x^1440 mod p(x) , x^1472 mod p(x) , x^1504 mod p(x) , x^1536 mod p(x) */ + { 0xc0b55b0e82e02e2f, 0x974ac56262b6ca4b }, + /* x^1312 mod p(x) , x^1344 mod p(x) , x^1376 mod p(x) , x^1408 mod p(x) */ + { 0x71aa1df0e172334d, 0x855712b3784d2a56 }, + /* x^1184 mod p(x) , x^1216 mod p(x) , x^1248 mod p(x) , x^1280 mod p(x) */ + { 0xfee3053e3969324d, 0xa5abe9f80eaee722 }, + /* x^1056 mod p(x) , x^1088 mod p(x) , x^1120 mod p(x) , x^1152 mod p(x) */ + { 0xf44779b93eb2bd08, 0x1fa0943ddb54814c }, + /* x^928 mod p(x) , x^960 mod p(x) , x^992 mod p(x) , x^1024 mod p(x) */ + { 0xf5449b3f00cc3374, 0xa53ff440d7bbfe6a }, + /* x^800 mod p(x) , x^832 mod p(x) , x^864 mod p(x) , x^896 mod p(x) */ + { 0x6f8346e1d777606e, 0xebe7e3566325605c }, + /* x^672 mod p(x) , x^704 mod p(x) , x^736 mod p(x) , x^768 mod p(x) */ + { 0xe3ab4f2ac0b95347, 0xc65a272ce5b592b8 }, + /* x^544 mod p(x) , x^576 mod p(x) , x^608 mod p(x) , x^640 mod p(x) */ + { 0xaa2215ea329ecc11, 0x5705a9ca4721589f }, + /* x^416 mod p(x) , x^448 mod p(x) , x^480 mod p(x) , x^512 mod p(x) */ + { 0x1ed8f66ed95efd26, 0xe3720acb88d14467 }, + /* x^288 mod p(x) , x^320 mod p(x) , x^352 mod p(x) , x^384 mod p(x) */ + { 0x78ed02d5a700e96a, 0xba1aca0315141c31 }, + /* x^160 mod p(x) , x^192 mod p(x) , x^224 mod p(x) , x^256 mod p(x) */ + { 0xba8ccbe832b39da3, 0xad2a31b3ed627dae }, + /* x^32 mod p(x) , x^64 mod p(x) , x^96 mod p(x) , x^128 mod p(x) */ + { 0xedb88320b1e6b092, 0x6655004fa06a2517 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; + +/* Barrett constants */ +/* 33 bit reflected Barrett constant m - (4^32)/n */ + +static const __vector unsigned long long v_Barrett_const[2] ALIGNED_(16) = { + /* x^64 div p(x) */ +#if BYTE_ORDER == LITTLE_ENDIAN + { 0x00000001f7011641, 0x0000000000000000 }, + { 0x00000001db710641, 0x0000000000000000 } +#else /* BYTE_ORDER == LITTLE_ENDIAN */ + { 0x0000000000000000, 0x00000001f7011641 }, + { 0x0000000000000000, 0x00000001db710641 } +#endif /* BYTE_ORDER == LITTLE_ENDIAN */ +}; diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_power8.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_power8.c new file mode 100644 index 000000000..1cb5f299f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/crc32_power8.c @@ -0,0 +1,589 @@ +/* crc32 for POWER8 using VSX instructions + * Copyright (C) 2021 IBM Corporation + * + * Author: Rogerio Alves + * + * For conditions of distribution and use, see copyright notice in zlib.h + * + * Calculate the checksum of data that is 16 byte aligned and a multiple of + * 16 bytes. + * + * The first step is to reduce it to 1024 bits. We do this in 8 parallel + * chunks in order to mask the latency of the vpmsum instructions. If we + * have more than 32 kB of data to checksum we repeat this step multiple + * times, passing in the previous 1024 bits. + * + * The next step is to reduce the 1024 bits to 64 bits. This step adds + * 32 bits of 0s to the end - this matches what a CRC does. We just + * calculate constants that land the data in this 32 bits. + * + * We then use fixed point Barrett reduction to compute a mod n over GF(2) + * for n = CRC using POWER8 instructions. We use x = 32. + * + * http://en.wikipedia.org/wiki/Barrett_reduction + * + * This code uses gcc vector builtins instead using assembly directly. + */ + +#include +#include "zendian.h" +#include "zbuild.h" + +#include "crc32_constants.h" +#include "crc32_braid_tbl.h" + +#if defined (__clang__) +#include "fallback_builtins.h" +#endif + +#define MAX_SIZE 32768 +#define VMX_ALIGN 16 +#define VMX_ALIGN_MASK (VMX_ALIGN-1) + +static unsigned int crc32_align(unsigned int crc, const unsigned char *p, unsigned long len) { + while (len--) + crc = crc_table[(crc ^ *p++) & 0xff] ^ (crc >> 8); + return crc; +} + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len); + +Z_INTERNAL uint32_t crc32_power8(uint32_t crc, const unsigned char *p, size_t _len) { + unsigned int prealign; + unsigned int tail; + + unsigned long len = (unsigned long) _len; + + if (p == (const unsigned char *) 0x0) + return 0; + + crc ^= 0xffffffff; + + if (len < VMX_ALIGN + VMX_ALIGN_MASK) { + crc = crc32_align(crc, p, len); + goto out; + } + + if ((unsigned long)p & VMX_ALIGN_MASK) { + prealign = VMX_ALIGN - ((unsigned long)p & VMX_ALIGN_MASK); + crc = crc32_align(crc, p, prealign); + len -= prealign; + p += prealign; + } + + crc = __crc32_vpmsum(crc, p, len & ~VMX_ALIGN_MASK); + + tail = len & VMX_ALIGN_MASK; + if (tail) { + p += len & ~VMX_ALIGN_MASK; + crc = crc32_align(crc, p, tail); + } + +out: + crc ^= 0xffffffff; + + return crc; +} + +/* When we have a load-store in a single-dispatch group and address overlap + * such that forward is not allowed (load-hit-store) the group must be flushed. + * A group ending NOP prevents the flush. + */ +#define GROUP_ENDING_NOP __asm__("ori 2,2,0" ::: "memory") + +#if BYTE_ORDER == BIG_ENDIAN +#define BYTESWAP_DATA +#endif + +#ifdef BYTESWAP_DATA +#define VEC_PERM(vr, va, vb, vc) vr = vec_perm(va, vb, (__vector unsigned char) vc) +#if BYTE_ORDER == LITTLE_ENDIAN +/* Byte reverse permute constant LE. */ +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x08090A0B0C0D0E0FUL, 0x0001020304050607UL }; +#else +static const __vector unsigned long long vperm_const ALIGNED_(16) = { 0x0F0E0D0C0B0A0908UL, 0X0706050403020100UL }; +#endif +#else +#define VEC_PERM(vr, va, vb, vc) +#endif + +static unsigned int ALIGNED_(32) __crc32_vpmsum(unsigned int crc, const void* p, unsigned long len) { + + const __vector unsigned long long vzero = {0,0}; + const __vector unsigned long long vones = {0xffffffffffffffffUL, 0xffffffffffffffffUL}; + + const __vector unsigned long long vmask_32bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 4); + + const __vector unsigned long long vmask_64bit = + (__vector unsigned long long)vec_sld((__vector unsigned char)vzero, (__vector unsigned char)vones, 8); + + __vector unsigned long long vcrc; + + __vector unsigned long long vconst1, vconst2; + + /* vdata0-vdata7 will contain our data (p). */ + __vector unsigned long long vdata0, vdata1, vdata2, vdata3, vdata4, vdata5, vdata6, vdata7; + + /* v0-v7 will contain our checksums */ + __vector unsigned long long v0 = {0,0}; + __vector unsigned long long v1 = {0,0}; + __vector unsigned long long v2 = {0,0}; + __vector unsigned long long v3 = {0,0}; + __vector unsigned long long v4 = {0,0}; + __vector unsigned long long v5 = {0,0}; + __vector unsigned long long v6 = {0,0}; + __vector unsigned long long v7 = {0,0}; + + + /* Vector auxiliary variables. */ + __vector unsigned long long va0, va1, va2, va3, va4, va5, va6, va7; + + unsigned int offset; /* Constant table offset. */ + + unsigned long i; /* Counter. */ + unsigned long chunks; + + unsigned long block_size; + int next_block = 0; + + /* Align by 128 bits. The last 128 bit block will be processed at end. */ + unsigned long length = len & 0xFFFFFFFFFFFFFF80UL; + + vcrc = (__vector unsigned long long)__builtin_pack_vector_int128(0UL, crc); + + /* Short version. */ + if (len < 256) { + /* Calculate where in the constant table we need to start. */ + offset = 256 - len; + + vconst1 = vec_ld(offset, vcrc_short_const); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + + /* xor initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + + for (i = 16; i < len; i += 16) { + vconst1 = vec_ld(offset + i, vcrc_short_const); + vdata0 = vec_ld(i, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vconst1, vperm_const); + vdata0 = (__vector unsigned long long) __builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)vconst1); + v0 = vec_xor(v0, vdata0); + } + } else { + + /* Load initial values. */ + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + /* xor in initial value */ + vdata0 = vec_xor(vdata0, vcrc); + + p = (char *)p + 128; + + do { + /* Checksum in blocks of MAX_SIZE. */ + block_size = length; + if (block_size > MAX_SIZE) { + block_size = MAX_SIZE; + } + + length = length - block_size; + + /* + * Work out the offset into the constants table to start at. Each + * constant is 16 bytes, and it is used against 128 bytes of input + * data - 128 / 16 = 8 + */ + offset = (MAX_SIZE/8) - (block_size/8); + /* We reduce our final 128 bytes in a separate step */ + chunks = (block_size/128)-1; + + vconst1 = vec_ld(offset, vcrc_const); + + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + + if (chunks > 1) { + offset += 16; + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + + /* + * main loop. Each iteration calculates the CRC for a 128-byte + * block. + */ + for (i = 0; i < chunks-2; i++) { + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + GROUP_ENDING_NOP; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst2); + vdata0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst2); + vdata1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(vdata1, vdata1, vdata1, vperm_const); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long) + vdata2, (__vector unsigned long long)vconst2); + vdata2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(vdata2, vdata2, vdata2, vperm_const); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst2); + vdata3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(vdata3, vdata3, vdata3, vperm_const); + + vconst2 = vec_ld(offset, vcrc_const); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + vdata4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(vdata4, vdata4, vdata4, vperm_const); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + vdata5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(vdata5, vdata5, vdata5, vperm_const); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + vdata6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(vdata6, vdata6, vdata6, vperm_const); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + vdata7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(vdata7, vdata7, vdata7, vperm_const); + + p = (char *)p + 128; + } + + /* First cool down */ + vconst1 = vec_ld(offset, vcrc_const); + offset += 16; + + v0 = vec_xor(v0, va0); + va0 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata0, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v1 = vec_xor(v1, va1); + va1 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata1, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v2 = vec_xor(v2, va2); + va2 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata2, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v3 = vec_xor(v3, va3); + va3 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata3, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v4 = vec_xor(v4, va4); + va4 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata4, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v5 = vec_xor(v5, va5); + va5 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata5, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v6 = vec_xor(v6, va6); + va6 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata6, + (__vector unsigned long long)vconst1); + GROUP_ENDING_NOP; + + v7 = vec_xor(v7, va7); + va7 = __builtin_crypto_vpmsumd((__vector unsigned long long)vdata7, + (__vector unsigned long long)vconst1); + }/* else */ + + /* Second cool down. */ + v0 = vec_xor(v0, va0); + v1 = vec_xor(v1, va1); + v2 = vec_xor(v2, va2); + v3 = vec_xor(v3, va3); + v4 = vec_xor(v4, va4); + v5 = vec_xor(v5, va5); + v6 = vec_xor(v6, va6); + v7 = vec_xor(v7, va7); + + /* + * vpmsumd produces a 96 bit result in the least significant bits + * of the register. Since we are bit reflected we have to shift it + * left 32 bits so it occupies the least significant bits in the + * bit reflected domain. + */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v1, + (__vector unsigned char)vzero, 4); + v2 = (__vector unsigned long long)vec_sld((__vector unsigned char)v2, + (__vector unsigned char)vzero, 4); + v3 = (__vector unsigned long long)vec_sld((__vector unsigned char)v3, + (__vector unsigned char)vzero, 4); + v4 = (__vector unsigned long long)vec_sld((__vector unsigned char)v4, + (__vector unsigned char)vzero, 4); + v5 = (__vector unsigned long long)vec_sld((__vector unsigned char)v5, + (__vector unsigned char)vzero, 4); + v6 = (__vector unsigned long long)vec_sld((__vector unsigned char)v6, + (__vector unsigned char)vzero, 4); + v7 = (__vector unsigned long long)vec_sld((__vector unsigned char)v7, + (__vector unsigned char)vzero, 4); + + /* xor with the last 1024 bits. */ + va0 = vec_ld(0, (__vector unsigned long long*) p); + VEC_PERM(va0, va0, va0, vperm_const); + + va1 = vec_ld(16, (__vector unsigned long long*) p); + VEC_PERM(va1, va1, va1, vperm_const); + + va2 = vec_ld(32, (__vector unsigned long long*) p); + VEC_PERM(va2, va2, va2, vperm_const); + + va3 = vec_ld(48, (__vector unsigned long long*) p); + VEC_PERM(va3, va3, va3, vperm_const); + + va4 = vec_ld(64, (__vector unsigned long long*) p); + VEC_PERM(va4, va4, va4, vperm_const); + + va5 = vec_ld(80, (__vector unsigned long long*) p); + VEC_PERM(va5, va5, va5, vperm_const); + + va6 = vec_ld(96, (__vector unsigned long long*) p); + VEC_PERM(va6, va6, va6, vperm_const); + + va7 = vec_ld(112, (__vector unsigned long long*) p); + VEC_PERM(va7, va7, va7, vperm_const); + + p = (char *)p + 128; + + vdata0 = vec_xor(v0, va0); + vdata1 = vec_xor(v1, va1); + vdata2 = vec_xor(v2, va2); + vdata3 = vec_xor(v3, va3); + vdata4 = vec_xor(v4, va4); + vdata5 = vec_xor(v5, va5); + vdata6 = vec_xor(v6, va6); + vdata7 = vec_xor(v7, va7); + + /* Check if we have more blocks to process */ + next_block = 0; + if (length != 0) { + next_block = 1; + + /* zero v0-v7 */ + v0 = vec_xor(v0, v0); + v1 = vec_xor(v1, v1); + v2 = vec_xor(v2, v2); + v3 = vec_xor(v3, v3); + v4 = vec_xor(v4, v4); + v5 = vec_xor(v5, v5); + v6 = vec_xor(v6, v6); + v7 = vec_xor(v7, v7); + } + length = length + 128; + + } while (next_block); + + /* Calculate how many bytes we have left. */ + length = (len & 127); + + /* Calculate where in (short) constant table we need to start. */ + offset = 128 - length; + + v0 = vec_ld(offset, vcrc_short_const); + v1 = vec_ld(offset + 16, vcrc_short_const); + v2 = vec_ld(offset + 32, vcrc_short_const); + v3 = vec_ld(offset + 48, vcrc_short_const); + v4 = vec_ld(offset + 64, vcrc_short_const); + v5 = vec_ld(offset + 80, vcrc_short_const); + v6 = vec_ld(offset + 96, vcrc_short_const); + v7 = vec_ld(offset + 112, vcrc_short_const); + + offset += 128; + + v0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)v0); + v1 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata1, (__vector unsigned int)v1); + v2 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata2, (__vector unsigned int)v2); + v3 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata3, (__vector unsigned int)v3); + v4 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata4, (__vector unsigned int)v4); + v5 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata5, (__vector unsigned int)v5); + v6 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata6, (__vector unsigned int)v6); + v7 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata7, (__vector unsigned int)v7); + + /* Now reduce the tail (0-112 bytes). */ + for (i = 0; i < length; i+=16) { + vdata0 = vec_ld(i,(__vector unsigned long long*)p); + VEC_PERM(vdata0, vdata0, vdata0, vperm_const); + va0 = vec_ld(offset + i,vcrc_short_const); + va0 = (__vector unsigned long long)__builtin_crypto_vpmsumw( + (__vector unsigned int)vdata0, (__vector unsigned int)va0); + v0 = vec_xor(v0, va0); + } + + /* xor all parallel chunks together. */ + v0 = vec_xor(v0, v1); + v2 = vec_xor(v2, v3); + v4 = vec_xor(v4, v5); + v6 = vec_xor(v6, v7); + + v0 = vec_xor(v0, v2); + v4 = vec_xor(v4, v6); + + v0 = vec_xor(v0, v4); + } + + /* Barrett Reduction */ + vconst1 = vec_ld(0, v_Barrett_const); + vconst2 = vec_ld(16, v_Barrett_const); + + v1 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)v0, 8); + v0 = vec_xor(v1,v0); + + /* shift left one bit */ + __vector unsigned char vsht_splat = vec_splat_u8 (1); + v0 = (__vector unsigned long long)vec_sll((__vector unsigned char)v0, vsht_splat); + + v0 = vec_and(v0, vmask_64bit); + + /* + * The reflected version of Barrett reduction. Instead of bit + * reflecting our data (which is expensive to do), we bit reflect our + * constants and our algorithm, which means the intermediate data in + * our vector registers goes from 0-63 instead of 63-0. We can reflect + * the algorithm because we don't carry in mod 2 arithmetic. + */ + + /* bottom 32 bits of a */ + v1 = vec_and(v0, vmask_32bit); + + /* ma */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst1); + + /* bottom 32bits of ma */ + v1 = vec_and(v1, vmask_32bit); + /* qn */ + v1 = __builtin_crypto_vpmsumd((__vector unsigned long long)v1, + (__vector unsigned long long)vconst2); + /* a - qn, subtraction is xor in GF(2) */ + v0 = vec_xor (v0, v1); + + /* + * Since we are bit reflected, the result (ie the low 32 bits) is in + * the high 32 bits. We just need to shift it left 4 bytes + * V0 [ 0 1 X 3 ] + * V0 [ 0 X 2 3 ] + */ + + /* shift result into top 64 bits of */ + v0 = (__vector unsigned long long)vec_sld((__vector unsigned char)v0, + (__vector unsigned char)vzero, 4); + +#if BYTE_ORDER == BIG_ENDIAN + return v0[0]; +#else + return v0[1]; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/fallback_builtins.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/fallback_builtins.h new file mode 100644 index 000000000..ed9584617 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/fallback_builtins.h @@ -0,0 +1,31 @@ +/* Helper functions to work around issues with clang builtins + * Copyright (C) 2021 IBM Corporation + * + * Authors: + * Daniel Black + * Rogerio Alves + * Tulio Magno Quites Machado Filho + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_BUILTINS_H +#define POWER_BUILTINS_H + +/* + * These stubs fix clang incompatibilities with GCC builtins. + */ + +#ifndef __builtin_crypto_vpmsumw +#define __builtin_crypto_vpmsumw __builtin_crypto_vpmsumb +#endif +#ifndef __builtin_crypto_vpmsumd +#define __builtin_crypto_vpmsumd __builtin_crypto_vpmsumb +#endif + +static inline __vector unsigned long long __attribute__((overloadable)) +vec_ld(int __a, const __vector unsigned long long* __b) { + return (__vector unsigned long long)__builtin_altivec_lvx(__a, __b); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.c new file mode 100644 index 000000000..003a4c6e3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.c @@ -0,0 +1,42 @@ +/* power_features.c - POWER feature check + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021-2022 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef HAVE_SYS_AUXV_H +# include +#endif +#ifdef __FreeBSD__ +# include +#endif +#include "../../zbuild.h" +#include "power_features.h" + +void Z_INTERNAL power_check_features(struct power_cpu_features *features) { +#ifdef PPC_FEATURES + unsigned long hwcap; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); +#else + hwcap = getauxval(AT_HWCAP); +#endif + + if (hwcap & PPC_FEATURE_HAS_ALTIVEC) + features->has_altivec = 1; +#endif + +#ifdef POWER_FEATURES + unsigned long hwcap2; +#ifdef __FreeBSD__ + elf_aux_info(AT_HWCAP2, &hwcap2, sizeof(hwcap2)); +#else + hwcap2 = getauxval(AT_HWCAP2); +#endif + + if (hwcap2 & PPC_FEATURE2_ARCH_2_07) + features->has_arch_2_07 = 1; + if (hwcap2 & PPC_FEATURE2_ARCH_3_00) + features->has_arch_3_00 = 1; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.h new file mode 100644 index 000000000..9252364cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/power_features.h @@ -0,0 +1,18 @@ +/* power_features.h -- check for POWER CPU features + * Copyright (C) 2020 Matheus Castanho , IBM + * Copyright (C) 2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef POWER_H_ +#define POWER_H_ + +struct power_cpu_features { + int has_altivec; + int has_arch_2_07; + int has_arch_3_00; +}; + +void Z_INTERNAL power_check_features(struct power_cpu_features *features); + +#endif /* POWER_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_power8.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_power8.c new file mode 100644 index 000000000..d01e0acd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_power8.c @@ -0,0 +1,12 @@ +/* Optimized slide_hash for POWER processors + * Copyright (C) 2019-2020 IBM Corporation + * Author: Matheus Castanho + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef POWER8_VSX + +#define SLIDE_PPC slide_hash_power8 +#include "slide_ppc_tpl.h" + +#endif /* POWER8_VSX */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_vmx.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_vmx.c new file mode 100644 index 000000000..5a87ef7d9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_hash_vmx.c @@ -0,0 +1,10 @@ +/* Optimized slide_hash for PowerPC processors with VMX instructions + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifdef PPC_VMX + +#define SLIDE_PPC slide_hash_vmx +#include "slide_ppc_tpl.h" + +#endif /* PPC_VMX */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_ppc_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_ppc_tpl.h new file mode 100644 index 000000000..5c17e38fb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/power/slide_ppc_tpl.h @@ -0,0 +1,31 @@ +/* Optimized slide_hash for PowerPC processors + * Copyright (C) 2017-2021 Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include +#include "zbuild.h" +#include "deflate.h" + +static inline void slide_hash_chain(Pos *table, uint32_t entries, uint16_t wsize) { + const vector unsigned short vmx_wsize = vec_splats(wsize); + Pos *p = table; + + do { + vector unsigned short value, result; + + value = vec_ld(0, p); + result = vec_subs(value, vmx_wsize); + vec_st(result, 0, p); + + p += 8; + entries -= 8; + } while (entries > 0); +} + +void Z_INTERNAL SLIDE_PPC(deflate_state *s) { + uint16_t wsize = s->w_size; + + slide_hash_chain(s->head, HASH_SIZE, wsize); + slide_hash_chain(s->prev, wsize, wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/README.md b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/README.md new file mode 100644 index 000000000..b4309e1a0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/README.md @@ -0,0 +1,45 @@ +# Building RISC-V Target with Cmake # + +> **Warning** +> We cannot detect rvv support at runtime, running the rvv code on a no-rvv target is a risk. Users should disable the rvv when the target does not support it. +> +> We will have a better solution when the kernels update `hwcap` or `hwprobe` for risc-v. + +## Prerequisite: Build RISC-V Clang Toolchain and QEMU ## + +If you don't have prebuilt clang and riscv64 qemu, you can refer to the [script](https://github.com/sifive/prepare-riscv-toolchain-qemu/blob/main/prepare_riscv_toolchain_qemu.sh) to get the source. Copy the script to the zlib-ng root directory, and run it to download the source and build them. Modify the content according to your conditions (e.g., toolchain version). + +```bash +./prepare_riscv_toolchain_qemu.sh +``` + +After running script, clang & qemu are built in `build-toolchain-qemu/riscv-clang/` & `build-toolchain-qemu/riscv-qemu/`. + +`build-toolchain-qemu/riscv-clang/` is your `TOOLCHAIN_PATH`. +`build-toolchain-qemu/riscv-qemu/bin/qemu-riscv64` is your `QEMU_PATH`. + +You can also download the prebuilt toolchain & qemu from [the release page](https://github.com/sifive/prepare-riscv-toolchain-qemu/releases), and enjoy using them. + +## Cross-Compile for RISC-V Target ## + +```bash +cmake -G Ninja -B ./build-riscv \ + -D CMAKE_TOOLCHAIN_FILE=./cmake/toolchain-riscv.cmake \ + -D CMAKE_INSTALL_PREFIX=./build-riscv/install \ + -D TOOLCHAIN_PATH={TOOLCHAIN_PATH} \ + -D QEMU_PATH={QEMU_PATH} \ + . + +cmake --build ./build-riscv +``` + +Disable the option if there is no RVV support: +``` +-D WITH_RVV=OFF +``` + +## Run Unittests on User Mode QEMU ## + +```bash +cd ./build-riscv && ctest --verbose +``` diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.c new file mode 100644 index 000000000..362d71483 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.c @@ -0,0 +1,15 @@ +#include +#include +#include + +#include "../../zbuild.h" +#include "riscv_features.h" + +/* TODO: detect risc-v cpu info at runtime when the kernel updates hwcap or hwprobe for risc-v */ +void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features) { +#if defined(__riscv_v) && defined(__linux__) + features->has_rvv = 1; +#else + features->has_rvv = 0; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.h new file mode 100644 index 000000000..f933fc9ac --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/riscv/riscv_features.h @@ -0,0 +1,18 @@ +/* riscv_features.h -- check for riscv features. + * + * Copyright (C) 2023 SiFive, Inc. All rights reserved. + * Contributed by Alex Chiang + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef RISCV_H_ +#define RISCV_H_ + +struct riscv_cpu_features { + int has_rvv; +}; + +void Z_INTERNAL riscv_check_features(struct riscv_cpu_features *features); + +#endif /* RISCV_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/Makefile.in new file mode 100644 index 000000000..39b5aae61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/Makefile.in @@ -0,0 +1,54 @@ +# Makefile for zlib-ng +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= +VGFMAFLAG= +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +s390_features.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +s390_features.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/s390_features.c + +dfltcc_common.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_common.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_common.c + +dfltcc_deflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_deflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_deflate.c + +dfltcc_inflate.o: + $(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +dfltcc_inflate.lo: + $(CC) $(SFLAGS) $(INCLUDES) -c -o $@ $(SRCDIR)/dfltcc_inflate.c + +crc32-vx.o: + $(CC) $(CFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +crc32-vx.lo: + $(CC) $(SFLAGS) $(VGFMAFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32-vx.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/README.md b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/README.md new file mode 100644 index 000000000..2c3165412 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/README.md @@ -0,0 +1,284 @@ +# Introduction + +This directory contains SystemZ deflate hardware acceleration support. +It can be enabled using the following build commands: + + $ ./configure --with-dfltcc-deflate --with-dfltcc-inflate + $ make + +or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 -DWITH_DFLTCC_INFLATE=1 . + $ make + +When built like this, zlib-ng would compress using hardware on level 1, +and using software on all other levels. Decompression will always happen +in hardware. In order to enable hardware compression for levels 1-6 +(i.e. to make it used by default) one could add +`-DDFLTCC_LEVEL_MASK=0x7e` to CFLAGS when building zlib-ng. + +SystemZ deflate hardware acceleration is available on [IBM z15]( +https://www.ibm.com/products/z15) and newer machines under the name [ +"Integrated Accelerator for zEnterprise Data Compression"]( +https://www.ibm.com/support/z-content-solutions/compression/). The +programming interface to it is a machine instruction called DEFLATE +CONVERSION CALL (DFLTCC). It is documented in Chapter 26 of [Principles +of Operation](https://publibfp.dhe.ibm.com/epubs/pdf/a227832c.pdf). Both +the code and the rest of this document refer to this feature simply as +"DFLTCC". + +# Performance + +Performance figures are published [here]( +https://github.com/iii-i/zlib-ng/wiki/Performance-with-dfltcc-patch-applied-and-dfltcc-support-built-on-dfltcc-enabled-machine +). The compression speed-up can be as high as 110x and the decompression +speed-up can be as high as 15x. + +# Limitations + +Two DFLTCC compression calls with identical inputs are not guaranteed to +produce identical outputs. Therefore care should be taken when using +hardware compression when reproducible results are desired. In +particular, zlib-ng-specific `zng_deflateSetParams` call allows setting +`Z_DEFLATE_REPRODUCIBLE` parameter, which disables DFLTCC support for a +particular stream. + +DFLTCC does not support every single zlib-ng feature, in particular: + +* `inflate(Z_BLOCK)` and `inflate(Z_TREES)` +* `inflateMark()` +* `inflatePrime()` +* `inflateSyncPoint()` + +When used, these functions will either switch to software, or, in case +this is not possible, gracefully fail. + +# Code structure + +All SystemZ-specific code lives in `arch/s390` directory and is +integrated with the rest of zlib-ng using hook macros. + +## Hook macros + +DFLTCC takes as arguments a parameter block, an input buffer, an output +buffer and a window. `ZALLOC_DEFLATE_STATE()`, `ZALLOC_INFLATE_STATE()`, +`ZFREE_STATE()`, `ZCOPY_DEFLATE_STATE()`, `ZCOPY_INFLATE_STATE()`, +`ZALLOC_WINDOW()`, `ZCOPY_WINDOW()` and `TRY_FREE_WINDOW()` macros encapsulate +allocation details for the parameter block (which is allocated alongside +zlib-ng state) and the window (which must be page-aligned and large enough). + +Software and hardware window formats do not match, therefore, +`deflateSetDictionary()`, `deflateGetDictionary()`, `inflateSetDictionary()` +and `inflateGetDictionary()` need special handling, which is triggered using +`DEFLATE_SET_DICTIONARY_HOOK()`, `DEFLATE_GET_DICTIONARY_HOOK()`, +`INFLATE_SET_DICTIONARY_HOOK()` and `INFLATE_GET_DICTIONARY_HOOK()` macros. + +`deflateResetKeep()` and `inflateResetKeep()` update the DFLTCC +parameter block using `DEFLATE_RESET_KEEP_HOOK()` and +`INFLATE_RESET_KEEP_HOOK()` macros. + +`INFLATE_PRIME_HOOK()`, `INFLATE_MARK_HOOK()` and +`INFLATE_SYNC_POINT_HOOK()` macros make the respective unsupported +calls gracefully fail. + +`DEFLATE_PARAMS_HOOK()` implements switching between hardware and +software compression mid-stream using `deflateParams()`. Switching +normally entails flushing the current block, which might not be possible +in low memory situations. `deflateParams()` uses `DEFLATE_DONE()` hook +in order to detect and gracefully handle such situations. + +The algorithm implemented in hardware has different compression ratio +than the one implemented in software. `DEFLATE_BOUND_ADJUST_COMPLEN()` +and `DEFLATE_NEED_CONSERVATIVE_BOUND()` macros make `deflateBound()` +return the correct results for the hardware implementation. + +Actual compression and decompression are handled by `DEFLATE_HOOK()` and +`INFLATE_TYPEDO_HOOK()` macros. Since inflation with DFLTCC manages the +window on its own, calling `updatewindow()` is suppressed using +`INFLATE_NEED_UPDATEWINDOW()` macro. + +In addition to compression, DFLTCC computes CRC-32 and Adler-32 +checksums, therefore, whenever it's used, software checksumming is +suppressed using `DEFLATE_NEED_CHECKSUM()` and `INFLATE_NEED_CHECKSUM()` +macros. + +While software always produces reproducible compression results, this +is not the case for DFLTCC. Therefore, zlib-ng users are given the +ability to specify whether or not reproducible compression results +are required. While it is always possible to specify this setting +before the compression begins, it is not always possible to do so in +the middle of a deflate stream - the exact conditions for that are +determined by `DEFLATE_CAN_SET_REPRODUCIBLE()` macro. + +## SystemZ-specific code + +When zlib-ng is built with DFLTCC, the hooks described above are +converted to calls to functions, which are implemented in +`arch/s390/dfltcc_*` files. The functions can be grouped in three broad +categories: + +* Base DFLTCC support, e.g. wrapping the machine instruction - + `dfltcc()` and allocating aligned memory - `dfltcc_alloc_state()`. +* Translating between software and hardware data formats, e.g. + `dfltcc_deflate_set_dictionary()`. +* Translating between software and hardware state machines, e.g. + `dfltcc_deflate()` and `dfltcc_inflate()`. + +The functions from the first two categories are fairly simple, however, +various quirks in both software and hardware state machines make the +functions from the third category quite complicated. + +### `dfltcc_deflate()` function + +This function is called by `deflate()` and has the following +responsibilities: + +* Checking whether DFLTCC can be used with the current stream. If this + is not the case, then it returns `0`, making `deflate()` use some + other function in order to compress in software. Otherwise it returns + `1`. +* Block management and Huffman table generation. DFLTCC ends blocks only + when explicitly instructed to do so by the software. Furthermore, + whether to use fixed or dynamic Huffman tables must also be determined + by the software. Since looking at data in order to gather statistics + would negate performance benefits, the following approach is used: the + first `DFLTCC_FIRST_FHT_BLOCK_SIZE` bytes are placed into a fixed + block, and every next `DFLTCC_BLOCK_SIZE` bytes are placed into + dynamic blocks. +* Writing EOBS. Block Closing Control bit in the parameter block + instructs DFLTCC to write EOBS, however, certain conditions need to be + met: input data length must be non-zero or Continuation Flag must be + set. To put this in simpler terms, DFLTCC will silently refuse to + write EOBS if this is the only thing that it is asked to do. Since the + code has to be able to emit EOBS in software anyway, in order to avoid + tricky corner cases Block Closing Control is never used. Whether to + write EOBS is instead controlled by `soft_bcc` variable. +* Triggering block post-processing. Depending on flush mode, `deflate()` + must perform various additional actions when a block or a stream ends. + `dfltcc_deflate()` informs `deflate()` about this using + `block_state *result` parameter. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `wrap` and Check Value Type or `bi_valid` + and Sub-Byte Boundary. Certain fields cannot be translated and must + persist untouched in the parameter block between calls, for example, + Continuation Flag or Continuation State Buffer. +* Handling flush modes and low-memory situations. These aspects are + quite intertwined and pervasive. The general idea here is that the + code must not do anything in software - whether explicitly by e.g. + calling `send_eobs()`, or implicitly - by returning to `deflate()` + with certain return and `*result` values, when Continuation Flag is + set. +* Ending streams. When a new block is started and flush mode is + `Z_FINISH`, Block Header Final parameter block bit is used to mark + this block as final. However, sometimes an empty final block is + needed, and, unfortunately, just like with EOBS, DFLTCC will silently + refuse to do this. The general idea of DFLTCC implementation is to + rely as much as possible on the existing code. Here in order to do + this, the code pretends that it does not support DFLTCC, which makes + `deflate()` call a software compression function, which writes an + empty final block. Whether this is required is controlled by + `need_empty_block` variable. +* Error handling. This is simply converting + Operation-Ending-Supplemental Code to string. Errors can only happen + due to things like memory corruption, and therefore they don't affect + the `deflate()` return code. + +### `dfltcc_inflate()` function + +This function is called by `inflate()` from the `TYPEDO` state (that is, +when all the metadata is parsed and the stream is positioned at the type +bits of deflate block header) and it's responsible for the following: + +* Falling back to software when flush mode is `Z_BLOCK` or `Z_TREES`. + Unfortunately, there is no way to ask DFLTCC to stop decompressing on + block or tree boundary. +* `inflate()` decompression loop management. This is controlled using + the return value, which can be either `DFLTCC_INFLATE_BREAK` or + `DFLTCC_INFLATE_CONTINUE`. +* Converting software state fields into hardware parameter block fields, + and vice versa. For example, `whave` and History Length or `wnext` and + History Offset. +* Ending streams. This instructs `inflate()` to return `Z_STREAM_END` + and is controlled by `last` state field. +* Error handling. Like deflate, error handling comprises + Operation-Ending-Supplemental Code to string conversion. Unlike + deflate, errors may happen due to bad inputs, therefore they are + propagated to `inflate()` by setting `mode` field to `MEM` or `BAD`. + +# Testing + +Given complexity of DFLTCC machine instruction, it is not clear whether +QEMU TCG will ever support it. At the time of writing, one has to have +access to an IBM z15+ VM or LPAR in order to test DFLTCC support. Since +DFLTCC is a non-privileged instruction, neither special VM/LPAR +configuration nor root are required. + +zlib-ng CI uses an IBM-provided z15 self-hosted builder for the DFLTCC +testing. There are no IBM Z builds of GitHub Actions runner, and +stable qemu-user has problems with .NET apps, so the builder runs the +x86_64 runner version with qemu-user built from the master branch. + +## Configuring the builder. + +### Install prerequisites. + +``` +$ sudo dnf install docker +``` + +### Add services. + +``` +$ sudo cp self-hosted-builder/*.service /etc/systemd/system/ +$ sudo systemctl daemon-reload +``` + +### Create a config file. + +``` +$ sudo tee /etc/actions-runner +repo=/ +access_token= +``` + +Access token should have the repo scope, consult +https://docs.github.com/en/rest/reference/actions#create-a-registration-token-for-a-repository +for details. + +### Autostart the x86_64 emulation support. + +``` +$ sudo systemctl enable --now qemu-user-static +``` + +### Autostart the runner. + +``` +$ sudo systemctl enable --now actions-runner +``` + +## Rebuilding the image + +In order to update the `iiilinuxibmcom/actions-runner` image, e.g. to get the +latest OS security fixes, use the following commands: + +``` +$ sudo docker build \ + --pull \ + -f self-hosted-builder/actions-runner.Dockerfile \ + -t iiilinuxibmcom/actions-runner +$ sudo systemctl restart actions-runner +``` + +## Removing persistent data + +The `actions-runner` service stores various temporary data, such as runner +registration information, work directories and logs, in the `actions-runner` +volume. In order to remove it and start from scratch, e.g. when switching the +runner to a different repository, use the following commands: + +``` +$ sudo systemctl stop actions-runner +$ sudo docker rm -f actions-runner +$ sudo docker volume rm actions-runner +``` diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/crc32-vx.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/crc32-vx.c new file mode 100644 index 000000000..acfa21887 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/crc32-vx.c @@ -0,0 +1,222 @@ +/* + * Hardware-accelerated CRC-32 variants for Linux on z Systems + * + * Use the z/Architecture Vector Extension Facility to accelerate the + * computing of bitreflected CRC-32 checksums. + * + * This CRC-32 implementation algorithm is bitreflected and processes + * the least-significant bit first (Little-Endian). + * + * This code was originally written by Hendrik Brueckner + * for use in the Linux kernel and has been + * relicensed under the zlib license. + */ + +#include "../../zbuild.h" +#include "crc32_braid_p.h" + +#include + +typedef unsigned char uv16qi __attribute__((vector_size(16))); +typedef unsigned int uv4si __attribute__((vector_size(16))); +typedef unsigned long long uv2di __attribute__((vector_size(16))); + +static uint32_t crc32_le_vgfm_16(uint32_t crc, const uint8_t *buf, size_t len) { + /* + * The CRC-32 constant block contains reduction constants to fold and + * process particular chunks of the input data stream in parallel. + * + * For the CRC-32 variants, the constants are precomputed according to + * these definitions: + * + * R1 = [(x4*128+32 mod P'(x) << 32)]' << 1 + * R2 = [(x4*128-32 mod P'(x) << 32)]' << 1 + * R3 = [(x128+32 mod P'(x) << 32)]' << 1 + * R4 = [(x128-32 mod P'(x) << 32)]' << 1 + * R5 = [(x64 mod P'(x) << 32)]' << 1 + * R6 = [(x32 mod P'(x) << 32)]' << 1 + * + * The bitreflected Barret reduction constant, u', is defined as + * the bit reversal of floor(x**64 / P(x)). + * + * where P(x) is the polynomial in the normal domain and the P'(x) is the + * polynomial in the reversed (bitreflected) domain. + * + * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials: + * + * P(x) = 0x04C11DB7 + * P'(x) = 0xEDB88320 + */ + const uv16qi perm_le2be = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; /* BE->LE mask */ + const uv2di r2r1 = {0x1C6E41596, 0x154442BD4}; /* R2, R1 */ + const uv2di r4r3 = {0x0CCAA009E, 0x1751997D0}; /* R4, R3 */ + const uv2di r5 = {0, 0x163CD6124}; /* R5 */ + const uv2di ru_poly = {0, 0x1F7011641}; /* u' */ + const uv2di crc_poly = {0, 0x1DB710641}; /* P'(x) << 1 */ + + /* + * Load the initial CRC value. + * + * The CRC value is loaded into the rightmost word of the + * vector register and is later XORed with the LSB portion + * of the loaded input data. + */ + uv2di v0 = {0, 0}; + v0 = (uv2di)vec_insert(crc, (uv4si)v0, 3); + + /* Load a 64-byte data chunk and XOR with CRC */ + uv2di v1 = vec_perm(((uv2di *)buf)[0], ((uv2di *)buf)[0], perm_le2be); + uv2di v2 = vec_perm(((uv2di *)buf)[1], ((uv2di *)buf)[1], perm_le2be); + uv2di v3 = vec_perm(((uv2di *)buf)[2], ((uv2di *)buf)[2], perm_le2be); + uv2di v4 = vec_perm(((uv2di *)buf)[3], ((uv2di *)buf)[3], perm_le2be); + + v1 ^= v0; + buf += 64; + len -= 64; + + while (len >= 64) { + /* Load the next 64-byte data chunk */ + uv16qi part1 = vec_perm(((uv16qi *)buf)[0], ((uv16qi *)buf)[0], perm_le2be); + uv16qi part2 = vec_perm(((uv16qi *)buf)[1], ((uv16qi *)buf)[1], perm_le2be); + uv16qi part3 = vec_perm(((uv16qi *)buf)[2], ((uv16qi *)buf)[2], perm_le2be); + uv16qi part4 = vec_perm(((uv16qi *)buf)[3], ((uv16qi *)buf)[3], perm_le2be); + + /* + * Perform a GF(2) multiplication of the doublewords in V1 with + * the R1 and R2 reduction constants in V0. The intermediate result + * is then folded (accumulated) with the next data chunk in PART1 and + * stored in V1. Repeat this step for the register contents + * in V2, V3, and V4 respectively. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r2r1, v1, part1); + v2 = (uv2di)vec_gfmsum_accum_128(r2r1, v2, part2); + v3 = (uv2di)vec_gfmsum_accum_128(r2r1, v3, part3); + v4 = (uv2di)vec_gfmsum_accum_128(r2r1, v4, part4); + + buf += 64; + len -= 64; + } + + /* + * Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3 + * and R4 and accumulating the next 128-bit chunk until a single 128-bit + * value remains. + */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v3); + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v4); + + while (len >= 16) { + /* Load next data chunk */ + v2 = vec_perm(*(uv2di *)buf, *(uv2di *)buf, perm_le2be); + + /* Fold next data chunk */ + v1 = (uv2di)vec_gfmsum_accum_128(r4r3, v1, (uv16qi)v2); + + buf += 16; + len -= 16; + } + + /* + * Set up a vector register for byte shifts. The shift value must + * be loaded in bits 1-4 in byte element 7 of a vector register. + * Shift by 8 bytes: 0x40 + * Shift by 4 bytes: 0x20 + */ + uv16qi v9 = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + v9 = vec_insert((unsigned char)0x40, v9, 7); + + /* + * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes + * to move R4 into the rightmost doubleword and set the leftmost + * doubleword to 0x1. + */ + v0 = vec_srb(r4r3, (uv2di)v9); + v0[0] = 1; + + /* + * Compute GF(2) product of V1 and V0. The rightmost doubleword + * of V1 is multiplied with R4. The leftmost doubleword of V1 is + * multiplied by 0x1 and is then XORed with rightmost product. + * Implicitly, the intermediate leftmost product becomes padded + */ + v1 = (uv2di)vec_gfmsum_128(v0, v1); + + /* + * Now do the final 32-bit fold by multiplying the rightmost word + * in V1 with R5 and XOR the result with the remaining bits in V1. + * + * To achieve this by a single VGFMAG, right shift V1 by a word + * and store the result in V2 which is then accumulated. Use the + * vector unpack instruction to load the rightmost half of the + * doubleword into the rightmost doubleword element of V1; the other + * half is loaded in the leftmost doubleword. + * The vector register with CONST_R5 contains the R5 constant in the + * rightmost doubleword and the leftmost doubleword is zero to ignore + * the leftmost product of V1. + */ + v9 = vec_insert((unsigned char)0x20, v9, 7); + v2 = vec_srb(v1, (uv2di)v9); + v1 = vec_unpackl((uv4si)v1); /* Split rightmost doubleword */ + v1 = (uv2di)vec_gfmsum_accum_128(r5, v1, (uv16qi)v2); + + /* + * Apply a Barret reduction to compute the final 32-bit CRC value. + * + * The input values to the Barret reduction are the degree-63 polynomial + * in V1 (R(x)), degree-32 generator polynomial, and the reduction + * constant u. The Barret reduction result is the CRC value of R(x) mod + * P(x). + * + * The Barret reduction algorithm is defined as: + * + * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u + * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x) + * 3. C(x) = R(x) XOR T2(x) mod x^32 + * + * Note: The leftmost doubleword of vector register containing + * CONST_RU_POLY is zero and, thus, the intermediate GF(2) product + * is zero and does not contribute to the final result. + */ + + /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */ + v2 = vec_unpackl((uv4si)v1); + v2 = (uv2di)vec_gfmsum_128(ru_poly, v2); + + /* + * Compute the GF(2) product of the CRC polynomial with T1(x) in + * V2 and XOR the intermediate result, T2(x), with the value in V1. + * The final result is stored in word element 2 of V2. + */ + v2 = vec_unpackl((uv4si)v2); + v2 = (uv2di)vec_gfmsum_accum_128(crc_poly, v2, (uv16qi)v1); + + return ((uv4si)v2)[2]; +} + +#define VX_MIN_LEN 64 +#define VX_ALIGNMENT 16L +#define VX_ALIGN_MASK (VX_ALIGNMENT - 1) + +uint32_t Z_INTERNAL crc32_s390_vx(uint32_t crc, const unsigned char *buf, size_t len) { + size_t prealign, aligned, remaining; + + if (len < VX_MIN_LEN + VX_ALIGN_MASK) + return PREFIX(crc32_braid)(crc, buf, len); + + if ((uintptr_t)buf & VX_ALIGN_MASK) { + prealign = VX_ALIGNMENT - ((uintptr_t)buf & VX_ALIGN_MASK); + len -= prealign; + crc = PREFIX(crc32_braid)(crc, buf, prealign); + buf += prealign; + } + aligned = len & ~VX_ALIGN_MASK; + remaining = len & VX_ALIGN_MASK; + + crc = crc32_le_vgfm_16(crc ^ 0xffffffff, buf, aligned) ^ 0xffffffff; + + if (remaining) + crc = PREFIX(crc32_braid)(crc, buf + aligned, remaining); + + return crc; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.c new file mode 100644 index 000000000..78be71811 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.c @@ -0,0 +1,40 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL general support. */ + +#include "zbuild.h" +#include "dfltcc_common.h" +#include "dfltcc_detail.h" + +/* + Memory management. + + DFLTCC requires parameter blocks and window to be aligned. zlib-ng allows + users to specify their own allocation functions, so using e.g. + `posix_memalign' is not an option. Thus, we overallocate and take the + aligned portion of the buffer. +*/ + +static const int PAGE_ALIGN = 0x1000; + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size) { + void *p; + void *w; + + /* To simplify freeing, we store the pointer to the allocated buffer right + * before the window. Note that DFLTCC always uses HB_SIZE bytes. + */ + p = ZALLOC(strm, sizeof(void *) + MAX(items * size, HB_SIZE) + PAGE_ALIGN, sizeof(unsigned char)); + if (p == NULL) + return NULL; + w = ALIGN_UP((char *)p + sizeof(void *), PAGE_ALIGN); + *(void **)((char *)w - sizeof(void *)) = p; + return w; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n) { + memcpy(dest, src, MAX(n, HB_SIZE)); +} + +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w) { + if (w) + ZFREE(strm, *(void **)((unsigned char *)w - sizeof(void *))); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.h new file mode 100644 index 000000000..b73437411 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_common.h @@ -0,0 +1,44 @@ +#ifndef DFLTCC_COMMON_H +#define DFLTCC_COMMON_H + +#include "zutil.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_window)(PREFIX3(streamp) strm, uInt items, uInt size); +void Z_INTERNAL PREFIX(dfltcc_copy_window)(void *dest, const void *src, size_t n); +void Z_INTERNAL PREFIX(dfltcc_free_window)(PREFIX3(streamp) strm, void *w); + +#define ZFREE_STATE ZFREE + +#define ZALLOC_WINDOW PREFIX(dfltcc_alloc_window) + +#define ZCOPY_WINDOW PREFIX(dfltcc_copy_window) + +#define ZFREE_WINDOW PREFIX(dfltcc_free_window) + +#define TRY_FREE_WINDOW PREFIX(dfltcc_free_window) + +#define DFLTCC_BLOCK_HEADER_BITS 3 +#define DFLTCC_HLITS_COUNT_BITS 5 +#define DFLTCC_HDISTS_COUNT_BITS 5 +#define DFLTCC_HCLENS_COUNT_BITS 4 +#define DFLTCC_MAX_HCLENS 19 +#define DFLTCC_HCLEN_BITS 3 +#define DFLTCC_MAX_HLITS 286 +#define DFLTCC_MAX_HDISTS 30 +#define DFLTCC_MAX_HLIT_HDIST_BITS 7 +#define DFLTCC_MAX_SYMBOL_BITS 16 +#define DFLTCC_MAX_EOBS_BITS 15 +#define DFLTCC_MAX_PADDING_BITS 7 + +#define DEFLATE_BOUND_COMPLEN(source_len) \ + ((DFLTCC_BLOCK_HEADER_BITS + \ + DFLTCC_HLITS_COUNT_BITS + \ + DFLTCC_HDISTS_COUNT_BITS + \ + DFLTCC_HCLENS_COUNT_BITS + \ + DFLTCC_MAX_HCLENS * DFLTCC_HCLEN_BITS + \ + (DFLTCC_MAX_HLITS + DFLTCC_MAX_HDISTS) * DFLTCC_MAX_HLIT_HDIST_BITS + \ + (source_len) * DFLTCC_MAX_SYMBOL_BITS + \ + DFLTCC_MAX_EOBS_BITS + \ + DFLTCC_MAX_PADDING_BITS) >> 3) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.c new file mode 100644 index 000000000..3ad988afc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.c @@ -0,0 +1,404 @@ +/* dfltcc_deflate.c - IBM Z DEFLATE CONVERSION CALL compression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC compression support: + + $ ./configure --with-dfltcc-deflate + or + + $ cmake -DWITH_DFLTCC_DEFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "deflate.h" +#include "trees_emit.h" +#include "dfltcc_deflate.h" +#include "dfltcc_detail.h" + +struct dfltcc_deflate_state { + struct dfltcc_state common; + uint16_t level_mask; /* Levels on which to use DFLTCC */ + uint32_t block_size; /* New block each X bytes */ + size_t block_threshold; /* New block after total_in > X */ + uint32_t dht_threshold; /* New block only if avail_in >= X */ +}; + +#define GET_DFLTCC_DEFLATE_STATE(state) ((struct dfltcc_deflate_state *)GET_DFLTCC_STATE(state)) + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp) strm) { + return dfltcc_alloc_state(strm, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + dfltcc_reset_state(&dfltcc_state->common); + + /* Initialize tuning parameters */ + dfltcc_state->level_mask = DFLTCC_LEVEL_MASK; + dfltcc_state->block_size = DFLTCC_BLOCK_SIZE; + dfltcc_state->block_threshold = DFLTCC_FIRST_FHT_BLOCK_SIZE; + dfltcc_state->dht_threshold = DFLTCC_DHT_MIN_SAMPLE_SIZE; +} + +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src) { + dfltcc_copy_state(dst, src, sizeof(deflate_state), sizeof(struct dfltcc_deflate_state)); +} + +static inline int dfltcc_can_deflate_with_params(PREFIX3(streamp) strm, int level, uInt window_bits, int strategy, + int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + + /* Unsupported compression settings */ + if ((dfltcc_state->level_mask & (1 << level)) == 0) + return 0; + if (window_bits != HB_BITS) + return 0; + if (strategy != Z_FIXED && strategy != Z_DEFAULT_STRATEGY) + return 0; + if (reproducible) + return 0; + + /* Unsupported hardware */ + if (!is_bit_set(dfltcc_state->common.af.fns, DFLTCC_GDHT) || + !is_bit_set(dfltcc_state->common.af.fns, DFLTCC_CMPR) || + !is_bit_set(dfltcc_state->common.af.fmts, DFLTCC_FMT0)) + return 0; + + return 1; +} + +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + + return dfltcc_can_deflate_with_params(strm, state->level, state->w_bits, state->strategy, state->reproducible); +} + +static inline void dfltcc_gdht(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + + dfltcc(DFLTCC_GDHT, param, NULL, NULL, &strm->next_in, &avail_in, NULL); +} + +static inline dfltcc_cc dfltcc_cmpr(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_CMPR | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->total_in += (strm->avail_in - avail_in); + strm->total_out += (strm->avail_out - avail_out); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +static inline void send_eobs(PREFIX3(streamp) strm, const struct dfltcc_param_v0 *param) { + deflate_state *state = (deflate_state *)strm->state; + + send_bits(state, PREFIX(bi_reverse)(param->eobs >> (15 - param->eobl), param->eobl), param->eobl, state->bi_buf, state->bi_valid); + PREFIX(flush_pending)(strm); + if (state->pending != 0) { + /* The remaining data is located in pending_out[0:pending]. If someone + * calls put_byte() - this might happen in deflate() - the byte will be + * placed into pending_buf[pending], which is incorrect. Move the + * remaining data to the beginning of pending_buf so that put_byte() is + * usable again. + */ + memmove(state->pending_buf, state->pending_out, state->pending); + state->pending_out = state->pending_buf; + } +#ifdef ZLIB_DEBUG + state->compressed_len += param->eobl; +#endif +} + +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_deflate_state *dfltcc_state = GET_DFLTCC_DEFLATE_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->common.param; + uInt masked_avail_in; + dfltcc_cc cc; + int need_empty_block; + int soft_bcc; + int no_flush; + + if (!PREFIX(dfltcc_can_deflate)(strm)) { + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + return 0; + } + +again: + masked_avail_in = 0; + soft_bcc = 0; + no_flush = flush == Z_NO_FLUSH; + + /* No input data. Return, except when Continuation Flag is set, which means + * that DFLTCC has buffered some output in the parameter block and needs to + * be called again in order to flush it. + */ + if (strm->avail_in == 0 && !param->cf) { + /* A block is still open, and the hardware does not support closing + * blocks without adding data. Thus, close it manually. + */ + if (!no_flush && param->bcf) { + send_eobs(strm, param); + param->bcf = 0; + } + /* Let one of deflate_* functions write a trailing empty block. */ + if (flush == Z_FINISH) + return 0; + /* Clear history. */ + if (flush == Z_FULL_FLUSH) + param->hl = 0; + /* Trigger block post-processing if necessary. */ + *result = no_flush ? need_more : block_done; + return 1; + } + + /* There is an open non-BFINAL block, we are not going to close it just + * yet, we have compressed more than DFLTCC_BLOCK_SIZE bytes and we see + * more than DFLTCC_DHT_MIN_SAMPLE_SIZE bytes. Open a new block with a new + * DHT in order to adapt to a possibly changed input data distribution. + */ + if (param->bcf && no_flush && + strm->total_in > dfltcc_state->block_threshold && + strm->avail_in >= dfltcc_state->dht_threshold) { + if (param->cf) { + /* We need to flush the DFLTCC buffer before writing the + * End-of-block Symbol. Mask the input data and proceed as usual. + */ + masked_avail_in += strm->avail_in; + strm->avail_in = 0; + no_flush = 0; + } else { + /* DFLTCC buffer is empty, so we can manually write the + * End-of-block Symbol right away. + */ + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } + } + + /* No space for compressed data. If we proceed, dfltcc_cmpr() will return + * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still + * set BCF=1, which is wrong. Avoid complications and return early. + */ + if (strm->avail_out == 0) { + *result = need_more; + return 1; + } + + /* The caller gave us too much data. Pass only one block worth of + * uncompressed data to DFLTCC and mask the rest, so that on the next + * iteration we start a new block. + */ + if (no_flush && strm->avail_in > dfltcc_state->block_size) { + masked_avail_in += (strm->avail_in - dfltcc_state->block_size); + strm->avail_in = dfltcc_state->block_size; + } + + /* When we have an open non-BFINAL deflate block and caller indicates that + * the stream is ending, we need to close an open deflate block and open a + * BFINAL one. + */ + need_empty_block = flush == Z_FINISH && param->bcf && !param->bhf; + + /* Translate stream to parameter block */ + param->cvt = state->wrap == 2 ? CVT_CRC32 : CVT_ADLER32; + if (!no_flush) + /* We need to close a block. Always do this in software - when there is + * no input data, the hardware will not honor BCC. */ + soft_bcc = 1; + if (flush == Z_FINISH && !param->bcf) + /* We are about to open a BFINAL block, set Block Header Final bit + * until the stream ends. + */ + param->bhf = 1; + /* DFLTCC-CMPR will write to next_out, so make sure that buffers with + * higher precedence are empty. + */ + Assert(state->pending == 0, "There must be no pending bytes"); + Assert(state->bi_valid < 8, "There must be less than 8 pending bits"); + param->sbb = (unsigned int)state->bi_valid; + if (param->sbb > 0) + *strm->next_out = (unsigned char)state->bi_buf; + /* Honor history and check value */ + param->nt = 0; + if (state->wrap == 1) + param->cv = strm->adler; + else if (state->wrap == 2) + param->cv = ZSWAP32(state->crc_fold.value); + + /* When opening a block, choose a Huffman-Table Type */ + if (!param->bcf) { + if (state->strategy == Z_FIXED || (strm->total_in == 0 && dfltcc_state->block_threshold > 0)) + param->htt = HTT_FIXED; + else { + param->htt = HTT_DYNAMIC; + dfltcc_gdht(strm); + } + } + + /* Deflate */ + do { + cc = dfltcc_cmpr(strm); + if (strm->avail_in < 4096 && masked_avail_in > 0) + /* We are about to call DFLTCC with a small input buffer, which is + * inefficient. Since there is masked data, there will be at least + * one more DFLTCC call, so skip the current one and make the next + * one handle more data. + */ + break; + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->common.msg, param->oesc); + state->bi_valid = param->sbb; + if (state->bi_valid == 0) + state->bi_buf = 0; /* Avoid accessing next_out */ + else + state->bi_buf = *strm->next_out & ((1 << state->bi_valid) - 1); + if (state->wrap == 1) + strm->adler = param->cv; + else if (state->wrap == 2) + state->crc_fold.value = ZSWAP32(param->cv); + + /* Unmask the input data */ + strm->avail_in += masked_avail_in; + masked_avail_in = 0; + + /* If we encounter an error, it means there is a bug in DFLTCC call */ + Assert(cc != DFLTCC_CC_OP2_CORRUPT || param->oesc == 0, "BUG"); + + /* Update Block-Continuation Flag. It will be used to check whether to call + * GDHT the next time. + */ + if (cc == DFLTCC_CC_OK) { + if (soft_bcc) { + send_eobs(strm, param); + param->bcf = 0; + dfltcc_state->block_threshold = strm->total_in + dfltcc_state->block_size; + } else + param->bcf = 1; + if (flush == Z_FINISH) { + if (need_empty_block) + /* Make the current deflate() call also close the stream */ + return 0; + else { + bi_windup(state); + *result = finish_done; + } + } else { + if (flush == Z_FULL_FLUSH) + param->hl = 0; /* Clear history */ + *result = flush == Z_NO_FLUSH ? need_more : block_done; + } + } else { + param->bcf = 1; + *result = need_more; + } + if (strm->avail_in != 0 && strm->avail_out != 0) + goto again; /* deflate() must use all input or all output */ + return 1; +} + +/* + Switching between hardware and software compression. + + DFLTCC does not support all zlib settings, e.g. generation of non-compressed + blocks or alternative window sizes. When such settings are applied on the + fly with deflateParams, we need to convert between hardware and software + window formats. +*/ +static int dfltcc_was_deflate_used(PREFIX3(streamp) strm) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return strm->total_in > 0 || param->nt == 0 || param->hl > 0; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush) { + deflate_state *state = (deflate_state *)strm->state; + int could_deflate = PREFIX(dfltcc_can_deflate)(strm); + int can_deflate = dfltcc_can_deflate_with_params(strm, level, state->w_bits, strategy, state->reproducible); + + if (can_deflate == could_deflate) + /* We continue to work in the same mode - no changes needed */ + return Z_OK; + + if (!dfltcc_was_deflate_used(strm)) + /* DFLTCC was not used yet - no changes needed */ + return Z_OK; + + /* For now, do not convert between window formats - simply get rid of the old data instead */ + *flush = Z_FULL_FLUSH; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might + * close the block without resetting the compression state. Detect this + * situation and return that deflation is not done. + */ + if (flush == Z_FULL_FLUSH && strm->avail_out == 0) + return 0; + + /* Return that deflation is not done if DFLTCC is used and either it + * buffered some data (Continuation Flag is set), or has not written EOBS + * yet (Block-Continuation Flag is set). + */ + return !PREFIX(dfltcc_can_deflate)(strm) || (!param->cf && !param->bcf); +} + +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible) { + deflate_state *state = (deflate_state *)strm->state; + + return reproducible != state->reproducible && !dfltcc_was_deflate_used(strm); +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + append_history(param, state->window, dictionary, dict_length); + state->strstart = 1; /* Add FDICT to zlib header */ + state->block_start = state->strstart; /* Make deflate_stored happy */ + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt *dict_length) { + deflate_state *state = (deflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.h new file mode 100644 index 000000000..cb261b156 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_deflate.h @@ -0,0 +1,60 @@ +#ifndef DFLTCC_DEFLATE_H +#define DFLTCC_DEFLATE_H + +#include "dfltcc_common.h" + +void Z_INTERNAL *PREFIX(dfltcc_alloc_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_reset_deflate_state)(PREFIX3(streamp)); +void Z_INTERNAL PREFIX(dfltcc_copy_deflate_state)(void *dst, const void *src); +int Z_INTERNAL PREFIX(dfltcc_can_deflate)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_deflate)(PREFIX3(streamp) strm, int flush, block_state *result); +int Z_INTERNAL PREFIX(dfltcc_deflate_params)(PREFIX3(streamp) strm, int level, int strategy, int *flush); +int Z_INTERNAL PREFIX(dfltcc_deflate_done)(PREFIX3(streamp) strm, int flush); +int Z_INTERNAL PREFIX(dfltcc_can_set_reproducible)(PREFIX3(streamp) strm, int reproducible); +int Z_INTERNAL PREFIX(dfltcc_deflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_deflate_get_dictionary)(PREFIX3(streamp) strm, unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_DEFLATE_STATE PREFIX(dfltcc_alloc_deflate_state) +#define ZCOPY_DEFLATE_STATE PREFIX(dfltcc_copy_deflate_state) + +#define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_deflate)((strm))) \ + return PREFIX(dfltcc_deflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define DEFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_deflate_state) + +#define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) \ + do { \ + int err; \ +\ + err = PREFIX(dfltcc_deflate_params)((strm), (level), (strategy), (hook_flush)); \ + if (err == Z_STREAM_ERROR) \ + return err; \ + } while (0) + +#define DEFLATE_DONE PREFIX(dfltcc_deflate_done) + +#define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \ + do { \ + if (deflateStateCheck((strm)) || PREFIX(dfltcc_can_deflate)((strm))) \ + (complen) = DEFLATE_BOUND_COMPLEN(source_len); \ + } while (0) + +#define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) (PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_HOOK PREFIX(dfltcc_deflate) + +#define DEFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_deflate)((strm))) + +#define DEFLATE_CAN_SET_REPRODUCIBLE PREFIX(dfltcc_can_set_reproducible) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_detail.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_detail.h new file mode 100644 index 000000000..354c2f555 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_detail.h @@ -0,0 +1,312 @@ +#include "../../zbuild.h" +#include + +#ifdef HAVE_SYS_SDT_H +#include +#endif + +/* + Tuning parameters. + */ +#ifndef DFLTCC_LEVEL_MASK +#define DFLTCC_LEVEL_MASK 0x2 +#endif +#ifndef DFLTCC_BLOCK_SIZE +#define DFLTCC_BLOCK_SIZE 1048576 +#endif +#ifndef DFLTCC_FIRST_FHT_BLOCK_SIZE +#define DFLTCC_FIRST_FHT_BLOCK_SIZE 4096 +#endif +#ifndef DFLTCC_DHT_MIN_SAMPLE_SIZE +#define DFLTCC_DHT_MIN_SAMPLE_SIZE 4096 +#endif +#ifndef DFLTCC_RIBM +#define DFLTCC_RIBM 0 +#endif + +/* + Parameter Block for Query Available Functions. + */ +#define static_assert(c, msg) __attribute__((unused)) static char static_assert_failed_ ## msg[c ? 1 : -1] + +struct dfltcc_qaf_param { + char fns[16]; + char reserved1[8]; + char fmts[2]; + char reserved2[6]; +}; + +#define DFLTCC_SIZEOF_QAF 32 +static_assert(sizeof(struct dfltcc_qaf_param) == DFLTCC_SIZEOF_QAF, qaf); + +static inline int is_bit_set(const char *bits, int n) { + return bits[n / 8] & (1 << (7 - (n % 8))); +} + +static inline void clear_bit(char *bits, int n) { + bits[n / 8] &= ~(1 << (7 - (n % 8))); +} + +#define DFLTCC_FACILITY 151 + +static inline int is_dfltcc_enabled(void) { + uint64_t facilities[(DFLTCC_FACILITY / 64) + 1]; + Z_REGISTER uint8_t r0 __asm__("r0"); + + memset(facilities, 0, sizeof(facilities)); + r0 = sizeof(facilities) / sizeof(facilities[0]) - 1; + /* STFLE is supported since z9-109 and only in z/Architecture mode. When + * compiling with -m31, gcc defaults to ESA mode, however, since the kernel + * is 64-bit, it's always z/Architecture mode at runtime. + */ + __asm__ volatile( +#ifndef __clang__ + ".machinemode push\n" + ".machinemode zarch\n" +#endif + "stfle %[facilities]\n" +#ifndef __clang__ + ".machinemode pop\n" +#endif + : [facilities] "=Q" (facilities), [r0] "+r" (r0) :: "cc"); + return is_bit_set((const char *)facilities, DFLTCC_FACILITY); +} + +#define DFLTCC_FMT0 0 + +/* + Parameter Block for Generate Dynamic-Huffman Table, Compress and Expand. + */ +#define CVT_CRC32 0 +#define CVT_ADLER32 1 +#define HTT_FIXED 0 +#define HTT_DYNAMIC 1 + +struct dfltcc_param_v0 { + uint16_t pbvn; /* Parameter-Block-Version Number */ + uint8_t mvn; /* Model-Version Number */ + uint8_t ribm; /* Reserved for IBM use */ + uint32_t reserved32 : 31; + uint32_t cf : 1; /* Continuation Flag */ + uint8_t reserved64[8]; + uint32_t nt : 1; /* New Task */ + uint32_t reserved129 : 1; + uint32_t cvt : 1; /* Check Value Type */ + uint32_t reserved131 : 1; + uint32_t htt : 1; /* Huffman-Table Type */ + uint32_t bcf : 1; /* Block-Continuation Flag */ + uint32_t bcc : 1; /* Block Closing Control */ + uint32_t bhf : 1; /* Block Header Final */ + uint32_t reserved136 : 1; + uint32_t reserved137 : 1; + uint32_t dhtgc : 1; /* DHT Generation Control */ + uint32_t reserved139 : 5; + uint32_t reserved144 : 5; + uint32_t sbb : 3; /* Sub-Byte Boundary */ + uint8_t oesc; /* Operation-Ending-Supplemental Code */ + uint32_t reserved160 : 12; + uint32_t ifs : 4; /* Incomplete-Function Status */ + uint16_t ifl; /* Incomplete-Function Length */ + uint8_t reserved192[8]; + uint8_t reserved256[8]; + uint8_t reserved320[4]; + uint16_t hl; /* History Length */ + uint32_t reserved368 : 1; + uint16_t ho : 15; /* History Offset */ + uint32_t cv; /* Check Value */ + uint32_t eobs : 15; /* End-of-block Symbol */ + uint32_t reserved431: 1; + uint8_t eobl : 4; /* End-of-block Length */ + uint32_t reserved436 : 12; + uint32_t reserved448 : 4; + uint16_t cdhtl : 12; /* Compressed-Dynamic-Huffman Table + Length */ + uint8_t reserved464[6]; + uint8_t cdht[288]; /* Compressed-Dynamic-Huffman Table */ + uint8_t reserved[24]; + uint8_t ribm2[8]; /* Reserved for IBM use */ + uint8_t csb[1152]; /* Continuation-State Buffer */ +}; + +#define DFLTCC_SIZEOF_GDHT_V0 384 +#define DFLTCC_SIZEOF_CMPR_XPND_V0 1536 +static_assert(offsetof(struct dfltcc_param_v0, csb) == DFLTCC_SIZEOF_GDHT_V0, gdht_v0); +static_assert(sizeof(struct dfltcc_param_v0) == DFLTCC_SIZEOF_CMPR_XPND_V0, cmpr_xpnd_v0); + +static inline z_const char *oesc_msg(char *buf, int oesc) { + if (oesc == 0x00) + return NULL; /* Successful completion */ + else { + sprintf(buf, "Operation-Ending-Supplemental Code is 0x%.2X", oesc); + return buf; + } +} + +/* + C wrapper for the DEFLATE CONVERSION CALL instruction. + */ +typedef enum { + DFLTCC_CC_OK = 0, + DFLTCC_CC_OP1_TOO_SHORT = 1, + DFLTCC_CC_OP2_TOO_SHORT = 2, + DFLTCC_CC_OP2_CORRUPT = 2, + DFLTCC_CC_AGAIN = 3, +} dfltcc_cc; + +#define DFLTCC_QAF 0 +#define DFLTCC_GDHT 1 +#define DFLTCC_CMPR 2 +#define DFLTCC_XPND 4 +#define HBT_CIRCULAR (1 << 7) +#define DFLTCC_FN_MASK ((1 << 7) - 1) +#define HB_BITS 15 +#define HB_SIZE (1 << HB_BITS) + +static inline dfltcc_cc dfltcc(int fn, void *param, + unsigned char **op1, size_t *len1, + z_const unsigned char **op2, size_t *len2, void *hist) { + unsigned char *t2 = op1 ? *op1 : NULL; +#ifdef Z_MEMORY_SANITIZER + unsigned char *orig_t2 = t2; +#endif + size_t t3 = len1 ? *len1 : 0; + z_const unsigned char *t4 = op2 ? *op2 : NULL; + size_t t5 = len2 ? *len2 : 0; + Z_REGISTER int r0 __asm__("r0") = fn; + Z_REGISTER void *r1 __asm__("r1") = param; + Z_REGISTER unsigned char *r2 __asm__("r2") = t2; + Z_REGISTER size_t r3 __asm__("r3") = t3; + Z_REGISTER z_const unsigned char *r4 __asm__("r4") = t4; + Z_REGISTER size_t r5 __asm__("r5") = t5; + int cc; + + __asm__ volatile( +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_entry, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + ".insn rrf,0xb9390000,%[r2],%[r4],%[hist],0\n" +#ifdef HAVE_SYS_SDT_H + STAP_PROBE_ASM(zlib, dfltcc_exit, STAP_PROBE_ASM_TEMPLATE(5)) +#endif + "ipm %[cc]\n" + : [r2] "+r" (r2) + , [r3] "+r" (r3) + , [r4] "+r" (r4) + , [r5] "+r" (r5) + , [cc] "=r" (cc) + : [r0] "r" (r0) + , [r1] "r" (r1) + , [hist] "r" (hist) +#ifdef HAVE_SYS_SDT_H + , STAP_PROBE_ASM_OPERANDS(5, r2, r3, r4, r5, hist) +#endif + : "cc", "memory"); + t2 = r2; t3 = r3; t4 = r4; t5 = r5; + +#ifdef Z_MEMORY_SANITIZER + switch (fn & DFLTCC_FN_MASK) { + case DFLTCC_QAF: + __msan_unpoison(param, DFLTCC_SIZEOF_QAF); + break; + case DFLTCC_GDHT: + __msan_unpoison(param, DFLTCC_SIZEOF_GDHT_V0); + break; + case DFLTCC_CMPR: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2 + (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1)); + break; + case DFLTCC_XPND: + __msan_unpoison(param, DFLTCC_SIZEOF_CMPR_XPND_V0); + __msan_unpoison(orig_t2, t2 - orig_t2); + break; + } +#endif + + if (op1) + *op1 = t2; + if (len1) + *len1 = t3; + if (op2) + *op2 = t4; + if (len2) + *len2 = t5; + return (cc >> 28) & 3; +} + +/* + Extension of inflate_state and deflate_state. Must be doubleword-aligned. +*/ +struct dfltcc_state { + struct dfltcc_param_v0 param; /* Parameter block. */ + struct dfltcc_qaf_param af; /* Available functions. */ + char msg[64]; /* Buffer for strm->msg */ +}; + +#define ALIGN_UP(p, size) (__typeof__(p))(((uintptr_t)(p) + ((size) - 1)) & ~((size) - 1)) + +#define GET_DFLTCC_STATE(state) ((struct dfltcc_state *)((char *)(state) + ALIGN_UP(sizeof(*state), 8))) + +static inline void *dfltcc_alloc_state(PREFIX3(streamp) strm, uInt size, uInt extension_size) { + return ZALLOC(strm, 1, ALIGN_UP(size, 8) + extension_size); +} + +static inline void dfltcc_reset_state(struct dfltcc_state *dfltcc_state) { + /* Initialize available functions */ + if (is_dfltcc_enabled()) { + dfltcc(DFLTCC_QAF, &dfltcc_state->param, NULL, NULL, NULL, NULL, NULL); + memmove(&dfltcc_state->af, &dfltcc_state->param, sizeof(dfltcc_state->af)); + } else + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + + /* Initialize parameter block */ + memset(&dfltcc_state->param, 0, sizeof(dfltcc_state->param)); + dfltcc_state->param.nt = 1; + dfltcc_state->param.ribm = DFLTCC_RIBM; +} + +static inline void dfltcc_copy_state(void *dst, const void *src, uInt size, uInt extension_size) { + memcpy(dst, src, ALIGN_UP(size, 8) + extension_size); +} + +static inline void append_history(struct dfltcc_param_v0 *param, unsigned char *history, + const unsigned char *buf, uInt count) { + size_t offset; + size_t n; + + /* Do not use more than 32K */ + if (count > HB_SIZE) { + buf += count - HB_SIZE; + count = HB_SIZE; + } + offset = (param->ho + param->hl) % HB_SIZE; + if (offset + count <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(history + offset, buf, count); + else { + /* Circular history buffer wraps - copy two chunks */ + n = HB_SIZE - offset; + memcpy(history + offset, buf, n); + memcpy(history, buf + n, count - n); + } + n = param->hl + count; + if (n <= HB_SIZE) + /* All history fits into buffer - no need to discard anything */ + param->hl = n; + else { + /* History does not fit into buffer - discard extra bytes */ + param->ho = (param->ho + (n - HB_SIZE)) % HB_SIZE; + param->hl = HB_SIZE; + } +} + +static inline void get_history(struct dfltcc_param_v0 *param, const unsigned char *history, + unsigned char *buf) { + if (param->ho + param->hl <= HB_SIZE) + /* Circular history buffer does not wrap - copy one chunk */ + memcpy(buf, history + param->ho, param->hl); + else { + /* Circular history buffer wraps - copy two chunks */ + memcpy(buf, history + param->ho, HB_SIZE - param->ho); + memcpy(buf + HB_SIZE - param->ho, history, param->ho + param->hl - HB_SIZE); + } +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.c new file mode 100644 index 000000000..f0d3951b5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.c @@ -0,0 +1,205 @@ +/* dfltcc_inflate.c - IBM Z DEFLATE CONVERSION CALL decompression support. */ + +/* + Use the following commands to build zlib-ng with DFLTCC decompression support: + + $ ./configure --with-dfltcc-inflate + or + + $ cmake -DWITH_DFLTCC_INFLATE=1 . + + and then + + $ make +*/ + +#include "zbuild.h" +#include "zutil.h" +#include "inftrees.h" +#include "inflate.h" +#include "dfltcc_inflate.h" +#include "dfltcc_detail.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm) { + return (struct inflate_state *)dfltcc_alloc_state(strm, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + dfltcc_reset_state(dfltcc_state); +} + +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src) { + dfltcc_copy_state(dst, src, sizeof(struct inflate_state), sizeof(struct dfltcc_state)); +} + +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + + /* Unsupported hardware */ + return is_bit_set(dfltcc_state->af.fns, DFLTCC_XPND) && is_bit_set(dfltcc_state->af.fmts, DFLTCC_FMT0); +} + +static inline dfltcc_cc dfltcc_xpnd(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + size_t avail_in = strm->avail_in; + size_t avail_out = strm->avail_out; + dfltcc_cc cc; + + cc = dfltcc(DFLTCC_XPND | HBT_CIRCULAR, + param, &strm->next_out, &avail_out, + &strm->next_in, &avail_in, state->window); + strm->avail_in = avail_in; + strm->avail_out = avail_out; + return cc; +} + +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + dfltcc_cc cc; + + if (flush == Z_BLOCK || flush == Z_TREES) { + /* DFLTCC does not support stopping on block boundaries */ + if (PREFIX(dfltcc_inflate_disable)(strm)) { + *ret = Z_STREAM_ERROR; + return DFLTCC_INFLATE_BREAK; + } else + return DFLTCC_INFLATE_SOFTWARE; + } + + if (state->last) { + if (state->bits != 0) { + strm->next_in++; + strm->avail_in--; + state->bits = 0; + } + state->mode = CHECK; + return DFLTCC_INFLATE_CONTINUE; + } + + if (strm->avail_in == 0 && !param->cf) + return DFLTCC_INFLATE_BREAK; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return DFLTCC_INFLATE_CONTINUE; + } + + /* Translate stream to parameter block */ + param->cvt = ((state->wrap & 4) && state->flags) ? CVT_CRC32 : CVT_ADLER32; + param->sbb = state->bits; + if (param->hl) + param->nt = 0; /* Honor history for the first block */ + if (state->wrap & 4) + param->cv = state->flags ? ZSWAP32(state->check) : state->check; + + /* Inflate */ + do { + cc = dfltcc_xpnd(strm); + } while (cc == DFLTCC_CC_AGAIN); + + /* Translate parameter block to stream */ + strm->msg = oesc_msg(dfltcc_state->msg, param->oesc); + state->last = cc == DFLTCC_CC_OK; + state->bits = param->sbb; + if (state->wrap & 4) + strm->adler = state->check = state->flags ? ZSWAP32(param->cv) : param->cv; + if (cc == DFLTCC_CC_OP2_CORRUPT && param->oesc != 0) { + /* Report an error if stream is corrupted */ + state->mode = BAD; + return DFLTCC_INFLATE_CONTINUE; + } + state->mode = TYPEDO; + /* Break if operands are exhausted, otherwise continue looping */ + return (cc == DFLTCC_CC_OP1_TOO_SHORT || cc == DFLTCC_CC_OP2_TOO_SHORT) ? + DFLTCC_INFLATE_BREAK : DFLTCC_INFLATE_CONTINUE; +} + +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_param_v0 *param = &GET_DFLTCC_STATE(state)->param; + + return !param->nt; +} + +/* + Rotates a circular buffer. + The implementation is based on https://cplusplus.com/reference/algorithm/rotate/ + */ +static void rotate(unsigned char *start, unsigned char *pivot, unsigned char *end) { + unsigned char *p = pivot; + unsigned char tmp; + + while (p != start) { + tmp = *start; + *start = *p; + *p = tmp; + + start++; + p++; + + if (p == end) + p = pivot; + else if (start == pivot) + pivot = p; + } +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (!PREFIX(dfltcc_can_inflate)(strm)) + return 0; + if (PREFIX(dfltcc_was_inflate_used)(strm)) + /* DFLTCC has already decompressed some data. Since there is not + * enough information to resume decompression in software, the call + * must fail. + */ + return 1; + /* DFLTCC was not used yet - decompress in software */ + memset(&dfltcc_state->af, 0, sizeof(dfltcc_state->af)); + /* Convert the window from the hardware to the software format */ + rotate(state->window, state->window + param->ho, state->window + HB_SIZE); + state->whave = state->wnext = MIN(param->hl, state->wsize); + return 0; +} + +/* + Preloading history. +*/ +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (PREFIX(inflate_ensure_window)(state)) { + state->mode = MEM; + return Z_MEM_ERROR; + } + + append_history(param, state->window, dictionary, dict_length); + state->havedict = 1; + return Z_OK; +} + +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt *dict_length) { + struct inflate_state *state = (struct inflate_state *)strm->state; + struct dfltcc_state *dfltcc_state = GET_DFLTCC_STATE(state); + struct dfltcc_param_v0 *param = &dfltcc_state->param; + + if (dictionary && state->window) + get_history(param, state->window, dictionary); + if (dict_length) + *dict_length = param->hl; + return Z_OK; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.h new file mode 100644 index 000000000..632fada62 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/dfltcc_inflate.h @@ -0,0 +1,70 @@ +#ifndef DFLTCC_INFLATE_H +#define DFLTCC_INFLATE_H + +#include "dfltcc_common.h" + +struct inflate_state Z_INTERNAL *PREFIX(dfltcc_alloc_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_reset_inflate_state)(PREFIX3(streamp) strm); +void Z_INTERNAL PREFIX(dfltcc_copy_inflate_state)(struct inflate_state *dst, const struct inflate_state *src); +int Z_INTERNAL PREFIX(dfltcc_can_inflate)(PREFIX3(streamp) strm); +typedef enum { + DFLTCC_INFLATE_CONTINUE, + DFLTCC_INFLATE_BREAK, + DFLTCC_INFLATE_SOFTWARE, +} dfltcc_inflate_action; +dfltcc_inflate_action Z_INTERNAL PREFIX(dfltcc_inflate)(PREFIX3(streamp) strm, int flush, int *ret); +int Z_INTERNAL PREFIX(dfltcc_was_inflate_used)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_disable)(PREFIX3(streamp) strm); +int Z_INTERNAL PREFIX(dfltcc_inflate_set_dictionary)(PREFIX3(streamp) strm, + const unsigned char *dictionary, uInt dict_length); +int Z_INTERNAL PREFIX(dfltcc_inflate_get_dictionary)(PREFIX3(streamp) strm, + unsigned char *dictionary, uInt* dict_length); + +#define ZALLOC_INFLATE_STATE PREFIX(dfltcc_alloc_inflate_state) +#define ZCOPY_INFLATE_STATE PREFIX(dfltcc_copy_inflate_state) + +#define INFLATE_RESET_KEEP_HOOK PREFIX(dfltcc_reset_inflate_state) + +#define INFLATE_PRIME_HOOK(strm, bits, value) \ + do { if (PREFIX(dfltcc_inflate_disable)((strm))) return Z_STREAM_ERROR; } while (0) + +#define INFLATE_TYPEDO_HOOK(strm, flush) \ + if (PREFIX(dfltcc_can_inflate)((strm))) { \ + dfltcc_inflate_action action; \ +\ + RESTORE(); \ + action = PREFIX(dfltcc_inflate)((strm), (flush), &ret); \ + LOAD(); \ + if (action == DFLTCC_INFLATE_CONTINUE) \ + break; \ + else if (action == DFLTCC_INFLATE_BREAK) \ + goto inf_leave; \ + } + +#define INFLATE_NEED_CHECKSUM(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_NEED_UPDATEWINDOW(strm) (!PREFIX(dfltcc_can_inflate)((strm))) + +#define INFLATE_MARK_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return -(1L << 16); \ + } while (0) + +#define INFLATE_SYNC_POINT_HOOK(strm) \ + do { \ + if (PREFIX(dfltcc_was_inflate_used)((strm))) return Z_STREAM_ERROR; \ + } while (0) + +#define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_set_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) \ + do { \ + if (PREFIX(dfltcc_can_inflate)((strm))) \ + return PREFIX(dfltcc_inflate_get_dictionary)((strm), (dict), (dict_len)); \ + } while (0) + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.c new file mode 100644 index 000000000..82901060e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.c @@ -0,0 +1,14 @@ +#include "../../zbuild.h" +#include "s390_features.h" + +#ifdef HAVE_SYS_AUXV_H +# include +#endif + +#ifndef HWCAP_S390_VXRS +#define HWCAP_S390_VXRS HWCAP_S390_VX +#endif + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features) { + features->has_vx = getauxval(AT_HWCAP) & HWCAP_S390_VXRS; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.h new file mode 100644 index 000000000..b8ffef74d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/s390_features.h @@ -0,0 +1,10 @@ +#ifndef S390_FEATURES_H_ +#define S390_FEATURES_H_ + +struct s390_cpu_features { + int has_vx; +}; + +void Z_INTERNAL s390_check_features(struct s390_cpu_features *features); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.Dockerfile b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.Dockerfile new file mode 100644 index 000000000..136eec77a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.Dockerfile @@ -0,0 +1,45 @@ +# Self-Hosted IBM Z Github Actions Runner. + +# Temporary image: amd64 dependencies. +FROM amd64/ubuntu:20.04 as ld-prefix +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install ca-certificates libicu66 libssl1.1 + +# Main image. +FROM s390x/ubuntu:20.04 + +# Packages for zlib-ng testing. +ENV DEBIAN_FRONTEND=noninteractive +RUN apt-get update && apt-get -y install \ + clang-11 \ + cmake \ + curl \ + gcc \ + git \ + jq \ + libxml2-dev \ + libxslt-dev \ + llvm-11-tools \ + ninja-build \ + python-is-python3 \ + python3 \ + python3-dev \ + python3-pip + +# amd64 dependencies. +COPY --from=ld-prefix / /usr/x86_64-linux-gnu/ +RUN ln -fs ../lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /usr/x86_64-linux-gnu/lib64/ +RUN ln -fs /etc/resolv.conf /usr/x86_64-linux-gnu/etc/ +ENV QEMU_LD_PREFIX=/usr/x86_64-linux-gnu + +# amd64 Github Actions Runner. +RUN useradd -m actions-runner +USER actions-runner +WORKDIR /home/actions-runner +RUN curl -L https://github.com/actions/runner/releases/download/v2.287.1/actions-runner-linux-x64-2.287.1.tar.gz | tar -xz +VOLUME /home/actions-runner + +# Scripts. +COPY fs/ / +ENTRYPOINT ["/usr/bin/entrypoint"] +CMD ["/usr/bin/actions-runner"] diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.service b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.service new file mode 100644 index 000000000..71053a79d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/actions-runner.service @@ -0,0 +1,24 @@ +[Unit] +Description=Self-Hosted IBM Z Github Actions Runner +Wants=qemu-user-static +After=qemu-user-static +StartLimitIntervalSec=0 + +[Service] +Type=simple +Restart=always +ExecStartPre=-/usr/bin/docker rm --force actions-runner +ExecStart=/usr/bin/docker run \ + --env-file=/etc/actions-runner \ + --init \ + --interactive \ + --name=actions-runner \ + --rm \ + --volume=actions-runner:/home/actions-runner \ + iiilinuxibmcom/actions-runner +ExecStop=/bin/sh -c "docker exec actions-runner kill -INT -- -1" +ExecStop=/bin/sh -c "docker wait actions-runner" +ExecStop=/bin/sh -c "docker rm actions-runner" + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner new file mode 100755 index 000000000..c9d8227d4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/actions-runner @@ -0,0 +1,40 @@ +#!/bin/bash + +# +# Ephemeral runner startup script. +# +# Expects the following environment variables: +# +# - repo=/ +# - access_token= +# + +set -e -u + +# Check the cached registration token. +token_file=registration-token.json +set +e +expires_at=$(jq --raw-output .expires_at "$token_file" 2>/dev/null) +status=$? +set -e +if [[ $status -ne 0 || $(date +%s) -ge $(date -d "$expires_at" +%s) ]]; then + # Refresh the cached registration token. + curl \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $access_token" \ + "https://api.github.com/repos/$repo/actions/runners/registration-token" \ + -o "$token_file" +fi + +# (Re-)register the runner. +registration_token=$(jq --raw-output .token "$token_file") +./config.sh remove --token "$registration_token" || true +./config.sh \ + --url "https://github.com/$repo" \ + --token "$registration_token" \ + --labels z15 \ + --ephemeral + +# Run one job. +./run.sh diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint new file mode 100755 index 000000000..eb8772bec --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/fs/usr/bin/entrypoint @@ -0,0 +1,30 @@ +#!/bin/bash + +# +# Container entrypoint that waits for all spawned processes. +# + +set -e -u + +# Create a FIFO and start reading from its read end. +tempdir=$(mktemp -d "/tmp/done.XXXXXXXXXX") +trap 'rm -r "$tempdir"' EXIT +done="$tempdir/pipe" +mkfifo "$done" +cat "$done" & waiter=$! + +# Start the workload. Its descendants will inherit the FIFO's write end. +status=0 +if [ "$#" -eq 0 ]; then + bash 9>"$done" || status=$? +else + "$@" 9>"$done" || status=$? +fi + +# When the workload and all of its descendants exit, the FIFO's write end will +# be closed and `cat "$done"` will exit. Wait until it happens. This is needed +# in order to handle SelfUpdater, which the workload may start in background +# before exiting. +wait "$waiter" + +exit "$status" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/qemu-user-static.service b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/qemu-user-static.service new file mode 100644 index 000000000..301f3edd9 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/s390/self-hosted-builder/qemu-user-static.service @@ -0,0 +1,11 @@ +[Unit] +Description=Support for transparent execution of non-native binaries with QEMU user emulation + +[Service] +Type=oneshot +# The source code for iiilinuxibmcom/qemu-user-static is at https://github.com/iii-i/qemu-user-static/tree/v6.1.0-1 +# TODO: replace it with multiarch/qemu-user-static once version >6.1 is available +ExecStart=/usr/bin/docker run --rm --interactive --privileged iiilinuxibmcom/qemu-user-static --reset -p yes + +[Install] +WantedBy=multi-user.target diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/Makefile.in b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/Makefile.in new file mode 100644 index 000000000..f0478bfdc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/Makefile.in @@ -0,0 +1,147 @@ +# Makefile for zlib +# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler +# For conditions of distribution and use, see copyright notice in zlib.h + +CC= +CFLAGS= +SFLAGS= +INCLUDES= +SUFFIX= + +AVX512FLAG=-mavx512f -mavx512dq -mavx512vl -mavx512bw +AVX512VNNIFLAG=-mavx512vnni +AVX2FLAG=-mavx2 +SSE2FLAG=-msse2 +SSSE3FLAG=-mssse3 +SSE42FLAG=-msse4.2 +PCLMULFLAG=-mpclmul +VPCLMULFLAG=-mvpclmulqdq +XSAVEFLAG=-mxsave +NOLTOFLAG= + +SRCDIR=. +SRCTOP=../.. +TOPDIR=$(SRCTOP) + +all: \ + x86_features.o x86_features.lo \ + adler32_avx2.o adler32_avx2.lo \ + adler32_avx512.o adler32_avx512.lo \ + adler32_avx512_vnni.o adler32_avx512_vnni.lo \ + adler32_sse42.o adler32_sse42.lo \ + adler32_ssse3.o adler32_ssse3.lo \ + chunkset_avx2.o chunkset_avx2.lo \ + chunkset_sse2.o chunkset_sse2.lo \ + chunkset_ssse3.o chunkset_ssse3.lo \ + compare256_avx2.o compare256_avx2.lo \ + compare256_sse2.o compare256_sse2.lo \ + insert_string_sse42.o insert_string_sse42.lo \ + crc32_pclmulqdq.o crc32_pclmulqdq.lo \ + crc32_vpclmulqdq.o crc32_vpclmulqdq.lo \ + slide_hash_avx2.o slide_hash_avx2.lo \ + slide_hash_sse2.o slide_hash_sse2.lo + +x86_features.o: + $(CC) $(CFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +x86_features.lo: + $(CC) $(SFLAGS) $(XSAVEFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/x86_features.c + +chunkset_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_avx2.c + +chunkset_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_sse2.c + +chunkset_ssse3.o: + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +chunkset_ssse3.lo: + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/chunkset_ssse3.c + +compare256_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_avx2.c + +compare256_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +compare256_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/compare256_sse2.c + +insert_string_sse42.o: + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +insert_string_sse42.lo: + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/insert_string_sse42.c + +crc32_pclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_pclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_pclmulqdq.c + +crc32_vpclmulqdq.o: + $(CC) $(CFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +crc32_vpclmulqdq.lo: + $(CC) $(SFLAGS) $(PCLMULFLAG) $(SSE42FLAG) $(VPCLMULFLAG) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/crc32_vpclmulqdq.c + +slide_hash_avx2.o: + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_avx2.lo: + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_avx2.c + +slide_hash_sse2.o: + $(CC) $(CFLAGS) $(SSE2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +slide_hash_sse2.lo: + $(CC) $(SFLAGS) $(SSE2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/slide_hash_sse2.c + +adler32_avx2.o: $(SRCDIR)/adler32_avx2.c + $(CC) $(CFLAGS) $(AVX2FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx2.lo: $(SRCDIR)/adler32_avx2.c + $(CC) $(SFLAGS) $(AVX2FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx2.c + +adler32_avx512.o: $(SRCDIR)/adler32_avx512.c + $(CC) $(CFLAGS) $(AVX512FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512.lo: $(SRCDIR)/adler32_avx512.c + $(CC) $(SFLAGS) $(AVX512FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512.c + +adler32_avx512_vnni.o: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(CFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_avx512_vnni.lo: $(SRCDIR)/adler32_avx512_vnni.c + $(CC) $(SFLAGS) $(AVX512VNNIFLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_avx512_vnni.c + +adler32_ssse3.o: $(SRCDIR)/adler32_ssse3.c + $(CC) $(CFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_ssse3.lo: $(SRCDIR)/adler32_ssse3.c + $(CC) $(SFLAGS) $(SSSE3FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_ssse3.c + +adler32_sse42.o: $(SRCDIR)/adler32_sse42.c + $(CC) $(CFLAGS) $(SSE42FLAG) $(NOLTOFLAG) $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +adler32_sse42.lo: $(SRCDIR)/adler32_sse42.c + $(CC) $(SFLAGS) $(SSE42FLAG) $(NOLTOFLAG) -DPIC $(INCLUDES) -c -o $@ $(SRCDIR)/adler32_sse42.c + +mostlyclean: clean +clean: + rm -f *.o *.lo *~ + rm -rf objs + rm -f *.gcda *.gcno *.gcov + +distclean: + rm -f Makefile diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2.c new file mode 100644 index 000000000..797d299e0 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2.c @@ -0,0 +1,17 @@ +/* adler32_avx2.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include + +#ifdef X86_AVX2 + +#include "adler32_avx2_tpl.h" + +#define COPY +#include "adler32_avx2_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_p.h new file mode 100644 index 000000000..f0f8a4a88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_p.h @@ -0,0 +1,32 @@ +/* adler32_avx2_p.h -- adler32 avx2 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_AVX2_P_H_ +#define ADLER32_AVX2_P_H_ + +#if defined(X86_AVX2) || defined(X86_AVX512VNNI) + +/* 32 bit horizontal sum, adapted from Agner Fog's vector library. */ +static inline uint32_t hsum256(__m256i x) { + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(x, 1), + _mm256_castsi256_si128(x)); + __m128i sum2 = _mm_add_epi32(sum1, _mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +static inline uint32_t partial_hsum256(__m256i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros */ + const __m256i perm_vec = _mm256_setr_epi32(0, 2, 4, 6, 1, 1, 1, 1); + __m256i non_zero = _mm256_permutevar8x32_epi32(x, perm_vec); + __m128i non_zero_sse = _mm256_castsi256_si128(non_zero); + __m128i sum2 = _mm_add_epi32(non_zero_sse,_mm_unpackhi_epi64(non_zero_sse, non_zero_sse)); + __m128i sum3 = _mm_add_epi32(sum2, _mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_tpl.h new file mode 100644 index 000000000..a94f44b4f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx2_tpl.h @@ -0,0 +1,141 @@ +/* adler32_avx2_tpl.h -- adler32 avx2 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include +#include "../../adler32_fold.h" +#include "../../adler32_p.h" +#include "../../fallback_builtins.h" +#include "adler32_avx2_p.h" + +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *src, size_t len); + +#define copy_sub32(a, b, c, d) adler32_fold_copy_sse42(a, b, c, d) +#define sub32(a, b, c) adler32_ssse3(a, b, c) +#else +#define copy_sub32(a, b, c, d) adler32_copy_len_16(adler0, c, b, d, adler1) +#define sub32(a, b, c) adler32_len_16(adler0, b, c, adler1) +#endif + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx2(uint32_t adler, const uint8_t *src, size_t len) { +#endif + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { +#ifdef COPY + return adler32_copy_len_16(adler0, src, dst, len, adler1); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } else if (len < 32) { +#ifdef COPY + return copy_sub32(adler, dst, src, len); +#else + return sub32(adler, src, len); +#endif + } + + __m256i vs1, vs2; + + const __m256i dot2v = _mm256_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, + 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m256i dot3v = _mm256_set1_epi16(1); + const __m256i zero = _mm256_setzero_si256(); + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 32 vs1 + sum( (32-i+1) c[i] ) + */ + __m256i vbuf = _mm256_loadu_si256((__m256i*)src); + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf, zero); // Sum of abs diff, resulting in 2 x int32's + // +#ifdef COPY + _mm256_storeu_si256((__m256i*)dst, vbuf); + dst += 32; +#endif + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + __m256i v_short_sum2 = _mm256_maddubs_epi16(vbuf, dot2v); // sum 32 uint8s to 16 shorts + __m256i vsum2 = _mm256_madd_epi16(v_short_sum2, dot3v); // sum 16 shorts to 8 uint32s + vs2 = _mm256_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + /* Defer the multiplication with 32 to outside of the loop */ + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + + /* The compiler is generating the following sequence for this integer modulus + * when done the scalar way, in GPRs: + + adler = (s1_unpack[0] % BASE) + (s1_unpack[1] % BASE) + (s1_unpack[2] % BASE) + (s1_unpack[3] % BASE) + + (s1_unpack[4] % BASE) + (s1_unpack[5] % BASE) + (s1_unpack[6] % BASE) + (s1_unpack[7] % BASE); + + mov $0x80078071,%edi // move magic constant into 32 bit register %edi + ... + vmovd %xmm1,%esi // move vector lane 0 to 32 bit register %esi + mov %rsi,%rax // zero-extend this value to 64 bit precision in %rax + imul %rdi,%rsi // do a signed multiplication with magic constant and vector element + shr $0x2f,%rsi // shift right by 47 + imul $0xfff1,%esi,%esi // do a signed multiplication with value truncated to 32 bits with 0xfff1 + sub %esi,%eax // subtract lower 32 bits of original vector value from modified one above + ... + // repeats for each element with vpextract instructions + + This is tricky with AVX2 for a number of reasons: + 1.) There's no 64 bit multiplication instruction, but there is a sequence to get there + 2.) There's ways to extend vectors to 64 bit precision, but no simple way to truncate + back down to 32 bit precision later (there is in AVX512) + 3.) Full width integer multiplications aren't cheap + + We can, however, and do a relatively cheap sequence for horizontal sums. + Then, we simply do the integer modulus on the resulting 64 bit GPR, on a scalar value. It was + previously thought that casting to 64 bit precision was needed prior to the horizontal sum, but + that is simply not the case, as NMAX is defined as the maximum number of scalar sums that can be + performed on the maximum possible inputs before overflow + */ + + + /* In AVX2-land, this trip through GPRs will probably be unvoidable, as there's no cheap and easy + * conversion from 64 bit integer to 32 bit (needed for the inexpensive modulus with a constant). + * This casting to 32 bit is cheap through GPRs (just register aliasing). See above for exactly + * what the compiler is doing to avoid integer divisions. */ + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + if (len) { + goto rem_peel; + } + + return adler; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512.c new file mode 100644 index 000000000..e6ebb05dc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512.c @@ -0,0 +1,16 @@ +/* adler32_avx512.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512 + +#include "adler32_avx512_tpl.h" + +#define COPY +#include "adler32_avx512_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_p.h new file mode 100644 index 000000000..5b79d2ab6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_p.h @@ -0,0 +1,46 @@ +#ifndef AVX512_FUNCS_H +#define AVX512_FUNCS_H + +#include +#include +/* Written because *_add_epi32(a) sets off ubsan */ +static inline uint32_t _mm512_reduce_add_epu32(__m512i x) { + __m256i a = _mm512_extracti64x4_epi64(x, 1); + __m256i b = _mm512_extracti64x4_epi64(x, 0); + + __m256i a_plus_b = _mm256_add_epi32(a, b); + __m128i c = _mm256_extracti128_si256(a_plus_b, 1); + __m128i d = _mm256_extracti128_si256(a_plus_b, 0); + __m128i c_plus_d = _mm_add_epi32(c, d); + + __m128i sum1 = _mm_unpackhi_epi64(c_plus_d, c_plus_d); + __m128i sum2 = _mm_add_epi32(sum1, c_plus_d); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + + return _mm_cvtsi128_si32(sum4); +} + +static inline uint32_t partial_hsum(__m512i x) { + /* We need a permutation vector to extract every other integer. The + * rest are going to be zeros. Marking this const so the compiler stands + * a better chance of keeping this resident in a register through entire + * loop execution. We certainly have enough zmm registers (32) */ + const __m512i perm_vec = _mm512_setr_epi32(0, 2, 4, 6, 8, 10, 12, 14, + 1, 1, 1, 1, 1, 1, 1, 1); + + __m512i non_zero = _mm512_permutexvar_epi32(perm_vec, x); + + /* From here, it's a simple 256 bit wide reduction sum */ + __m256i non_zero_avx = _mm512_castsi512_si256(non_zero); + + /* See Agner Fog's vectorclass for a decent reference. Essentially, phadd is + * pretty slow, much slower than the longer instruction sequence below */ + __m128i sum1 = _mm_add_epi32(_mm256_extracti128_si256(non_zero_avx, 1), + _mm256_castsi256_si128(non_zero_avx)); + __m128i sum2 = _mm_add_epi32(sum1,_mm_unpackhi_epi64(sum1, sum1)); + __m128i sum3 = _mm_add_epi32(sum2,_mm_shuffle_epi32(sum2, 1)); + return (uint32_t)_mm_cvtsi128_si32(sum3); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_tpl.h new file mode 100644 index 000000000..7546afef5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_tpl.h @@ -0,0 +1,106 @@ +/* adler32_avx512_tpl.h -- adler32 avx512 vectorized function templates + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "adler32_avx512_p.h" + +#ifdef X86_AVX512 + +#ifdef COPY +Z_INTERNAL uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL uint32_t adler32_avx512(uint32_t adler, const uint8_t *src, size_t len) { +#endif + + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 64) { + /* This handles the remaining copies, just call normal adler checksum after this */ +#ifdef COPY + __mmask64 storemask = (0xFFFFFFFFFFFFFFFFUL >> (64 - len)); + __m512i copy_vec = _mm512_maskz_loadu_epi8(storemask, src); + _mm512_mask_storeu_epi8(dst, storemask, copy_vec); +#endif + +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + __m512i vbuf, vs1_0, vs3; + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + const __m512i dot3v = _mm512_set1_epi16(1); + const __m512i zero = _mm512_setzero_si512(); + size_t k; + + while (len >= 64) { + __m512i vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + __m512i vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + vs1_0 = vs1; + vs3 = _mm512_setzero_si512(); + + k = MIN(len, NMAX); + k -= k % 64; + len -= k; + + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf = _mm512_loadu_si512(src); +#ifdef COPY + _mm512_storeu_si512(dst, vbuf); + dst += 64; +#endif + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf, zero); + __m512i v_short_sum2 = _mm512_maddubs_epi16(vbuf, dot2v); + vs1 = _mm512_add_epi32(vs1_sad, vs1); + vs3 = _mm512_add_epi32(vs3, vs1_0); + __m512i vsum2 = _mm512_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm512_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_vnni.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_vnni.c new file mode 100644 index 000000000..8dcc93d05 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_avx512_vnni.c @@ -0,0 +1,225 @@ +/* adler32_avx512_vnni.c -- compute the Adler-32 checksum of a data stream + * Based on Brian Bockelman's AVX2 version + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_AVX512VNNI + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../cpu_features.h" +#include "../../fallback_builtins.h" +#include +#include "../../adler32_fold.h" +#include "adler32_avx512_p.h" +#include "adler32_avx2_p.h" + +Z_INTERNAL uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 32) +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + if (len < 64) +#ifdef X86_AVX2 + return adler32_avx2(adler, src, len); +#elif defined(X86_SSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + + const __m512i dot2v = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + + const __m512i zero = _mm512_setzero_si512(); + __m512i vs1, vs2; + + while (len >= 64) { + vs1 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler0)); + vs2 = _mm512_zextsi128_si512(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 64; + len -= k; + __m512i vs1_0 = vs1; + __m512i vs3 = _mm512_setzero_si512(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m512i vs2_1 = _mm512_setzero_si512(); + __m512i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 128) { + vbuf1 = _mm512_loadu_si512((__m512i*)src); + + src += 64; + k -= 64; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + vs2 = _mm512_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 128) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm512_loadu_si512((__m512i*)src); + vbuf1 = _mm512_loadu_si512((__m512i*)(src + 64)); + src += 128; + k -= 128; + + __m512i vs1_sad = _mm512_sad_epu8(vbuf0, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs3 = _mm512_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm512_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm512_add_epi32(vs3, vs1); + vs1_sad = _mm512_sad_epu8(vbuf1, zero); + vs1 = _mm512_add_epi32(vs1, vs1_sad); + vs2_1 = _mm512_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm512_slli_epi32(vs3, 6); + vs2 = _mm512_add_epi32(vs2, vs3); + vs2 = _mm512_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = _mm512_reduce_add_epu32(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel; + } + + return adler; +} + +Z_INTERNAL uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + if (src == NULL) return 1L; + if (len == 0) return adler; + + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel_copy: + if (len < 32) { + /* This handles the remaining copies, just call normal adler checksum after this */ + __mmask32 storemask = (0xFFFFFFFFUL >> (32 - len)); + __m256i copy_vec = _mm256_maskz_loadu_epi8(storemask, src); + _mm256_mask_storeu_epi8(dst, storemask, copy_vec); + +#if defined(X86_SSSE3) + return adler32_ssse3(adler, src, len); +#else + return adler32_len_16(adler0, src, len, adler1); +#endif + } + + const __m256i dot2v = _mm256_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32); + + const __m256i zero = _mm256_setzero_si256(); + __m256i vs1, vs2; + + while (len >= 32) { + vs1 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler0)); + vs2 = _mm256_zextsi128_si256(_mm_cvtsi32_si128(adler1)); + size_t k = MIN(len, NMAX); + k -= k % 32; + len -= k; + __m256i vs1_0 = vs1; + __m256i vs3 = _mm256_setzero_si256(); + /* We might get a tad bit more ILP here if we sum to a second register in the loop */ + __m256i vs2_1 = _mm256_setzero_si256(); + __m256i vbuf0, vbuf1; + + /* Remainder peeling */ + if (k % 64) { + vbuf1 = _mm256_loadu_si256((__m256i*)src); + _mm256_storeu_si256((__m256i*)dst, vbuf1); + dst += 32; + + src += 32; + k -= 32; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + vs2 = _mm256_dpbusd_epi32(vs2, vbuf1, dot2v); + vs1_0 = vs1; + } + + /* Manually unrolled this loop by 2 for an decent amount of ILP */ + while (k >= 64) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 64 vs1 + sum( (64-i+1) c[i] ) + */ + vbuf0 = _mm256_loadu_si256((__m256i*)src); + vbuf1 = _mm256_loadu_si256((__m256i*)(src + 32)); + _mm256_storeu_si256((__m256i*)dst, vbuf0); + _mm256_storeu_si256((__m256i*)(dst + 32), vbuf1); + dst += 64; + src += 64; + k -= 64; + + __m256i vs1_sad = _mm256_sad_epu8(vbuf0, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs3 = _mm256_add_epi32(vs3, vs1_0); + /* multiply-add, resulting in 16 ints. Fuse with sum stage from prior versions, as we now have the dp + * instructions to eliminate them */ + vs2 = _mm256_dpbusd_epi32(vs2, vbuf0, dot2v); + + vs3 = _mm256_add_epi32(vs3, vs1); + vs1_sad = _mm256_sad_epu8(vbuf1, zero); + vs1 = _mm256_add_epi32(vs1, vs1_sad); + vs2_1 = _mm256_dpbusd_epi32(vs2_1, vbuf1, dot2v); + vs1_0 = vs1; + } + + vs3 = _mm256_slli_epi32(vs3, 5); + vs2 = _mm256_add_epi32(vs2, vs3); + vs2 = _mm256_add_epi32(vs2, vs2_1); + + adler0 = partial_hsum256(vs1) % BASE; + adler1 = hsum256(vs2) % BASE; + } + + adler = adler0 | (adler1 << 16); + + /* Process tail (len < 64). */ + if (len) { + goto rem_peel_copy; + } + + return adler; +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_sse42.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_sse42.c new file mode 100644 index 000000000..257a36098 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_sse42.c @@ -0,0 +1,121 @@ +/* adler32_sse42.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "../../adler32_fold.h" +#include "adler32_ssse3_p.h" +#include + +#ifdef X86_SSE42 + +Z_INTERNAL uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len) { + uint32_t adler0, adler1; + adler1 = (adler >> 16) & 0xffff; + adler0 = adler & 0xffff; + +rem_peel: + if (len < 16) { + return adler32_copy_len_16(adler0, src, dst, len, adler1); + } + + __m128i vbuf, vbuf_0; + __m128i vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + v_sad_sum2, vsum2, vsum2_0; + __m128i zero = _mm_setzero_si128(); + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + size_t k; + + while (len >= 16) { + + k = MIN(len, NMAX); + k -= k % 16; + len -= k; + + vs1 = _mm_cvtsi32_si128(adler0); + vs2 = _mm_cvtsi32_si128(adler1); + + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + vbuf_0 = _mm_loadu_si128((__m128i*)(src + 16)); + src += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + _mm_storeu_si128((__m128i*)dst, vbuf); + _mm_storeu_si128((__m128i*)(dst + 16), vbuf_0); + dst += 32; + + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + vs2 = _mm_add_epi32(vsum2, vs2); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_loadu_si128((__m128i*)src); + src += 16; + k -= 16; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + + _mm_storeu_si128((__m128i*)dst, vbuf); + dst += 16; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + adler0 = partial_hsum(vs1) % BASE; + adler1 = hsum(vs2) % BASE; + } + + /* If this is true, there's fewer than 16 elements remaining */ + if (len) { + goto rem_peel; + } + + return adler0 | (adler1 << 16); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3.c new file mode 100644 index 000000000..99ce79582 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3.c @@ -0,0 +1,156 @@ +/* adler32_ssse3.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995-2011 Mark Adler + * Authors: + * Adam Stylinski + * Brian Bockelman + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "../../adler32_p.h" +#include "adler32_ssse3_p.h" + +#ifdef X86_SSSE3 + +#include + +Z_INTERNAL uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len) { + uint32_t sum2; + + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; + + /* in case user likes doing a byte at a time, keep it fast */ + if (UNLIKELY(len == 1)) + return adler32_len_1(adler, buf, sum2); + + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (UNLIKELY(buf == NULL)) + return 1L; + + /* in case short lengths are provided, keep it somewhat fast */ + if (UNLIKELY(len < 16)) + return adler32_len_16(adler, buf, len, sum2); + + const __m128i dot2v = _mm_setr_epi8(32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17); + const __m128i dot2v_0 = _mm_setr_epi8(16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + const __m128i dot3v = _mm_set1_epi16(1); + const __m128i zero = _mm_setzero_si128(); + + __m128i vbuf, vs1_0, vs3, vs1, vs2, vs2_0, v_sad_sum1, v_short_sum2, v_short_sum2_0, + vbuf_0, v_sad_sum2, vsum2, vsum2_0; + + /* If our buffer is unaligned (likely), make the determination whether + * or not there's enough of a buffer to consume to make the scalar, aligning + * additions worthwhile or if it's worth it to just eat the cost of an unaligned + * load. This is a pretty simple test, just test if 16 - the remainder + len is + * < 16 */ + size_t max_iters = NMAX; + size_t rem = (uintptr_t)buf & 15; + size_t align_offset = 16 - rem; + size_t k = 0; + if (rem) { + if (len < 16 + align_offset) { + /* Let's eat the cost of this one unaligned load so that + * we don't completely skip over the vectorization. Doing + * 16 bytes at a time unaligned is is better than 16 + <= 15 + * sums */ + vbuf = _mm_loadu_si128((__m128i*)buf); + len -= 16; + buf += 16; + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs1_0 = vs1; + goto unaligned_jmp; + } + + for (size_t i = 0; i < align_offset; ++i) { + adler += *(buf++); + sum2 += adler; + } + + /* lop off the max number of sums based on the scalar sums done + * above */ + len -= align_offset; + max_iters -= align_offset; + } + + + while (len >= 16) { + vs1 = _mm_cvtsi32_si128(adler); + vs2 = _mm_cvtsi32_si128(sum2); + vs3 = _mm_setzero_si128(); + vs2_0 = _mm_setzero_si128(); + vs1_0 = vs1; + + k = (len < max_iters ? len : max_iters); + k -= k % 16; + len -= k; + + while (k >= 32) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + vbuf_0 = _mm_load_si128((__m128i*)(buf + 16)); + buf += 32; + k -= 32; + + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + v_sad_sum2 = _mm_sad_epu8(vbuf_0, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + + vs1 = _mm_add_epi32(v_sad_sum2, vs1); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + v_short_sum2_0 = _mm_maddubs_epi16(vbuf_0, dot2v_0); + vs2 = _mm_add_epi32(vsum2, vs2); + vsum2_0 = _mm_madd_epi16(v_short_sum2_0, dot3v); + vs2_0 = _mm_add_epi32(vsum2_0, vs2_0); + vs1_0 = vs1; + } + + vs2 = _mm_add_epi32(vs2_0, vs2); + vs3 = _mm_slli_epi32(vs3, 5); + vs2 = _mm_add_epi32(vs3, vs2); + vs3 = _mm_setzero_si128(); + + while (k >= 16) { + /* + vs1 = adler + sum(c[i]) + vs2 = sum2 + 16 vs1 + sum( (16-i+1) c[i] ) + */ + vbuf = _mm_load_si128((__m128i*)buf); + buf += 16; + k -= 16; + +unaligned_jmp: + v_sad_sum1 = _mm_sad_epu8(vbuf, zero); + vs1 = _mm_add_epi32(v_sad_sum1, vs1); + vs3 = _mm_add_epi32(vs1_0, vs3); + v_short_sum2 = _mm_maddubs_epi16(vbuf, dot2v_0); + vsum2 = _mm_madd_epi16(v_short_sum2, dot3v); + vs2 = _mm_add_epi32(vsum2, vs2); + vs1_0 = vs1; + } + + vs3 = _mm_slli_epi32(vs3, 4); + vs2 = _mm_add_epi32(vs2, vs3); + + /* We don't actually need to do a full horizontal sum, since psadbw is actually doing + * a partial reduction sum implicitly and only summing to integers in vector positions + * 0 and 2. This saves us some contention on the shuffle port(s) */ + adler = partial_hsum(vs1) % BASE; + sum2 = hsum(vs2) % BASE; + max_iters = NMAX; + } + + /* Process tail (len < 16). */ + return adler32_len_16(adler, buf, len, sum2); +} + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3_p.h new file mode 100644 index 000000000..d7ec3fe0d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/adler32_ssse3_p.h @@ -0,0 +1,29 @@ +/* adler32_ssse3_p.h -- adler32 ssse3 utility functions + * Copyright (C) 2022 Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef ADLER32_SSSE3_P_H_ +#define ADLER32_SSSE3_P_H_ + +#ifdef X86_SSSE3 + +#include +#include + +static inline uint32_t partial_hsum(__m128i x) { + __m128i second_int = _mm_srli_si128(x, 8); + __m128i sum = _mm_add_epi32(x, second_int); + return _mm_cvtsi128_si32(sum); +} + +static inline uint32_t hsum(__m128i x) { + __m128i sum1 = _mm_unpackhi_epi64(x, x); + __m128i sum2 = _mm_add_epi32(x, sum1); + __m128i sum3 = _mm_shuffle_epi32(sum2, 0x01); + __m128i sum4 = _mm_add_epi32(sum2, sum3); + return _mm_cvtsi128_si32(sum4); +} +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_avx2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_avx2.c new file mode 100644 index 000000000..f309878b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_avx2.c @@ -0,0 +1,135 @@ +/* chunkset_avx2.c -- AVX2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" + +#ifdef X86_AVX2 +#include +#include "../generic/chunk_permute_table.h" + +typedef __m256i chunk_t; + +#define CHUNK_SIZE 32 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG + +/* Populate don't cares so that this is a direct lookup (with some indirection into the permute table), because dist can + * never be 0 - 2, we'll start with an offset, subtracting 3 from the input */ +static const lut_rem_pair perm_idx_lut[29] = { + { 0, 2}, /* 3 */ + { 0, 0}, /* don't care */ + { 1 * 32, 2}, /* 5 */ + { 2 * 32, 2}, /* 6 */ + { 3 * 32, 4}, /* 7 */ + { 0 * 32, 0}, /* don't care */ + { 4 * 32, 5}, /* 9 */ + { 5 * 32, 22}, /* 10 */ + { 6 * 32, 21}, /* 11 */ + { 7 * 32, 20}, /* 12 */ + { 8 * 32, 6}, /* 13 */ + { 9 * 32, 4}, /* 14 */ + {10 * 32, 2}, /* 15 */ + { 0 * 32, 0}, /* don't care */ + {11 * 32, 15}, /* 17 */ + {11 * 32 + 16, 14}, /* 18 */ + {11 * 32 + 16 * 2, 13}, /* 19 */ + {11 * 32 + 16 * 3, 12}, /* 20 */ + {11 * 32 + 16 * 4, 11}, /* 21 */ + {11 * 32 + 16 * 5, 10}, /* 22 */ + {11 * 32 + 16 * 6, 9}, /* 23 */ + {11 * 32 + 16 * 7, 8}, /* 24 */ + {11 * 32 + 16 * 8, 7}, /* 25 */ + {11 * 32 + 16 * 9, 6}, /* 26 */ + {11 * 32 + 16 * 10, 5}, /* 27 */ + {11 * 32 + 16 * 11, 4}, /* 28 */ + {11 * 32 + 16 * 12, 3}, /* 29 */ + {11 * 32 + 16 * 13, 2}, /* 30 */ + {11 * 32 + 16 * 14, 1} /* 31 */ +}; + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm256_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm256_loadu_si256((__m256i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm256_storeu_si256((__m256i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m256i ret_vec; + /* While technically we only need to read 4 or 8 bytes into this vector register for a lot of cases, GCC is + * compiling this to a shared load for all branches, preferring the simpler code. Given that the buf value isn't in + * GPRs to begin with the 256 bit load is _probably_ just as inexpensive */ + *chunk_rem = lut_rem.remval; + +#ifdef Z_MEMORY_SANITIZER + /* See note in chunkset_ssse3.c for why this is ok */ + __msan_unpoison(buf + dist, 32 - dist); +#endif + + if (dist < 16) { + /* This simpler case still requires us to shuffle in 128 bit lanes, so we must apply a static offset after + * broadcasting the first vector register to both halves. This is _marginally_ faster than doing two separate + * shuffles and combining the halves later */ + const __m256i permute_xform = + _mm256_setr_epi8(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16); + __m256i perm_vec = _mm256_load_si256((__m256i*)(permute_table+lut_rem.idx)); + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + perm_vec = _mm256_add_epi8(perm_vec, permute_xform); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + ret_vec = _mm256_shuffle_epi8(ret_vec, perm_vec); + } else if (dist == 16) { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + return _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), ret_vec0, 1); + } else { + __m128i ret_vec0 = _mm_loadu_si128((__m128i*)buf); + __m128i ret_vec1 = _mm_loadu_si128((__m128i*)(buf + 16)); + /* Take advantage of the fact that only the latter half of the 256 bit vector will actually differ */ + __m128i perm_vec1 = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + __m128i xlane_permutes = _mm_cmpgt_epi8(_mm_set1_epi8(16), perm_vec1); + __m128i xlane_res = _mm_shuffle_epi8(ret_vec0, perm_vec1); + /* Since we can't wrap twice, we can simply keep the later half exactly how it is instead of having to _also_ + * shuffle those values */ + __m128i latter_half = _mm_blendv_epi8(ret_vec1, xlane_res, xlane_permutes); + ret_vec = _mm256_inserti128_si256(_mm256_castsi128_si256(ret_vec0), latter_half, 1); + } + + return ret_vec; +} + +#define CHUNKSIZE chunksize_avx2 +#define CHUNKCOPY chunkcopy_avx2 +#define CHUNKUNROLL chunkunroll_avx2 +#define CHUNKMEMSET chunkmemset_avx2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_avx2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_avx2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_sse2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_sse2.c new file mode 100644 index 000000000..c402c0ee1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_sse2.c @@ -0,0 +1,56 @@ +/* chunkset_sse2.c -- SSE2 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +#ifdef X86_SSE2 +#include + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +#define CHUNKSIZE chunksize_sse2 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 +#define CHUNKMEMSET chunkmemset_sse2 +#define CHUNKMEMSET_SAFE chunkmemset_safe_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_sse2 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_ssse3.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_ssse3.c new file mode 100644 index 000000000..0bd626385 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/chunkset_ssse3.c @@ -0,0 +1,103 @@ +/* chunkset_ssse3.c -- SSSE3 inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +/* This requires SSE2 support. While it's implicit with SSSE3, we can minimize + * code size by sharing the chunkcopy functions, which will certainly compile + * to identical machine code */ +#if defined(X86_SSSE3) && defined(X86_SSE2) +#include +#include "../generic/chunk_permute_table.h" + +typedef __m128i chunk_t; + +#define CHUNK_SIZE 16 + +#define HAVE_CHUNKMEMSET_2 +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 +#define HAVE_CHUNK_MAG +#define HAVE_CHUNKCOPY +#define HAVE_CHUNKUNROLL + +static const lut_rem_pair perm_idx_lut[13] = { + {0, 1}, /* 3 */ + {0, 0}, /* don't care */ + {1 * 32, 1}, /* 5 */ + {2 * 32, 4}, /* 6 */ + {3 * 32, 2}, /* 7 */ + {0 * 32, 0}, /* don't care */ + {4 * 32, 7}, /* 9 */ + {5 * 32, 6}, /* 10 */ + {6 * 32, 5}, /* 11 */ + {7 * 32, 4}, /* 12 */ + {8 * 32, 3}, /* 13 */ + {9 * 32, 2}, /* 14 */ + {10 * 32, 1},/* 15 */ +}; + + +static inline void chunkmemset_2(uint8_t *from, chunk_t *chunk) { + int16_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi16(tmp); +} + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + int32_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi32(tmp); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + int64_t tmp; + memcpy(&tmp, from, sizeof(tmp)); + *chunk = _mm_set1_epi64x(tmp); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + *chunk = _mm_loadu_si128((__m128i *)s); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + _mm_storeu_si128((__m128i *)out, *chunk); +} + +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + lut_rem_pair lut_rem = perm_idx_lut[dist - 3]; + __m128i perm_vec, ret_vec; +#ifdef Z_MEMORY_SANITIZER + /* Important to note: + * This is _not_ to subvert the memory sanitizer but to instead unpoison some + * bytes we willingly and purposefully load uninitialized that we swizzle over + * in a vector register, anyway. If what we assume is wrong about what is used, + * the memory sanitizer will still usefully flag it */ + __msan_unpoison(buf + dist, 16 - dist); +#endif + ret_vec = _mm_loadu_si128((__m128i*)buf); + *chunk_rem = lut_rem.remval; + + perm_vec = _mm_load_si128((__m128i*)(permute_table + lut_rem.idx)); + ret_vec = _mm_shuffle_epi8(ret_vec, perm_vec); + + return ret_vec; +} + +extern uint8_t* chunkcopy_sse2(uint8_t *out, uint8_t const *from, unsigned len); +extern uint8_t* chunkunroll_sse2(uint8_t *out, unsigned *dist, unsigned *len); + +#define CHUNKSIZE chunksize_ssse3 +#define CHUNKMEMSET chunkmemset_ssse3 +#define CHUNKMEMSET_SAFE chunkmemset_safe_ssse3 +#define CHUNKCOPY chunkcopy_sse2 +#define CHUNKUNROLL chunkunroll_sse2 + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_ssse3 + +#include "inffast_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_avx2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_avx2.c new file mode 100644 index 000000000..1318a0e33 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_avx2.c @@ -0,0 +1,63 @@ +/* compare256_avx2.c -- AVX2 version of compare256 + * Copyright Mika T. Lindqvist + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) + +#include +#ifdef _MSC_VER +# include +#endif + +static inline uint32_t compare256_avx2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + __m256i ymm_src0, ymm_src1, ymm_cmp; + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); /* non-identical bytes = 00, identical bytes = FF */ + unsigned mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); /* Invert bits so identical = 0 */ + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + + ymm_src0 = _mm256_loadu_si256((__m256i*)src0); + ymm_src1 = _mm256_loadu_si256((__m256i*)src1); + ymm_cmp = _mm256_cmpeq_epi8(ymm_src0, ymm_src1); + mask = (unsigned)_mm256_movemask_epi8(ymm_cmp); + if (mask != 0xFFFFFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + src0 += 32, src1 += 32, len += 32; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1) { + return compare256_avx2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_avx2 +#define COMPARE256 compare256_avx2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_sse2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_sse2.c new file mode 100644 index 000000000..aad4bd240 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/compare256_sse2.c @@ -0,0 +1,96 @@ +/* compare256_sse2.c -- SSE2 version of compare256 + * Copyright Adam Stylinski + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include "fallback_builtins.h" + +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) + +#include + +static inline uint32_t compare256_sse2_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + int align_offset = ((uintptr_t)src0) & 15; + const uint8_t *end0 = src0 + 256; + const uint8_t *end1 = src1 + 256; + __m128i xmm_src0, xmm_src1, xmm_cmp; + + /* Do the first load unaligned, than all subsequent ones we have at least + * one aligned load. Sadly aligning both loads is probably unrealistic */ + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + unsigned mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + int align_adv = 16 - align_offset; + len += align_adv; + src0 += align_adv; + src1 += align_adv; + + /* Do a flooring division (should just be a shift right) */ + int num_iter = (256 - len) / 16; + + for (int i = 0; i < num_iter; ++i) { + xmm_src0 = _mm_load_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + /* Compiler _may_ turn this branch into a ptest + movemask, + * since a lot of those uops are shared and fused */ + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + + len += 16, src0 += 16, src1 += 16; + } + + if (align_offset) { + src0 = end0 - 16; + src1 = end1 - 16; + len = 256 - 16; + + xmm_src0 = _mm_loadu_si128((__m128i*)src0); + xmm_src1 = _mm_loadu_si128((__m128i*)src1); + xmm_cmp = _mm_cmpeq_epi8(xmm_src0, xmm_src1); + + mask = (unsigned)_mm_movemask_epi8(xmm_cmp); + + if (mask != 0xFFFF) { + uint32_t match_byte = (uint32_t)__builtin_ctz(~mask); + return len + match_byte; + } + } + + return 256; +} + +Z_INTERNAL uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1) { + return compare256_sse2_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_sse2 +#define COMPARE256 compare256_sse2_static + +#include "match_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_pclmulqdq_tpl.h new file mode 100644 index 000000000..3e7992831 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_pclmulqdq_tpl.h @@ -0,0 +1,186 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +Z_INTERNAL void CRC32_FOLD_COPY(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { +#else +Z_INTERNAL void CRC32_FOLD(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { +#endif + unsigned long algn_diff; + __m128i xmm_t0, xmm_t1, xmm_t2, xmm_t3; + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i xmm_crc_part = _mm_setzero_si128(); +#ifdef COPY + char ALIGNED_(16) partial_buf[16] = { 0 }; +#else + __m128i xmm_initial = _mm_cvtsi32_si128(init_crc); + int32_t first = init_crc != 0; + + /* Technically the CRC functions don't even call this for input < 64, but a bare minimum of 31 + * bytes of input is needed for the aligning load that occurs. If there's an initial CRC, to + * carry it forward through the folded CRC there must be 16 - src % 16 + 16 bytes available, which + * by definition can be up to 15 bytes + one full vector load. */ + assert(len >= 31 || first == 0); +#endif + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + if (len < 16) { +#ifdef COPY + if (len == 0) + return; + + memcpy(partial_buf, src, len); + xmm_crc_part = _mm_load_si128((const __m128i *)partial_buf); + memcpy(dst, partial_buf, len); +#endif + goto partial; + } + + algn_diff = ((uintptr_t)16 - ((uintptr_t)src & 0xF)) & 0xF; + if (algn_diff) { + xmm_crc_part = _mm_loadu_si128((__m128i *)src); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_crc_part); + dst += algn_diff; +#else + XOR_INITIAL128(xmm_crc_part); + + if (algn_diff < 4 && init_crc != 0) { + xmm_t0 = xmm_crc_part; + xmm_crc_part = _mm_loadu_si128((__m128i*)src + 1); + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + src += 16; + len -= 16; + } +#endif + + partial_fold(algn_diff, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + + src += algn_diff; + len -= algn_diff; + } + +#ifdef X86_VPCLMULQDQ + if (len >= 256) { +#ifdef COPY + size_t n = fold_16_vpclmulqdq_copy(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, dst, src, len); + dst += n; +#else + size_t n = fold_16_vpclmulqdq(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, src, len, + xmm_initial, first); + first = 0; +#endif + len -= n; + src += n; + } +#endif + + while (len >= 64) { + len -= 64; + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + xmm_t3 = _mm_load_si128((__m128i *)src + 3); + src += 64; + + fold_4(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + _mm_storeu_si128((__m128i *)dst + 3, xmm_t3); + dst += 64; +#else + XOR_INITIAL128(xmm_t0); +#endif + + xmm_crc0 = _mm_xor_si128(xmm_crc0, xmm_t0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t3); + } + + /* + * len = num bytes left - 64 + */ + if (len >= 48) { + len -= 48; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + xmm_t2 = _mm_load_si128((__m128i *)src + 2); + src += 48; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + _mm_storeu_si128((__m128i *)dst + 2, xmm_t2); + dst += 48; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_3(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_t0); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t1); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t2); + } else if (len >= 32) { + len -= 32; + + xmm_t0 = _mm_load_si128((__m128i *)src); + xmm_t1 = _mm_load_si128((__m128i *)src + 1); + src += 32; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + _mm_storeu_si128((__m128i *)dst + 1, xmm_t1); + dst += 32; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_2(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_t0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t1); + } else if (len >= 16) { + len -= 16; + xmm_t0 = _mm_load_si128((__m128i *)src); + src += 16; +#ifdef COPY + _mm_storeu_si128((__m128i *)dst, xmm_t0); + dst += 16; +#else + XOR_INITIAL128(xmm_t0); +#endif + fold_1(&xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_t0); + } + +partial: + if (len) { + memcpy(&xmm_crc_part, src, len); +#ifdef COPY + _mm_storeu_si128((__m128i *)partial_buf, xmm_crc_part); + memcpy(dst, partial_buf, len); +#endif + partial_fold(len, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3, &xmm_crc_part); + } + + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_vpclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_vpclmulqdq_tpl.h new file mode 100644 index 000000000..3ea5c3305 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_fold_vpclmulqdq_tpl.h @@ -0,0 +1,107 @@ +/* crc32_fold_vpclmulqdq_tpl.h -- VPCMULQDQ-based CRC32 folding template. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef COPY +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len) { +#else +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, + __m128i init_crc, int32_t first) { + __m512i zmm_initial = _mm512_zextsi128_si512(init_crc); +#endif + __m512i zmm_t0, zmm_t1, zmm_t2, zmm_t3; + __m512i zmm_crc0, zmm_crc1, zmm_crc2, zmm_crc3; + __m512i z0, z1, z2, z3; + size_t len_tmp = len; + const __m512i zmm_fold4 = _mm512_set4_epi32( + 0x00000001, 0x54442bd4, 0x00000001, 0xc6e41596); + const __m512i zmm_fold16 = _mm512_set4_epi32( + 0x00000001, 0x1542778a, 0x00000001, 0x322d1430); + + // zmm register init + zmm_crc0 = _mm512_setzero_si512(); + zmm_t0 = _mm512_loadu_si512((__m512i *)src); +#ifndef COPY + XOR_INITIAL512(zmm_t0); +#endif + zmm_crc1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_crc2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_crc3 = _mm512_loadu_si512((__m512i *)src + 3); + + /* already have intermediate CRC in xmm registers + * fold4 with 4 xmm_crc to get zmm_crc0 + */ + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc0, 0); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc1, 1); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc2, 2); + zmm_crc0 = _mm512_inserti32x4(zmm_crc0, *xmm_crc3, 3); + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_t0, 0x96); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_crc1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_crc2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_crc3); + dst += 256; +#endif + len -= 256; + src += 256; + + // fold-16 loops + while (len >= 256) { + zmm_t0 = _mm512_loadu_si512((__m512i *)src); + zmm_t1 = _mm512_loadu_si512((__m512i *)src + 1); + zmm_t2 = _mm512_loadu_si512((__m512i *)src + 2); + zmm_t3 = _mm512_loadu_si512((__m512i *)src + 3); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x01); + z1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x01); + z2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x01); + z3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x01); + + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold16, 0x10); + zmm_crc1 = _mm512_clmulepi64_epi128(zmm_crc1, zmm_fold16, 0x10); + zmm_crc2 = _mm512_clmulepi64_epi128(zmm_crc2, zmm_fold16, 0x10); + zmm_crc3 = _mm512_clmulepi64_epi128(zmm_crc3, zmm_fold16, 0x10); + + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_t0, 0x96); + zmm_crc1 = _mm512_ternarylogic_epi32(zmm_crc1, z1, zmm_t1, 0x96); + zmm_crc2 = _mm512_ternarylogic_epi32(zmm_crc2, z2, zmm_t2, 0x96); + zmm_crc3 = _mm512_ternarylogic_epi32(zmm_crc3, z3, zmm_t3, 0x96); + +#ifdef COPY + _mm512_storeu_si512((__m512i *)dst, zmm_t0); + _mm512_storeu_si512((__m512i *)dst + 1, zmm_t1); + _mm512_storeu_si512((__m512i *)dst + 2, zmm_t2); + _mm512_storeu_si512((__m512i *)dst + 3, zmm_t3); + dst += 256; +#endif + len -= 256; + src += 256; + } + // zmm_crc[0,1,2,3] -> zmm_crc0 + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc1, 0x96); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc2, 0x96); + + z0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x01); + zmm_crc0 = _mm512_clmulepi64_epi128(zmm_crc0, zmm_fold4, 0x10); + zmm_crc0 = _mm512_ternarylogic_epi32(zmm_crc0, z0, zmm_crc3, 0x96); + + // zmm_crc0 -> xmm_crc[0, 1, 2, 3] + *xmm_crc0 = _mm512_extracti32x4_epi32(zmm_crc0, 0); + *xmm_crc1 = _mm512_extracti32x4_epi32(zmm_crc0, 1); + *xmm_crc2 = _mm512_extracti32x4_epi32(zmm_crc0, 2); + *xmm_crc3 = _mm512_extracti32x4_epi32(zmm_crc0, 3); + + return (len_tmp - len); // return n bytes processed +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq.c new file mode 100644 index 000000000..9383b7a2b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq.c @@ -0,0 +1,30 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifdef X86_PCLMULQDQ_CRC + +#define CRC32_FOLD_COPY crc32_fold_pclmulqdq_copy +#define CRC32_FOLD crc32_fold_pclmulqdq +#define CRC32_FOLD_RESET crc32_fold_pclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_pclmulqdq_final +#define CRC32 crc32_pclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq_tpl.h new file mode 100644 index 000000000..0d66663cb --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_pclmulqdq_tpl.h @@ -0,0 +1,363 @@ +/* + * Compute the CRC32 using a parallelized folding approach with the PCLMULQDQ + * instruction. + * + * A white paper describing this algorithm can be found at: + * doc/crc-pclmulqdq.pdf + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Copyright (C) 2016 Marian Beermann (support for initial value) + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" + +#include +#include +#include // _mm_extract_epi32 +#ifdef X86_VPCLMULQDQ +# include +#endif + +#include "../../crc32_fold.h" +#include "../../crc32_braid_p.h" +#include "../../fallback_builtins.h" +#include + +#ifdef X86_VPCLMULQDQ +static size_t fold_16_vpclmulqdq(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, const uint8_t *src, size_t len, __m128i init_crc, + int32_t first); +static size_t fold_16_vpclmulqdq_copy(__m128i *xmm_crc0, __m128i *xmm_crc1, + __m128i *xmm_crc2, __m128i *xmm_crc3, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +static void fold_1(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc3, ps_res; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res = _mm_xor_ps(ps_crc0, ps_crc3); + + *xmm_crc0 = *xmm_crc1; + *xmm_crc1 = *xmm_crc2; + *xmm_crc2 = x_tmp3; + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static void fold_2(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3, x_tmp2; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res31, ps_res20; + + x_tmp3 = *xmm_crc3; + x_tmp2 = *xmm_crc2; + + *xmm_crc3 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res31 = _mm_xor_ps(ps_crc3, ps_crc1); + + *xmm_crc2 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res20 = _mm_xor_ps(ps_crc0, ps_crc2); + + *xmm_crc0 = x_tmp2; + *xmm_crc1 = x_tmp3; + *xmm_crc2 = _mm_castps_si128(ps_res20); + *xmm_crc3 = _mm_castps_si128(ps_res31); +} + +static void fold_3(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3, ps_res32, ps_res21, ps_res10; + + x_tmp3 = *xmm_crc3; + + *xmm_crc3 = *xmm_crc2; + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_res32 = _mm_xor_ps(ps_crc2, ps_crc3); + + *xmm_crc2 = *xmm_crc1; + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_res21 = _mm_xor_ps(ps_crc1, ps_crc2); + + *xmm_crc1 = *xmm_crc0; + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_res10 = _mm_xor_ps(ps_crc0, ps_crc1); + + *xmm_crc0 = x_tmp3; + *xmm_crc1 = _mm_castps_si128(ps_res10); + *xmm_crc2 = _mm_castps_si128(ps_res21); + *xmm_crc3 = _mm_castps_si128(ps_res32); +} + +static void fold_4(__m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, __m128i *xmm_crc3) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + __m128i x_tmp0, x_tmp1, x_tmp2, x_tmp3; + __m128 ps_crc0, ps_crc1, ps_crc2, ps_crc3; + __m128 ps_t0, ps_t1, ps_t2, ps_t3; + __m128 ps_res0, ps_res1, ps_res2, ps_res3; + + x_tmp0 = *xmm_crc0; + x_tmp1 = *xmm_crc1; + x_tmp2 = *xmm_crc2; + x_tmp3 = *xmm_crc3; + + *xmm_crc0 = _mm_clmulepi64_si128(*xmm_crc0, xmm_fold4, 0x01); + x_tmp0 = _mm_clmulepi64_si128(x_tmp0, xmm_fold4, 0x10); + ps_crc0 = _mm_castsi128_ps(*xmm_crc0); + ps_t0 = _mm_castsi128_ps(x_tmp0); + ps_res0 = _mm_xor_ps(ps_crc0, ps_t0); + + *xmm_crc1 = _mm_clmulepi64_si128(*xmm_crc1, xmm_fold4, 0x01); + x_tmp1 = _mm_clmulepi64_si128(x_tmp1, xmm_fold4, 0x10); + ps_crc1 = _mm_castsi128_ps(*xmm_crc1); + ps_t1 = _mm_castsi128_ps(x_tmp1); + ps_res1 = _mm_xor_ps(ps_crc1, ps_t1); + + *xmm_crc2 = _mm_clmulepi64_si128(*xmm_crc2, xmm_fold4, 0x01); + x_tmp2 = _mm_clmulepi64_si128(x_tmp2, xmm_fold4, 0x10); + ps_crc2 = _mm_castsi128_ps(*xmm_crc2); + ps_t2 = _mm_castsi128_ps(x_tmp2); + ps_res2 = _mm_xor_ps(ps_crc2, ps_t2); + + *xmm_crc3 = _mm_clmulepi64_si128(*xmm_crc3, xmm_fold4, 0x01); + x_tmp3 = _mm_clmulepi64_si128(x_tmp3, xmm_fold4, 0x10); + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + ps_t3 = _mm_castsi128_ps(x_tmp3); + ps_res3 = _mm_xor_ps(ps_crc3, ps_t3); + + *xmm_crc0 = _mm_castps_si128(ps_res0); + *xmm_crc1 = _mm_castps_si128(ps_res1); + *xmm_crc2 = _mm_castps_si128(ps_res2); + *xmm_crc3 = _mm_castps_si128(ps_res3); +} + +static const unsigned ALIGNED_(32) pshufb_shf_table[60] = { + 0x84838281, 0x88878685, 0x8c8b8a89, 0x008f8e8d, /* shl 15 (16 - 1)/shr1 */ + 0x85848382, 0x89888786, 0x8d8c8b8a, 0x01008f8e, /* shl 14 (16 - 3)/shr2 */ + 0x86858483, 0x8a898887, 0x8e8d8c8b, 0x0201008f, /* shl 13 (16 - 4)/shr3 */ + 0x87868584, 0x8b8a8988, 0x8f8e8d8c, 0x03020100, /* shl 12 (16 - 4)/shr4 */ + 0x88878685, 0x8c8b8a89, 0x008f8e8d, 0x04030201, /* shl 11 (16 - 5)/shr5 */ + 0x89888786, 0x8d8c8b8a, 0x01008f8e, 0x05040302, /* shl 10 (16 - 6)/shr6 */ + 0x8a898887, 0x8e8d8c8b, 0x0201008f, 0x06050403, /* shl 9 (16 - 7)/shr7 */ + 0x8b8a8988, 0x8f8e8d8c, 0x03020100, 0x07060504, /* shl 8 (16 - 8)/shr8 */ + 0x8c8b8a89, 0x008f8e8d, 0x04030201, 0x08070605, /* shl 7 (16 - 9)/shr9 */ + 0x8d8c8b8a, 0x01008f8e, 0x05040302, 0x09080706, /* shl 6 (16 -10)/shr10*/ + 0x8e8d8c8b, 0x0201008f, 0x06050403, 0x0a090807, /* shl 5 (16 -11)/shr11*/ + 0x8f8e8d8c, 0x03020100, 0x07060504, 0x0b0a0908, /* shl 4 (16 -12)/shr12*/ + 0x008f8e8d, 0x04030201, 0x08070605, 0x0c0b0a09, /* shl 3 (16 -13)/shr13*/ + 0x01008f8e, 0x05040302, 0x09080706, 0x0d0c0b0a, /* shl 2 (16 -14)/shr14*/ + 0x0201008f, 0x06050403, 0x0a090807, 0x0e0d0c0b /* shl 1 (16 -15)/shr15*/ +}; + +static void partial_fold(const size_t len, __m128i *xmm_crc0, __m128i *xmm_crc1, __m128i *xmm_crc2, + __m128i *xmm_crc3, __m128i *xmm_crc_part) { + const __m128i xmm_fold4 = _mm_set_epi32( 0x00000001, 0x54442bd4, + 0x00000001, 0xc6e41596); + const __m128i xmm_mask3 = _mm_set1_epi32((int32_t)0x80808080); + + __m128i xmm_shl, xmm_shr, xmm_tmp1, xmm_tmp2, xmm_tmp3; + __m128i xmm_a0_0, xmm_a0_1; + __m128 ps_crc3, psa0_0, psa0_1, ps_res; + + xmm_shl = _mm_load_si128((__m128i *)(pshufb_shf_table + (4 * (len - 1)))); + xmm_shr = xmm_shl; + xmm_shr = _mm_xor_si128(xmm_shr, xmm_mask3); + + xmm_a0_0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shl); + + *xmm_crc0 = _mm_shuffle_epi8(*xmm_crc0, xmm_shr); + xmm_tmp1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shl); + *xmm_crc0 = _mm_or_si128(*xmm_crc0, xmm_tmp1); + + *xmm_crc1 = _mm_shuffle_epi8(*xmm_crc1, xmm_shr); + xmm_tmp2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shl); + *xmm_crc1 = _mm_or_si128(*xmm_crc1, xmm_tmp2); + + *xmm_crc2 = _mm_shuffle_epi8(*xmm_crc2, xmm_shr); + xmm_tmp3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shl); + *xmm_crc2 = _mm_or_si128(*xmm_crc2, xmm_tmp3); + + *xmm_crc3 = _mm_shuffle_epi8(*xmm_crc3, xmm_shr); + *xmm_crc_part = _mm_shuffle_epi8(*xmm_crc_part, xmm_shl); + *xmm_crc3 = _mm_or_si128(*xmm_crc3, *xmm_crc_part); + + xmm_a0_1 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x10); + xmm_a0_0 = _mm_clmulepi64_si128(xmm_a0_0, xmm_fold4, 0x01); + + ps_crc3 = _mm_castsi128_ps(*xmm_crc3); + psa0_0 = _mm_castsi128_ps(xmm_a0_0); + psa0_1 = _mm_castsi128_ps(xmm_a0_1); + + ps_res = _mm_xor_ps(ps_crc3, psa0_0); + ps_res = _mm_xor_ps(ps_res, psa0_1); + + *xmm_crc3 = _mm_castps_si128(ps_res); +} + +static inline void crc32_fold_load(__m128i *fold, __m128i *fold0, __m128i *fold1, __m128i *fold2, __m128i *fold3) { + *fold0 = _mm_load_si128(fold + 0); + *fold1 = _mm_load_si128(fold + 1); + *fold2 = _mm_load_si128(fold + 2); + *fold3 = _mm_load_si128(fold + 3); +} + +static inline void crc32_fold_save(__m128i *fold, const __m128i *fold0, const __m128i *fold1, + const __m128i *fold2, const __m128i *fold3) { + _mm_storeu_si128(fold + 0, *fold0); + _mm_storeu_si128(fold + 1, *fold1); + _mm_storeu_si128(fold + 2, *fold2); + _mm_storeu_si128(fold + 3, *fold3); +} + +Z_INTERNAL uint32_t CRC32_FOLD_RESET(crc32_fold *crc) { + __m128i xmm_crc0 = _mm_cvtsi32_si128(0x9db42487); + __m128i xmm_zero = _mm_setzero_si128(); + crc32_fold_save((__m128i *)crc->fold, &xmm_crc0, &xmm_zero, &xmm_zero, &xmm_zero); + return 0; +} + +#define ONCE(op) if (first) { first = 0; op; } +#define XOR_INITIAL128(where) ONCE(where = _mm_xor_si128(where, xmm_initial)) +#ifdef X86_VPCLMULQDQ +# define XOR_INITIAL512(where) ONCE(where = _mm512_xor_si512(where, zmm_initial)) +#endif + +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" +#define COPY +#ifdef X86_VPCLMULQDQ +# include "crc32_fold_vpclmulqdq_tpl.h" +#endif +#include "crc32_fold_pclmulqdq_tpl.h" + +static const unsigned ALIGNED_(16) crc_k[] = { + 0xccaa009e, 0x00000000, /* rk1 */ + 0x751997d0, 0x00000001, /* rk2 */ + 0xccaa009e, 0x00000000, /* rk5 */ + 0x63cd6124, 0x00000001, /* rk6 */ + 0xf7011640, 0x00000001, /* rk7 */ + 0xdb710640, 0x00000001 /* rk8 */ +}; + +static const unsigned ALIGNED_(16) crc_mask[4] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000000 +}; + +static const unsigned ALIGNED_(16) crc_mask2[4] = { + 0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +Z_INTERNAL uint32_t CRC32_FOLD_FINAL(crc32_fold *crc) { + const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask); + const __m128i xmm_mask2 = _mm_load_si128((__m128i *)crc_mask2); + __m128i xmm_crc0, xmm_crc1, xmm_crc2, xmm_crc3; + __m128i x_tmp0, x_tmp1, x_tmp2, crc_fold; + + crc32_fold_load((__m128i *)crc->fold, &xmm_crc0, &xmm_crc1, &xmm_crc2, &xmm_crc3); + + /* + * k1 + */ + crc_fold = _mm_load_si128((__m128i *)crc_k); + + x_tmp0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x10); + xmm_crc0 = _mm_clmulepi64_si128(xmm_crc0, crc_fold, 0x01); + xmm_crc1 = _mm_xor_si128(xmm_crc1, x_tmp0); + xmm_crc1 = _mm_xor_si128(xmm_crc1, xmm_crc0); + + x_tmp1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x10); + xmm_crc1 = _mm_clmulepi64_si128(xmm_crc1, crc_fold, 0x01); + xmm_crc2 = _mm_xor_si128(xmm_crc2, x_tmp1); + xmm_crc2 = _mm_xor_si128(xmm_crc2, xmm_crc1); + + x_tmp2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x10); + xmm_crc2 = _mm_clmulepi64_si128(xmm_crc2, crc_fold, 0x01); + xmm_crc3 = _mm_xor_si128(xmm_crc3, x_tmp2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + + /* + * k5 + */ + crc_fold = _mm_load_si128((__m128i *)(crc_k + 4)); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc0 = _mm_srli_si128(xmm_crc0, 8); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + + xmm_crc0 = xmm_crc3; + xmm_crc3 = _mm_slli_si128(xmm_crc3, 4); + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc0); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask2); + + /* + * k7 + */ + xmm_crc1 = xmm_crc3; + xmm_crc2 = xmm_crc3; + crc_fold = _mm_load_si128((__m128i *)(crc_k + 8)); + + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_and_si128(xmm_crc3, xmm_mask); + + xmm_crc2 = xmm_crc3; + xmm_crc3 = _mm_clmulepi64_si128(xmm_crc3, crc_fold, 0x10); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc2); + xmm_crc3 = _mm_xor_si128(xmm_crc3, xmm_crc1); + + crc->value = ~((uint32_t)_mm_extract_epi32(xmm_crc3, 2)); + + return crc->value; +} + +Z_INTERNAL uint32_t CRC32(uint32_t crc32, const uint8_t *buf, size_t len) { + /* For lens < 64, crc32_braid method is faster. The CRC32 instruction for + * these short lengths might also prove to be effective */ + if (len < 64) + return PREFIX(crc32_braid)(crc32, buf, len); + + crc32_fold ALIGNED_(16) crc_state; + CRC32_FOLD_RESET(&crc_state); + CRC32_FOLD(&crc_state, buf, len, crc32); + return CRC32_FOLD_FINAL(&crc_state); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_vpclmulqdq.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_vpclmulqdq.c new file mode 100644 index 000000000..ec641b432 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/crc32_vpclmulqdq.c @@ -0,0 +1,17 @@ +/* crc32_vpclmulqdq.c -- VPCMULQDQ-based CRC32 folding implementation. + * Copyright Wangyang Guo (wangyang.guo@intel.com) + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) + +#define X86_VPCLMULQDQ +#define CRC32_FOLD_COPY crc32_fold_vpclmulqdq_copy +#define CRC32_FOLD crc32_fold_vpclmulqdq +#define CRC32_FOLD_RESET crc32_fold_vpclmulqdq_reset +#define CRC32_FOLD_FINAL crc32_fold_vpclmulqdq_final +#define CRC32 crc32_vpclmulqdq + +#include "crc32_pclmulqdq_tpl.h" + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/insert_string_sse42.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/insert_string_sse42.c new file mode 100644 index 000000000..565d92f97 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/insert_string_sse42.c @@ -0,0 +1,50 @@ +/* insert_string_sse42.c -- insert_string integer hash variant using SSE4.2's CRC instructions + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#include "../../zbuild.h" +#include +#ifdef _MSC_VER +# include +#endif +#include "../../deflate.h" + +#ifdef X86_SSE42_CRC_INTRIN +# ifdef _MSC_VER +# define HASH_CALC(s, h, val)\ + h = _mm_crc32_u32(h, val) +# else +# define HASH_CALC(s, h, val)\ + h = __builtin_ia32_crc32si(h, val) +# endif +#else +# ifdef _MSC_VER +# define HASH_CALC(s, h, val) {\ + __asm mov edx, h\ + __asm mov eax, val\ + __asm crc32 eax, edx\ + __asm mov h, eax\ + } +# else +# define HASH_CALC(s, h, val) \ + __asm__ __volatile__ (\ + "crc32 %1,%0\n\t"\ + : "+r" (h)\ + : "r" (val)\ + ); +# endif +#endif + +#define HASH_CALC_VAR h +#define HASH_CALC_VAR_INIT uint32_t h = 0 + +#define UPDATE_HASH update_hash_sse42 +#define INSERT_STRING insert_string_sse42 +#define QUICK_INSERT_STRING quick_insert_string_sse42 + +#ifdef X86_SSE42 +# include "../../insert_string_tpl.h" +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_avx2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_avx2.c new file mode 100644 index 000000000..94fe10c7b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_avx2.c @@ -0,0 +1,39 @@ +/* + * AVX2 optimized hash slide, based on Intel's slide_sse implementation + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * Mika T. Lindqvist + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include + +static inline void slide_hash_chain(Pos *table, uint32_t entries, const __m256i wsize) { + table += entries; + table -= 16; + + do { + __m256i value, result; + + value = _mm256_loadu_si256((__m256i *)table); + result = _mm256_subs_epu16(value, wsize); + _mm256_storeu_si256((__m256i *)table, result); + + table -= 16; + entries -= 16; + } while (entries > 0); +} + +Z_INTERNAL void slide_hash_avx2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m256i ymm_wsize = _mm256_set1_epi16((short)wsize); + + slide_hash_chain(s->head, HASH_SIZE, ymm_wsize); + slide_hash_chain(s->prev, wsize, ymm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_sse2.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_sse2.c new file mode 100644 index 000000000..5daac4a73 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/slide_hash_sse2.c @@ -0,0 +1,62 @@ +/* + * SSE optimized hash slide + * + * Copyright (C) 2017 Intel Corporation + * Authors: + * Arjan van de Ven + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "../../zbuild.h" +#include "../../deflate.h" + +#include +#include + +static inline void slide_hash_chain(Pos *table0, Pos *table1, uint32_t entries0, + uint32_t entries1, const __m128i wsize) { + uint32_t entries; + Pos *table; + __m128i value0, value1, result0, result1; + + int on_chain = 0; + +next_chain: + table = (on_chain) ? table1 : table0; + entries = (on_chain) ? entries1 : entries0; + + table += entries; + table -= 16; + + /* ZALLOC allocates this pointer unless the user chose a custom allocator. + * Our alloc function is aligned to 64 byte boundaries */ + do { + value0 = _mm_load_si128((__m128i *)table); + value1 = _mm_load_si128((__m128i *)(table + 8)); + result0 = _mm_subs_epu16(value0, wsize); + result1 = _mm_subs_epu16(value1, wsize); + _mm_store_si128((__m128i *)table, result0); + _mm_store_si128((__m128i *)(table + 8), result1); + + table -= 16; + entries -= 16; + } while (entries > 0); + + ++on_chain; + if (on_chain > 1) { + return; + } else { + goto next_chain; + } +} + +Z_INTERNAL void slide_hash_sse2(deflate_state *s) { + uint16_t wsize = (uint16_t)s->w_size; + const __m128i xmm_wsize = _mm_set1_epi16((short)wsize); + + assert(((uintptr_t)s->head & 15) == 0); + assert(((uintptr_t)s->prev & 15) == 0); + + slide_hash_chain(s->head, s->prev, HASH_SIZE, wsize, xmm_wsize); +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.c new file mode 100644 index 000000000..3272e3fdd --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.c @@ -0,0 +1,97 @@ +/* x86_features.c - x86 feature check + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Author: + * Jim Kukunas + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "../../zbuild.h" +#include "x86_features.h" + +#ifdef _WIN32 +# include +#else +// Newer versions of GCC and clang come with cpuid.h +# include +#endif + +#include + +static inline void cpuid(int info, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuid((int *)registers, info); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid(info, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline void cpuidex(int info, int subinfo, unsigned* eax, unsigned* ebx, unsigned* ecx, unsigned* edx) { +#ifdef _WIN32 + unsigned int registers[4]; + __cpuidex((int *)registers, info, subinfo); + + *eax = registers[0]; + *ebx = registers[1]; + *ecx = registers[2]; + *edx = registers[3]; +#else + __cpuid_count(info, subinfo, *eax, *ebx, *ecx, *edx); +#endif +} + +static inline uint64_t xgetbv(unsigned int xcr) { +#ifdef _WIN32 + return _xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ ( ".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (uint64_t)(edx) << 32 | eax; +#endif +} + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features) { + unsigned eax, ebx, ecx, edx; + unsigned maxbasic; + + cpuid(0, &maxbasic, &ebx, &ecx, &edx); + cpuid(1 /*CPU_PROCINFO_AND_FEATUREBITS*/, &eax, &ebx, &ecx, &edx); + + features->has_sse2 = edx & 0x4000000; + features->has_ssse3 = ecx & 0x200; + features->has_sse42 = ecx & 0x100000; + features->has_pclmulqdq = ecx & 0x2; + + if (ecx & 0x08000000) { + uint64_t xfeature = xgetbv(0); + + features->has_os_save_ymm = ((xfeature & 0x06) == 0x06); + features->has_os_save_zmm = ((xfeature & 0xe6) == 0xe6); + } + + if (maxbasic >= 7) { + cpuidex(7, 0, &eax, &ebx, &ecx, &edx); + + // check BMI1 bit + // Reference: https://software.intel.com/sites/default/files/article/405250/how-to-detect-new-instruction-support-in-the-4th-generation-intel-core-processor-family.pdf + features->has_vpclmulqdq = ecx & 0x400; + + // check AVX2 bit if the OS supports saving YMM registers + if (features->has_os_save_ymm) { + features->has_avx2 = ebx & 0x20; + } + + // check AVX512 bits if the OS supports saving ZMM registers + if (features->has_os_save_zmm) { + features->has_avx512 = ebx & 0x00010000; + features->has_avx512vnni = ecx & 0x800; + } + } +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.h new file mode 100644 index 000000000..4a36bde83 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/arch/x86/x86_features.h @@ -0,0 +1,24 @@ +/* x86_features.h -- check for CPU features +* Copyright (C) 2013 Intel Corporation Jim Kukunas +* For conditions of distribution and use, see copyright notice in zlib.h +*/ + +#ifndef X86_FEATURES_H_ +#define X86_FEATURES_H_ + +struct x86_cpu_features { + int has_avx2; + int has_avx512; + int has_avx512vnni; + int has_sse2; + int has_ssse3; + int has_sse42; + int has_pclmulqdq; + int has_vpclmulqdq; + int has_os_save_ymm; + int has_os_save_zmm; +}; + +void Z_INTERNAL x86_check_features(struct x86_cpu_features *features); + +#endif /* CPU_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/chunkset.c b/internal-complibs/zlib-ng-2.1.1-beta2/chunkset.c new file mode 100644 index 000000000..7b2bb7ba3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/chunkset.c @@ -0,0 +1,42 @@ +/* chunkset.c -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" + +typedef uint64_t chunk_t; + +#define CHUNK_SIZE 8 + +#define HAVE_CHUNKMEMSET_4 +#define HAVE_CHUNKMEMSET_8 + +static inline void chunkmemset_4(uint8_t *from, chunk_t *chunk) { + uint8_t *dest = (uint8_t *)chunk; + memcpy(dest, from, sizeof(uint32_t)); + memcpy(dest+4, from, sizeof(uint32_t)); +} + +static inline void chunkmemset_8(uint8_t *from, chunk_t *chunk) { + memcpy(chunk, from, sizeof(uint64_t)); +} + +static inline void loadchunk(uint8_t const *s, chunk_t *chunk) { + memcpy(chunk, (uint8_t *)s, sizeof(uint64_t)); +} + +static inline void storechunk(uint8_t *out, chunk_t *chunk) { + memcpy(out, chunk, sizeof(uint64_t)); +} + +#define CHUNKSIZE chunksize_c +#define CHUNKCOPY chunkcopy_c +#define CHUNKUNROLL chunkunroll_c +#define CHUNKMEMSET chunkmemset_c +#define CHUNKMEMSET_SAFE chunkmemset_safe_c + +#include "chunkset_tpl.h" + +#define INFLATE_FAST inflate_fast_c + +#include "inffast_tpl.h" diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/chunkset_tpl.h b/internal-complibs/zlib-ng-2.1.1-beta2/chunkset_tpl.h new file mode 100644 index 000000000..f909a1255 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/chunkset_tpl.h @@ -0,0 +1,200 @@ +/* chunkset_tpl.h -- inline functions to copy small data chunks. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include + +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) +extern uint8_t* chunkmemset_ssse3(uint8_t *out, unsigned dist, unsigned len); +#endif + +/* Returns the chunk size */ +Z_INTERNAL uint32_t CHUNKSIZE(void) { + return sizeof(chunk_t); +} + +/* Behave like memcpy, but assume that it's OK to overwrite at least + chunk_t bytes of output even if the length is shorter than this, + that the length is non-zero, and that `from` lags `out` by at least + sizeof chunk_t bytes (or that they don't overlap at all or simply that + the distance is less than the length of the copy). + + Aside from better memory bus utilisation, this means that short copies + (chunk_t bytes or fewer) will fall straight through the loop + without iteration, which will hopefully make the branch prediction more + reliable. */ +#ifndef HAVE_CHUNKCOPY +Z_INTERNAL uint8_t* CHUNKCOPY(uint8_t *out, uint8_t const *from, unsigned len) { + Assert(len > 0, "chunkcopy should never have a length 0"); + chunk_t chunk; + int32_t align = ((len - 1) % sizeof(chunk_t)) + 1; + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += align; + from += align; + len -= align; + while (len > 0) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += sizeof(chunk_t); + from += sizeof(chunk_t); + len -= sizeof(chunk_t); + } + return out; +} +#endif + +/* Perform short copies until distance can be rewritten as being at least + sizeof chunk_t. + + This assumes that it's OK to overwrite at least the first + 2*sizeof(chunk_t) bytes of output even if the copy is shorter than this. + This assumption holds because inflate_fast() starts every iteration with at + least 258 bytes of output space available (258 being the maximum length + output from a single token; see inflate_fast()'s assumptions below). */ +#ifndef HAVE_CHUNKUNROLL +Z_INTERNAL uint8_t* CHUNKUNROLL(uint8_t *out, unsigned *dist, unsigned *len) { + unsigned char const *from = out - *dist; + chunk_t chunk; + while (*dist < *len && *dist < sizeof(chunk_t)) { + loadchunk(from, &chunk); + storechunk(out, &chunk); + out += *dist; + *len -= *dist; + *dist += *dist; + } + return out; +} +#endif + +#ifndef HAVE_CHUNK_MAG +/* Loads a magazine to feed into memory of the pattern */ +static inline chunk_t GET_CHUNK_MAG(uint8_t *buf, uint32_t *chunk_rem, uint32_t dist) { + /* This code takes string of length dist from "from" and repeats + * it for as many times as can fit in a chunk_t (vector register) */ + uint32_t cpy_dist; + uint32_t bytes_remaining = sizeof(chunk_t); + chunk_t chunk_load; + uint8_t *cur_chunk = (uint8_t *)&chunk_load; + while (bytes_remaining) { + cpy_dist = MIN(dist, bytes_remaining); + memcpy(cur_chunk, buf, cpy_dist); + bytes_remaining -= cpy_dist; + cur_chunk += cpy_dist; + /* This allows us to bypass an expensive integer division since we're effectively + * counting in this loop, anyway */ + *chunk_rem = cpy_dist; + } + + return chunk_load; +} +#endif + +/* Copy DIST bytes from OUT - DIST into OUT + DIST * k, for 0 <= k < LEN/DIST. + Return OUT + LEN. */ +Z_INTERNAL uint8_t* CHUNKMEMSET(uint8_t *out, unsigned dist, unsigned len) { + /* Debug performance related issues when len < sizeof(uint64_t): + Assert(len >= sizeof(uint64_t), "chunkmemset should be called on larger chunks"); */ + Assert(dist > 0, "chunkmemset cannot have a distance 0"); + /* Only AVX2 */ +#if CHUNK_SIZE == 32 && defined(X86_SSSE3) && defined(X86_SSE2) + if (len <= 16) { + return chunkmemset_ssse3(out, dist, len); + } +#endif + + uint8_t *from = out - dist; + + if (dist == 1) { + memset(out, *from, len); + return out + len; + } else if (dist > sizeof(chunk_t)) { + return CHUNKCOPY(out, out - dist, len); + } + + chunk_t chunk_load; + uint32_t chunk_mod = 0; + + /* TODO: possibly build up a permutation table for this if not an even modulus */ +#ifdef HAVE_CHUNKMEMSET_2 + if (dist == 2) { + chunkmemset_2(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_4 + if (dist == 4) { + chunkmemset_4(from, &chunk_load); + } else +#endif +#ifdef HAVE_CHUNKMEMSET_8 + if (dist == 8) { + chunkmemset_8(from, &chunk_load); + } else if (dist == sizeof(chunk_t)) { + loadchunk(from, &chunk_load); + } else +#endif + { + chunk_load = GET_CHUNK_MAG(from, &chunk_mod, dist); + } + + /* If we're lucky enough and dist happens to be an even modulus of our vector length, + * we can do two stores per loop iteration, which for most ISAs, especially x86, is beneficial */ + if (chunk_mod == 0) { + while (len >= (2 * sizeof(chunk_t))) { + storechunk(out, &chunk_load); + storechunk(out + sizeof(chunk_t), &chunk_load); + out += 2 * sizeof(chunk_t); + len -= 2 * sizeof(chunk_t); + } + } + + /* If we don't have a "dist" length that divides evenly into a vector + * register, we can write the whole vector register but we need only + * advance by the amount of the whole string that fits in our chunk_t. + * If we do divide evenly into the vector length, adv_amount = chunk_t size*/ + uint32_t adv_amount = sizeof(chunk_t) - chunk_mod; + while (len >= sizeof(chunk_t)) { + storechunk(out, &chunk_load); + len -= adv_amount; + out += adv_amount; + } + + if (len) { + memcpy(out, &chunk_load, len); + out += len; + } + + return out; +} + +Z_INTERNAL uint8_t* CHUNKMEMSET_SAFE(uint8_t *out, unsigned dist, unsigned len, unsigned left) { +#if !defined(UNALIGNED64_OK) +# if !defined(UNALIGNED_OK) + static const uint32_t align_mask = 7; +# else + static const uint32_t align_mask = 3; +# endif +#endif + + len = MIN(len, left); + uint8_t *from = out - dist; +#if !defined(UNALIGNED64_OK) + while (((uintptr_t)out & align_mask) && (len > 0)) { + *out++ = *from++; + --len; + --left; + } +#endif + if (left < (unsigned)(3 * sizeof(chunk_t))) { + while (len > 0) { + *out++ = *from++; + --len; + } + return out; + } + if (len) + return CHUNKMEMSET(out, dist, len); + + return out; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.c b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.c new file mode 100644 index 000000000..ff1a05a25 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.c @@ -0,0 +1,111 @@ +// archdetect.c -- Detect compiler architecture and raise preprocessor error +// containing a simple arch identifier. +// Copyright (C) 2019 Hans Kristian Rosbach +// Licensed under the Zlib license, see LICENSE.md for details + +// x86_64 +#if defined(__x86_64__) || defined(_M_X64) + #error archfound x86_64 + +// x86 +#elif defined(__i386) || defined(_M_IX86) + #error archfound i686 + +// ARM +#elif defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) + #error archfound aarch64 +#elif defined(__arm__) || defined(__arm) || defined(_M_ARM) || defined(__TARGET_ARCH_ARM) + #if defined(__ARM64_ARCH_8__) || defined(__ARMv8__) || defined(__ARMv8_A__) + #error archfound armv8 + #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) + #error archfound armv7 + #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6M__) + #error archfound armv6 + #elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) + #error archfound armv5 + #elif defined(__ARM_ARCH_4T__) || defined(__TARGET_ARCH_5E__) + #error archfound armv4 + #elif defined(__ARM_ARCH_3__) || defined(__TARGET_ARCH_3M__) + #error archfound armv3 + #elif defined(__ARM_ARCH_2__) + #error archfound armv2 + #endif + +// PowerPC +#elif defined(__powerpc__) || defined(_ppc__) || defined(__PPC__) + #if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) + #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + #error archfound powerpc64le + #else + #error archfound powerpc64 + #endif + #else + #error archfound powerpc + #endif + +// --------------- Less common architectures alphabetically below --------------- + +// ALPHA +#elif defined(__alpha__) || defined(__alpha) + #error archfound alpha + +// Blackfin +#elif defined(__BFIN__) + #error archfound blackfin + +// Itanium +#elif defined(__ia64) || defined(_M_IA64) + #error archfound ia64 + +// MIPS +#elif defined(__mips__) || defined(__mips) + #error archfound mips + +// Motorola 68000-series +#elif defined(__m68k__) + #error archfound m68k + +// SuperH +#elif defined(__sh__) + #error archfound sh + +// SPARC +#elif defined(__sparc__) || defined(__sparc) + #if defined(__sparcv9) || defined(__sparc_v9__) + #error archfound sparc9 + #elif defined(__sparcv8) || defined(__sparc_v8__) + #error archfound sparc8 + #endif + +// SystemZ +#elif defined(__370__) + #error archfound s370 +#elif defined(__s390__) + #error archfound s390 +#elif defined(__s390x) || defined(__zarch__) + #error archfound s390x + +// PARISC +#elif defined(__hppa__) + #error archfound parisc + +// RS-6000 +#elif defined(__THW_RS6000) + #error archfound rs6000 + +// RISC-V +#elif defined(__riscv) + #if __riscv_xlen == 64 + #error archfound riscv64 + #elif __riscv_xlen == 32 + #error archfound riscv32 + #endif + +// Emscripten (WebAssembly) +#elif defined(__EMSCRIPTEN__) + #error archfound wasm32 + +// return 'unrecognized' if we do not know what architecture this is +#else + #error archfound unrecognized +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.cmake new file mode 100644 index 000000000..21c237d61 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-arch.cmake @@ -0,0 +1,101 @@ +# detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH +# Copyright (C) 2019 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details +set(ARCHDETECT_FOUND TRUE) + +if(CMAKE_OSX_ARCHITECTURES) + # If multiple architectures are requested (universal build), pick only the first + list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH) +elseif(MSVC) + if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86") + set(ARCH "i686") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64") + set(ARCH "x86_64") + elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7") + set(ARCH "arm") + elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64") + set(ARCH "aarch64") + endif() +elseif(EMSCRIPTEN) + set(ARCH "wasm32") +elseif(CMAKE_CROSSCOMPILING) + set(ARCH ${CMAKE_C_COMPILER_TARGET}) +else() + # Let preprocessor parse archdetect.c and raise an error containing the arch identifier + enable_language(C) + try_run( + run_result_unused + compile_result_unused + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_LIST_DIR}/detect-arch.c + COMPILE_OUTPUT_VARIABLE RAWOUTPUT + CMAKE_FLAGS CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} + ) + + # Find basearch tag, and extract the arch word into BASEARCH variable + string(REGEX REPLACE ".*archfound ([a-zA-Z0-9_]+).*" "\\1" ARCH "${RAWOUTPUT}") + if(NOT ARCH) + set(ARCH unknown) + endif() +endif() + +# Make sure we have ARCH set +if(NOT ARCH OR ARCH STREQUAL "unknown") + set(ARCH ${CMAKE_SYSTEM_PROCESSOR}) + message(STATUS "Arch not recognized, falling back to cmake arch: '${ARCH}'") +else() + message(STATUS "Arch detected: '${ARCH}'") +endif() + +# Base arch detection +if("${ARCH}" MATCHES "(x86_64|AMD64|i[3-6]86)") + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) +elseif("${ARCH}" MATCHES "(arm(v[0-9])?|aarch64)") + set(BASEARCH "arm") + set(BASEARCH_ARM_FOUND TRUE) +elseif("${ARCH}" MATCHES "ppc(64(le)?)?|powerpc(64(le)?)?") + set(BASEARCH "ppc") + set(BASEARCH_PPC_FOUND TRUE) +elseif("${ARCH}" MATCHES "alpha") + set(BASEARCH "alpha") + set(BASEARCH_ALPHA_FOUND TRUE) +elseif("${ARCH}" MATCHES "blackfin") + set(BASEARCH "blackfin") + set(BASEARCH_BLACKFIN_FOUND TRUE) +elseif("${ARCH}" MATCHES "ia64") + set(BASEARCH "ia64") + set(BASEARCH_IA64_FOUND TRUE) +elseif("${ARCH}" MATCHES "mips") + set(BASEARCH "mips") + set(BASEARCH_MIPS_FOUND TRUE) +elseif("${ARCH}" MATCHES "m68k") + set(BASEARCH "m68k") + set(BASEARCH_M68K_FOUND TRUE) +elseif("${ARCH}" MATCHES "sh") + set(BASEARCH "sh") + set(BASEARCH_SH_FOUND TRUE) +elseif("${ARCH}" MATCHES "sparc[89]?") + set(BASEARCH "sparc") + set(BASEARCH_SPARC_FOUND TRUE) +elseif("${ARCH}" MATCHES "s3[679]0x?") + set(BASEARCH "s360") + set(BASEARCH_S360_FOUND TRUE) +elseif("${ARCH}" MATCHES "parisc") + set(BASEARCH "parisc") + set(BASEARCH_PARISC_FOUND TRUE) +elseif("${ARCH}" MATCHES "rs6000") + set(BASEARCH "rs6000") + set(BASEARCH_RS6000_FOUND TRUE) +elseif("${ARCH}" MATCHES "riscv(32|64)") + set(BASEARCH "riscv") + set(BASEARCH_RISCV_FOUND TRUE) +elseif("${ARCH}" MATCHES "wasm32") + set(BASEARCH "wasm32") + set(BASEARCH_WASM32_FOUND TRUE) +else() + set(BASEARCH "x86") + set(BASEARCH_X86_FOUND TRUE) + message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.") +endif() +message(STATUS "Basearch of '${ARCH}' has been detected as: '${BASEARCH}'") diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-coverage.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-coverage.cmake new file mode 100644 index 000000000..8e67a085c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-coverage.cmake @@ -0,0 +1,46 @@ +# detect-coverage.cmake -- Detect supported compiler coverage flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_code_coverage) + # Check for -coverage flag support for Clang/GCC + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -coverage) + endif() + check_c_compiler_flag(-coverage HAVE_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_COVERAGE) + add_compile_options(-coverage) + add_link_options(-coverage) + message(STATUS "Code coverage enabled using: -coverage") + else() + # Some versions of GCC don't support -coverage shorthand + if(CMAKE_VERSION VERSION_LESS 3.14) + set(CMAKE_REQUIRED_LIBRARIES -lgcov) + else() + set(CMAKE_REQUIRED_LINK_OPTIONS -lgcov -fprofile-arcs) + endif() + check_c_compiler_flag("-ftest-coverage -fprofile-arcs -fprofile-values" HAVE_TEST_COVERAGE) + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_LINK_OPTIONS) + + if(HAVE_TEST_COVERAGE) + add_compile_options(-ftest-coverage -fprofile-arcs -fprofile-values) + add_link_options(-lgcov -fprofile-arcs) + message(STATUS "Code coverage enabled using: -ftest-coverage") + else() + message(WARNING "Compiler does not support code coverage") + set(WITH_CODE_COVERAGE OFF) + endif() + endif() + + # Set optimization level to zero for code coverage builds + if (WITH_CODE_COVERAGE) + # Use CMake compiler flag variables due to add_compile_options failure on Windows GCC + set(CMAKE_C_FLAGS "-O0 ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-O0 ${CMAKE_CXX_FLAGS}") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-install-dirs.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-install-dirs.cmake new file mode 100644 index 000000000..a7c774f47 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-install-dirs.cmake @@ -0,0 +1,43 @@ +# detect-install-dirs.cmake -- Detect install directory parameters +# Copyright (C) 2021 Hans Kristian Rosbach +# Licensed under the Zlib license, see LICENSE.md for details + +# Determine installation directory for executables +if (DEFINED BIN_INSTALL_DIR) + set(BIN_INSTALL_DIR "${BIN_INSTALL_DIR}" CACHE PATH "Installation directory for executables (Deprecated)" FORCE) + set(CMAKE_INSTALL_BINDIR "${BIN_INSTALL_DIR}") +elseif (DEFINED INSTALL_BIN_DIR) + set(CMAKE_INSTALL_BINDIR "${INSTALL_BIN_DIR}") +endif() + +# Determine installation directory for libraries +if (DEFINED LIB_INSTALL_DIR) + set(LIB_INSTALL_DIR "${LIB_INSTALL_DIR}" CACHE PATH "Installation directory for libraries (Deprecated)" FORCE) + set(CMAKE_INSTALL_LIBDIR "${LIB_INSTALL_DIR}") +elseif (DEFINED INSTALL_LIB_DIR) + set(CMAKE_INSTALL_LIBDIR "${INSTALL_LIB_DIR}") +endif() + +# Determine installation directory for include files +if (DEFINED INC_INSTALL_DIR) + set(INC_INSTALL_DIR "${INC_INSTALL_DIR}" CACHE PATH "Installation directory for headers (Deprecated)" FORCE) + set(CMAKE_INSTALL_INCLUDEDIR "${INC_INSTALL_DIR}") +elseif (DEFINED INSTALL_INC_DIR) + set(CMAKE_INSTALL_INCLUDEDIR "${INSTALL_INC_DIR}") +endif() + +# Define GNU standard installation directories +include(GNUInstallDirs) + +# Determine installation directory for pkgconfig files +if (DEFINED PKGCONFIG_INSTALL_DIR) + set(PKGCONFIG_INSTALL_DIR "${PKGCONFIG_INSTALL_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED INSTALL_PKGCONFIG_DIR) + set(PKGCONFIG_INSTALL_DIR "${INSTALL_PKGCONFIG_DIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +elseif (DEFINED CMAKE_INSTALL_FULL_PKGCONFIGDIR) + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_FULL_PKGCONFIGDIR}" CACHE PATH "Installation directory for pkgconfig (.pc) files" FORCE) +else() + set(PKGCONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files") +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-intrinsics.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-intrinsics.cmake new file mode 100644 index 000000000..e9e6d36da --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-intrinsics.cmake @@ -0,0 +1,548 @@ +# detect-intrinsics.cmake -- Detect compiler intrinsics support +# Licensed under the Zlib license, see LICENSE.md for details + +macro(check_acle_compiler_flag) + if(MSVC) + # Both ARM and ARM64-targeting msvc support intrinsics, but + # ARM msvc is missing some intrinsics introduced with ARMv8, e.g. crc32 + if(MSVC_C_ARCHITECTURE_ID STREQUAL "ARM64") + set(HAVE_ACLE_FLAG TRUE) + endif() + else() + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc" CACHE INTERNAL "Compiler option to enable ACLE support") + endif() + endif() + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG FAIL_REGEX "not supported") + if(NOT NATIVEFLAG AND NOT HAVE_ACLE_FLAG) + set(ACLEFLAG "-march=armv8-a+crc+simd" CACHE INTERNAL "Compiler option to enable ACLE support" FORCE) + # Check whether compiler supports ACLE flag + set(CMAKE_REQUIRED_FLAGS "${ACLEFLAG}") + check_c_source_compiles( + "int main() { return 0; }" + HAVE_ACLE_FLAG2 FAIL_REGEX "not supported") + set(HAVE_ACLE_FLAG ${HAVE_ACLE_FLAG2} CACHE INTERNAL "Have compiler option to enable ACLE intrinsics" FORCE) + unset(HAVE_ACLE_FLAG2 CACHE) # Don't cache this internal variable + endif() + set(CMAKE_REQUIRED_FLAGS) + endif() +endmacro() + +macro(check_avx512_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + else() + set(AVX512FLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + # For CPUs that can benefit from AVX512, it seems GCC generates suboptimal + # instruction scheduling unless you specify a reasonable -mtune= target + set(AVX512FLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE) + if(HAVE_CASCADE_LAKE) + set(AVX512FLAG "${AVX512FLAG} -mtune=cascadelake") + else() + set(AVX512FLAG "${AVX512FLAG} -mtune=skylake-avx512") + endif() + unset(HAVE_CASCADE_LAKE) + endif() + endif() + elseif(MSVC) + set(AVX512FLAG "/arch:AVX512") + endif() + # Check whether compiler supports AVX512 intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; + }" + HAVE_AVX512_INTRIN + ) + + # Evidently both GCC and clang were late to implementing these + check_c_source_compile_or_run( + "#include + int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; + }" + HAVE_MASK_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx512vnni_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX512VNNIFLAG "-mavx512f -mavx512bw -mavx512dq -mavx512vl -mavx512vnni") + else() + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX512VNNIFLAG "-mavx512f -mavx512dq -mavx512bw -mavx512vl -mavx512vnni") + if(NOT CMAKE_GENERATOR_TOOLSET MATCHES "ClangCl") + check_c_compiler_flag("-mtune=cascadelake" HAVE_CASCADE_LAKE) + if(HAVE_CASCADE_LAKE) + set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=cascadelake") + else() + set(AVX512VNNIFLAG "${AVX512VNNIFLAG} -mtune=skylake-avx512") + endif() + unset(HAVE_CASCADE_LAKE) + endif() + endif() + elseif(MSVC) + set(AVX512VNNIFLAG "/arch:AVX512") + endif() + + # Check whether compiler supports AVX512vnni intrinsics + set(CMAKE_REQUIRED_FLAGS "${AVX512VNNIFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; + }" + HAVE_AVX512VNNI_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_avx2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(AVX2FLAG "-mavx2") + else() + set(AVX2FLAG "/arch:AVX2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(AVX2FLAG "-mavx2") + endif() + elseif(MSVC) + set(AVX2FLAG "/arch:AVX2") + endif() + # Check whether compiler supports AVX2 intrinics + set(CMAKE_REQUIRED_FLAGS "${AVX2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; + }" + HAVE_AVX2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_compiler_flag) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports NEON flag + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main() { return 0; }" + MFPU_NEON_AVAILABLE FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_neon_ld4_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + if("${ARCH}" MATCHES "aarch64") + set(NEONFLAG "-march=armv8-a+simd") + else() + set(NEONFLAG "-mfpu=neon") + endif() + endif() + endif() + # Check whether compiler supports loading 4 neon vecs into a register range + set(CMAKE_REQUIRED_FLAGS "${NEONFLAG}") + check_c_source_compiles( + "#ifdef _M_ARM64 + # include + #else + # include + #endif + int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; + }" + NEON_HAS_LD4) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_pclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(PCLMULFLAG "-mpclmul") + endif() + endif() + # Check whether compiler supports PCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + # The pclmul code currently crashes on Mac in 32bit mode. Avoid for now. + set(CMAKE_REQUIRED_FLAGS "${PCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_PCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_PCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_vpclmulqdq_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(VPCLMULFLAG "-mvpclmulqdq -mavx512f") + endif() + endif() + # Check whether compiler supports VPCLMULQDQ intrinsics + if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + set(CMAKE_REQUIRED_FLAGS "${VPCLMULFLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; + }" + HAVE_VPCLMULQDQ_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) + else() + set(HAVE_VPCLMULQDQ_INTRIN OFF) + endif() +endmacro() + +macro(check_ppc_intrinsics) + # Check if compiler supports AltiVec + set(CMAKE_REQUIRED_FLAGS "-maltivec") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_ALTIVEC + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_ALTIVEC) + set(PPCFLAGS "-maltivec") + endif() + + set(CMAKE_REQUIRED_FLAGS "-maltivec -mno-vsx") + check_c_source_compiles( + "#include + int main(void) + { + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; + }" + HAVE_NOVSX + ) + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_NOVSX) + set(PPCFLAGS "${PPCFLAGS} -mno-vsx") + endif() + + # Check if we have what we need for AltiVec optimizations + set(CMAKE_REQUIRED_FLAGS "${PPCFLAGS} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); + #else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); + #endif + }" + HAVE_VMX + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_power8_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER8FLAG "-mcpu=power8") + endif() + endif() + # Check if we have what we need for POWER8 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER8FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + #ifdef __FreeBSD__ + #include + #endif + int main() { + #ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); + #else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); + #endif + }" + HAVE_POWER8_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_rvv_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(RISCVFLAG "-march=rv64gcv") + endif() + endif() + # Check whether compiler supports RVV + set(CMAKE_REQUIRED_FLAGS "${RISCVFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + int main() { + return 0; + }" + HAVE_RVV_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_s390_intrinsics) + check_c_source_compiles( + "#include + #ifndef HWCAP_S390_VXRS + #define HWCAP_S390_VXRS HWCAP_S390_VX + #endif + int main() { + return (getauxval(AT_HWCAP) & HWCAP_S390_VXRS); + }" + HAVE_S390_INTRIN + ) +endmacro() + +macro(check_power9_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(POWER9FLAG "-mcpu=power9") + endif() + endif() + # Check if we have what we need for POWER9 optimizations + set(CMAKE_REQUIRED_FLAGS "${POWER9FLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "int main() { + return 0; + }" + HAVE_POWER9_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_sse2_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE2FLAG "-msse2") + else() + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(MSVC) + if(NOT "${ARCH}" MATCHES "x86_64") + set(SSE2FLAG "/arch:SSE2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE2FLAG "-msse2") + endif() + endif() + # Check whether compiler supports SSE2 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSE2FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; + }" + HAVE_SSE2_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_ssse3_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSSE3FLAG "-mssse3") + else() + set(SSSE3FLAG "/arch:SSSE3") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSSE3FLAG "-mssse3") + endif() + endif() + # Check whether compiler supports SSSE3 intrinsics + set(CMAKE_REQUIRED_FLAGS "${SSSE3FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "#include + int main(void) { + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; + }" + HAVE_SSSE3_INTRIN + ) +endmacro() + +macro(check_sse42_intrinsics) + if(CMAKE_C_COMPILER_ID MATCHES "Intel") + if(CMAKE_HOST_UNIX OR APPLE) + set(SSE42FLAG "-msse4.2") + else() + set(SSE42FLAG "/arch:SSE4.2") + endif() + elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + if(NOT NATIVEFLAG) + set(SSE42FLAG "-msse4.2") + endif() + endif() + # Check whether compiler supports SSE4.2 CRC inline asm + set(CMAKE_REQUIRED_FLAGS "${SSE42FLAG} ${NATIVEFLAG}") + check_c_source_compile_or_run( + "int main(void) { + unsigned val = 0, h = 0; + #if defined(_MSC_VER) + { __asm mov edx, h __asm mov eax, val __asm crc32 eax, edx __asm mov h, eax } + #else + __asm__ __volatile__ ( \"crc32 %1,%0\" : \"+r\" (h) : \"r\" (val) ); + #endif + return (int)h; + }" + HAVE_SSE42CRC_INLINE_ASM + ) + # Check whether compiler supports SSE4.2 CRC intrinsics + check_c_source_compile_or_run( + "#include + int main(void) { + unsigned crc = 0; + char c = 'c'; + #if defined(_MSC_VER) + crc = _mm_crc32_u32(crc, c); + #else + crc = __builtin_ia32_crc32qi(crc, c); + #endif + (void)crc; + return 0; + }" + HAVE_SSE42CRC_INTRIN + ) + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_vgfma_intrinsics) + if(NOT NATIVEFLAG) + set(VGFMAFLAG "-march=z13") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") + set(VGFMAFLAG "${VGFMAFLAG} -mzarch") + endif() + if(CMAKE_C_COMPILER_ID MATCHES "Clang") + set(VGFMAFLAG "${VGFMAFLAG} -fzvector") + endif() + endif() + # Check whether compiler supports "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic + set(CMAKE_REQUIRED_FLAGS "${VGFMAFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#include + int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; + }" + HAVE_VGFMA_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() + +macro(check_xsave_intrinsics) + if(NOT NATIVEFLAG AND NOT MSVC) + set(XSAVEFLAG "-mxsave") + endif() + set(CMAKE_REQUIRED_FLAGS "${XSAVEFLAG} ${NATIVEFLAG}") + check_c_source_compiles( + "#ifdef _WIN32 + # include + #else + # include + #endif + int main(void) { + return _xgetbv(0); + }" + HAVE_XSAVE_INTRIN FAIL_REGEX "not supported") + set(CMAKE_REQUIRED_FLAGS) +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-sanitizer.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-sanitizer.cmake new file mode 100644 index 000000000..f9521ec2f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/detect-sanitizer.cmake @@ -0,0 +1,166 @@ +# detect-sanitizer.cmake -- Detect supported compiler sanitizer flags +# Licensed under the Zlib license, see LICENSE.md for details + +macro(add_common_sanitizer_flags) + if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") + add_compile_options(-g3) + endif() + check_c_compiler_flag(-fno-omit-frame-pointer HAVE_NO_OMIT_FRAME_POINTER) + if(HAVE_NO_OMIT_FRAME_POINTER) + add_compile_options(-fno-omit-frame-pointer) + add_link_options(-fno-omit-frame-pointer) + endif() + check_c_compiler_flag(-fno-optimize-sibling-calls HAVE_NO_OPTIMIZE_SIBLING_CALLS) + if(HAVE_NO_OPTIMIZE_SIBLING_CALLS) + add_compile_options(-fno-optimize-sibling-calls) + add_link_options(-fno-optimize-sibling-calls) + endif() +endmacro() + +macro(check_sanitizer_support known_checks supported_checks) + set(available_checks "") + + # Build list of supported sanitizer flags by incrementally trying compilation with + # known sanitizer checks + + foreach(check ${known_checks}) + if(available_checks STREQUAL "") + set(compile_checks "${check}") + else() + set(compile_checks "${available_checks},${check}") + endif() + + set(CMAKE_REQUIRED_FLAGS -fsanitize=${compile_checks}) + + check_c_source_compiles("int main() { return 0; }" HAVE_SANITIZER_${check} + FAIL_REGEX "not supported|unrecognized command|unknown option") + + set(CMAKE_REQUIRED_FLAGS) + + if(HAVE_SANITIZER_${check}) + set(available_checks ${compile_checks}) + endif() + endforeach() + + set(${supported_checks} ${available_checks}) +endmacro() + +macro(add_address_sanitizer) + set(known_checks + address + pointer-compare + pointer-subtract + ) + + check_sanitizer_support("${known_checks}" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Address sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Address sanitizer is not supported") + endif() + + if(CMAKE_CROSSCOMPILING_EMULATOR) + # Only check for leak sanitizer if not cross-compiling due to qemu crash + message(WARNING "Leak sanitizer is not supported when cross compiling") + else() + # Leak sanitizer requires address sanitizer + check_sanitizer_support("leak" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Leak sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Leak sanitizer is not supported") + endif() + endif() +endmacro() + +macro(add_memory_sanitizer) + check_sanitizer_support("memory" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Memory sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + + check_c_compiler_flag(-fsanitize-memory-track-origins HAVE_MEMORY_TRACK_ORIGINS) + if(HAVE_MEMORY_TRACK_ORIGINS) + add_compile_options(-fsanitize-memory-track-origins) + add_link_options(-fsanitize-memory-track-origins) + endif() + else() + message(STATUS "Memory sanitizer is not supported") + endif() +endmacro() + +macro(add_thread_sanitizer) + check_sanitizer_support("thread" supported_checks) + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Thread sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + add_common_sanitizer_flags() + else() + message(STATUS "Thread sanitizer is not supported") + endif() +endmacro() + +macro(add_undefined_sanitizer) + set(known_checks + array-bounds + bool + bounds + builtin + enum + float-cast-overflow + float-divide-by-zero + function + integer-divide-by-zero + local-bounds + null + nonnull-attribute + pointer-overflow + return + returns-nonnull-attribute + shift + shift-base + shift-exponent + signed-integer-overflow + undefined + unsigned-integer-overflow + unsigned-shift-base + vla-bound + vptr + ) + + # Only check for alignment sanitizer flag if unaligned access is not supported + if(NOT WITH_UNALIGNED) + list(APPEND known_checks alignment) + endif() + # Object size sanitizer has no effect at -O0 and produces compiler warning if enabled + if(NOT CMAKE_C_FLAGS MATCHES "-O0") + list(APPEND known_checks object-size) + endif() + + check_sanitizer_support("${known_checks}" supported_checks) + + if(NOT ${supported_checks} STREQUAL "") + message(STATUS "Undefined behavior sanitizer is enabled: ${supported_checks}") + add_compile_options(-fsanitize=${supported_checks}) + add_link_options(-fsanitize=${supported_checks}) + + # Group sanitizer flag -fsanitize=undefined will automatically add alignment, even if + # it is not in our sanitize flag list, so we need to explicitly disable alignment sanitizing. + if(WITH_UNALIGNED) + add_compile_options(-fno-sanitize=alignment) + endif() + + add_common_sanitizer_flags() + else() + message(STATUS "Undefined behavior sanitizer is not supported") + endif() +endmacro() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/fallback-macros.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/fallback-macros.cmake new file mode 100644 index 000000000..8bc6cf25b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/fallback-macros.cmake @@ -0,0 +1,19 @@ +# fallback-macros.cmake -- CMake fallback macros +# Copyright (C) 2022 Nathan Moinvaziri +# Licensed under the Zlib license, see LICENSE.md for details + +# CMake less than version 3.5.2 +if(NOT COMMAND add_compile_options) + macro(add_compile_options options) + string(APPEND CMAKE_C_FLAGS ${options}) + string(APPEND CMAKE_CXX_FLAGS ${options}) + endmacro() +endif() + +# CMake less than version 3.14 +if(NOT COMMAND add_link_options) + macro(add_link_options options) + string(APPEND CMAKE_EXE_LINKER_FLAGS ${options}) + string(APPEND CMAKE_SHARED_LINKER_FLAGS ${options}) + endmacro() +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-aarch64.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-aarch64.cmake new file mode 100644 index 000000000..1e2473107 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-aarch64.cmake @@ -0,0 +1,24 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET "aarch64-linux-gnu") +set(CMAKE_CXX_COMPILER_TARGET "aarch64-linux-gnu") + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-aarch64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-arm.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-arm.cmake new file mode 100644 index 000000000..1bdd8d2cc --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-arm.cmake @@ -0,0 +1,29 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +if(NOT DEFINED CMAKE_C_COMPILER_TARGET) + set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabi) +endif() +if(NOT DEFINED CMAKE_CXX_COMPILER_TARGET) + set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabi) +endif() + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-armhf.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-armhf.cmake new file mode 100644 index 000000000..007859caf --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-armhf.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR arm) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf) +set(CMAKE_CXX_COMPILER_TARGET arm-linux-gnueabihf) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-arm -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-i686.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-i686.cmake new file mode 100644 index 000000000..b95e63f50 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-i686.cmake @@ -0,0 +1,35 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET i686-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET i686-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/i686-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES + ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-x86_64.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-x86_64.cmake new file mode 100644 index 000000000..8c660b0b1 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-mingw-x86_64.cmake @@ -0,0 +1,34 @@ +set(CMAKE_SYSTEM_NAME Windows) + +set(CMAKE_C_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_CXX_COMPILER_TARGET x86_64-w64-mingw32) +set(CMAKE_RC_COMPILER_TARGET x86_64-w64-mingw32) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR wine) + +set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32) +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + +# Prefer posix gcc variant for gtest pthread support +find_program(C_COMPILER_FULL_PATH NAMES + ${CMAKE_C_COMPILER_TARGET}-gcc-posix + ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES + ${CMAKE_CXX_COMPILER_TARGET}-g++-posix + ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() + +find_program(RC_COMPILER_FULL_PATH NAMES ${CMAKE_RC_COMPILER_TARGET}-windres) +if(RC_COMPILER_FULL_PATH) + set(CMAKE_RC_COMPILER ${RC_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc.cmake new file mode 100644 index 000000000..f09713370 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR powerpc) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc -cpu 7400 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64.cmake new file mode 100644 index 000000000..80d8b904e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64 -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64le.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64le.cmake new file mode 100644 index 000000000..68381de12 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-powerpc64le.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR ppc64le) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET powerpc64le-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET powerpc64le-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-ppc64le -cpu power8 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-riscv.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-riscv.cmake new file mode 100644 index 000000000..9cf8fdb7f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-riscv.cmake @@ -0,0 +1,28 @@ +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_SYSTEM_NAME "Linux") +set(CMAKE_SYSTEM_PROCESSOR "riscv64") + +# Avoid to use system path for cross-compile +set(CMAKE_FIND_USE_CMAKE_SYSTEM_PATH FALSE) + +set(TOOLCHAIN_PATH "" CACHE STRING "The toolchain path.") +if(NOT TOOLCHAIN_PATH) + set(TOOLCHAIN_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-clang) +endif() + +set(TOOLCHAIN_PREFIX "riscv64-unknown-linux-gnu-" CACHE STRING "The toolchain prefix.") +set(QEMU_PATH "" CACHE STRING "The qemu path.") +if(NOT QEMU_PATH) + set(QEMU_PATH ${CMAKE_SOURCE_DIR}/prebuilt-riscv-toolchain-qemu/riscv-qemu/bin/qemu-riscv64) +endif() + +# toolchain setting +set(CMAKE_C_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang") +set(CMAKE_CXX_COMPILER "${TOOLCHAIN_PATH}/bin/${TOOLCHAIN_PREFIX}clang++") + +# disable auto-vectorizer +add_compile_options(-fno-vectorize -fno-slp-vectorize) + +# emulator setting +set(QEMU_CPU_OPTION "rv64,zba=true,zbb=true,zbc=true,zbs=true,v=true,vlen=512,elen=64,vext_spec=v1.0") +set(CMAKE_CROSSCOMPILING_EMULATOR ${QEMU_PATH} -cpu ${QEMU_CPU_OPTION} -L ${TOOLCHAIN_PATH}/sysroot/) diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-s390x.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-s390x.cmake new file mode 100644 index 000000000..9455a2bed --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-s390x.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR s390x) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET s390x-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET s390x-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-s390x -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-sparc64.cmake b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-sparc64.cmake new file mode 100644 index 000000000..16161a78c --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cmake/toolchain-sparc64.cmake @@ -0,0 +1,25 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR sparc64) +set(CMAKE_SYSTEM_VERSION 1) + +set(CMAKE_C_COMPILER_TARGET sparc64-linux-gnu) +set(CMAKE_CXX_COMPILER_TARGET sparc64-linux-gnu) + +set(CMAKE_CROSSCOMPILING TRUE) +set(CMAKE_CROSSCOMPILING_EMULATOR qemu-sparc64 -L /usr/${CMAKE_C_COMPILER_TARGET}/) + +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + +find_program(C_COMPILER_FULL_PATH NAMES ${CMAKE_C_COMPILER_TARGET}-gcc) +if(NOT C_COMPILER_FULL_PATH) + message(FATAL_ERROR "Cross-compiler for ${CMAKE_C_COMPILER_TARGET} not found") +endif() +set(CMAKE_C_COMPILER ${C_COMPILER_FULL_PATH}) + +find_program(CXX_COMPILER_FULL_PATH NAMES g++-${CMAKE_CXX_COMPILER_TARGET} ${CMAKE_CXX_COMPILER_TARGET}-g++) +if(CXX_COMPILER_FULL_PATH) + set(CMAKE_CXX_COMPILER ${CXX_COMPILER_FULL_PATH}) +endif() diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/compare256.c b/internal-complibs/zlib-ng-2.1.1-beta2/compare256.c new file mode 100644 index 000000000..82551cdd5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/compare256.c @@ -0,0 +1,180 @@ +/* compare256.c -- 256 byte memory comparison with match length return + * Copyright (C) 2020 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "fallback_builtins.h" + +/* ALIGNED, byte comparison */ +static inline uint32_t compare256_c_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src0 += 1, src1 += 1, len += 1; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1) { + return compare256_c_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_c +#define COMPARE256 compare256_c_static + +#include "match_tpl.h" + +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +/* 16-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_16_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + + if (zng_memcmp_2(src0, src1) != 0) + return len + (*src0 == *src1); + src0 += 2, src1 += 2, len += 2; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_16_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_16 +#define COMPARE256 compare256_unaligned_16_static + +#include "match_tpl.h" + +#ifdef HAVE_BUILTIN_CTZ +/* 32-bit unaligned integer comparison */ +static inline uint32_t compare256_unaligned_32_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint32_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint32_t match_byte = __builtin_ctz(diff) / 8; + return len + match_byte; + } + + src0 += 4, src1 += 4, len += 4; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_32_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_32 +#define COMPARE256 compare256_unaligned_32_static + +#include "match_tpl.h" + +#endif + +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +/* UNALIGNED64_OK, 64-bit integer comparison */ +static inline uint32_t compare256_unaligned_64_static(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + uint64_t sv, mv, diff; + + memcpy(&sv, src0, sizeof(sv)); + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint64_t match_byte = __builtin_ctzll(diff) / 8; + return len + (uint32_t)match_byte; + } + + src0 += 8, src1 += 8, len += 8; + } while (len < 256); + + return 256; +} + +Z_INTERNAL uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1) { + return compare256_unaligned_64_static(src0, src1); +} + +#define LONGEST_MATCH longest_match_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#define LONGEST_MATCH_SLOW +#define LONGEST_MATCH longest_match_slow_unaligned_64 +#define COMPARE256 compare256_unaligned_64_static + +#include "match_tpl.h" + +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/compare256_rle.h b/internal-complibs/zlib-ng-2.1.1-beta2/compare256_rle.h new file mode 100644 index 000000000..0f3998d4a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/compare256_rle.h @@ -0,0 +1,134 @@ +/* compare256_rle.h -- 256 byte run-length encoding comparison + * Copyright (C) 2022 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "fallback_builtins.h" + +typedef uint32_t (*compare256_rle_func)(const uint8_t* src0, const uint8_t* src1); + +/* ALIGNED, byte comparison */ +static inline uint32_t compare256_rle_c(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + + do { + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + if (*src0 != *src1) + return len; + src1 += 1, len += 1; + } while (len < 256); + + return 256; +} + +#ifdef UNALIGNED_OK +/* 16-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_16(const uint8_t *src0, const uint8_t *src1) { + uint32_t len = 0; + uint16_t src0_cmp, src1_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + + do { + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + memcpy(&src1_cmp, src1, sizeof(src1_cmp)); + if (src0_cmp != src1_cmp) + return len + (*src0 == *src1); + src1 += 2, len += 2; + } while (len < 256); + + return 256; +} + +#ifdef HAVE_BUILTIN_CTZ +/* 32-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_32(const uint8_t *src0, const uint8_t *src1) { + uint32_t sv, len = 0; + uint16_t src0_cmp; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + sv = ((uint32_t)src0_cmp << 16) | src0_cmp; + + do { + uint32_t mv, diff; + + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint32_t match_byte = __builtin_ctz(diff) / 8; + return len + match_byte; + } + + src1 += 4, len += 4; + } while (len < 256); + + return 256; +} + +#endif + +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +/* 64-bit unaligned integer comparison */ +static inline uint32_t compare256_rle_unaligned_64(const uint8_t *src0, const uint8_t *src1) { + uint32_t src0_cmp32, len = 0; + uint16_t src0_cmp; + uint64_t sv; + + memcpy(&src0_cmp, src0, sizeof(src0_cmp)); + src0_cmp32 = ((uint32_t)src0_cmp << 16) | src0_cmp; + sv = ((uint64_t)src0_cmp32 << 32) | src0_cmp32; + + do { + uint64_t mv, diff; + + memcpy(&mv, src1, sizeof(mv)); + + diff = sv ^ mv; + if (diff) { + uint64_t match_byte = __builtin_ctzll(diff) / 8; + return len + (uint32_t)match_byte; + } + + src1 += 8, len += 8; + } while (len < 256); + + return 256; +} + +#endif + +#endif + diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/compress.c b/internal-complibs/zlib-ng-2.1.1-beta2/compress.c new file mode 100644 index 000000000..66118e4f4 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/compress.c @@ -0,0 +1,98 @@ +/* compress.c -- compress a memory buffer + * Copyright (C) 1995-2005, 2014, 2016 Jean-loup Gailly, Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil.h" + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_common.h" +#else +/* Returns the upper bound on compressed data length based on uncompressed data length, assuming default settings. + * Zero means that arch-specific deflation code behaves identically to the regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_COMPLEN(source_len) 0 +#endif + +/* =========================================================================== + Compresses the source buffer into the destination buffer. The level + parameter has the same meaning as in deflateInit. sourceLen is the byte + length of the source buffer. Upon entry, destLen is the total size of the + destination buffer, which must be at least 0.1% larger than sourceLen plus + 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. + + compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_BUF_ERROR if there was not enough room in the output buffer, + Z_STREAM_ERROR if the level parameter is invalid. +*/ +int Z_EXPORT PREFIX(compress2)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, + z_uintmax_t sourceLen, int level) { + PREFIX3(stream) stream; + int err; + const unsigned int max = (unsigned int)-1; + z_size_t left; + + left = *destLen; + *destLen = 0; + + stream.zalloc = NULL; + stream.zfree = NULL; + stream.opaque = NULL; + + err = PREFIX(deflateInit)(&stream, level); + if (err != Z_OK) + return err; + + stream.next_out = dest; + stream.avail_out = 0; + stream.next_in = (z_const unsigned char *)source; + stream.avail_in = 0; + + do { + if (stream.avail_out == 0) { + stream.avail_out = left > (unsigned long)max ? max : (unsigned int)left; + left -= stream.avail_out; + } + if (stream.avail_in == 0) { + stream.avail_in = sourceLen > (unsigned long)max ? max : (unsigned int)sourceLen; + sourceLen -= stream.avail_in; + } + err = PREFIX(deflate)(&stream, sourceLen ? Z_NO_FLUSH : Z_FINISH); + } while (err == Z_OK); + + *destLen = stream.total_out; + PREFIX(deflateEnd)(&stream); + return err == Z_STREAM_END ? Z_OK : err; +} + +/* =========================================================================== + */ +int Z_EXPORT PREFIX(compress)(unsigned char *dest, z_uintmax_t *destLen, const unsigned char *source, z_uintmax_t sourceLen) { + return PREFIX(compress2)(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); +} + +/* =========================================================================== + If the default memLevel or windowBits for deflateInit() is changed, then + this function needs to be updated. + */ +z_uintmax_t Z_EXPORT PREFIX(compressBound)(z_uintmax_t sourceLen) { + z_uintmax_t complen = DEFLATE_BOUND_COMPLEN(sourceLen); + + if (complen > 0) + /* Architecture-specific code provided an upper bound. */ + return complen + ZLIB_WRAPLEN; + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + ZLIB_WRAPLEN; /* zlib wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + ZLIB_WRAPLEN; +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/configure b/internal-complibs/zlib-ng-2.1.1-beta2/configure new file mode 100755 index 000000000..f84233e09 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/configure @@ -0,0 +1,2318 @@ +#!/usr/bin/env bash +# configure script for zlib. +# +# Normally configure builds both a static and a shared library. +# If you want to build just a static library, use: ./configure --static +# +# To impose specific compiler or flags or install directory, use for example: +# prefix=$HOME CC=cc CFLAGS="-O4" ./configure +# or for csh/tcsh users: +# (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure) + +# Incorrect settings of CC or CFLAGS may prevent creating a shared library. +# If you have problems, try without defining CC and CFLAGS before reporting +# an error. + +# start off configure.log +echo -------------------- >> configure.log +echo $0 $* >> configure.log +date >> configure.log + +SRCDIR=$(cd $(dirname $0); pwd) +BUILDDIR=$(pwd) + +# set command prefix for cross-compilation +if [ -n "${CHOST}" ]; then + # normalize the chost before parsing it + NORM_CHOST=$(sh "$SRCDIR"/tools/config.sub $CHOST) + uname="$(echo "${NORM_CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/')" + CROSS_PREFIX="${CHOST}-" + ARCH="$(echo "${NORM_CHOST}" | sed -e 's/-.*//')" +else + ARCH="$(uname -m)" +fi + +case "${ARCH}" in + x86_64) + case "${CFLAGS}" in + *-m32*) + ARCH=i686 + ;; + esac + ;; + i386 | i486 | i586 | i686) + case "${CFLAGS}" in + *-m64*) + ARCH=x86_64 + ;; + esac + ;; +esac + +# destination name for windows import library +IMPORTLIB= + +# establish commands for library building +if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then + AR=${AR-"${CROSS_PREFIX}ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +else + AR=${AR-"ar"} + test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log +fi +ARFLAGS=${ARFLAGS-"rc"} +if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then + RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"} + test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log +else + RANLIB=${RANLIB-"ranlib"} +fi + +# set defaults before processing command line options +LDCONFIG=${LDCONFIG-"ldconfig"} +DEFFILE= +RC= +RCFLAGS= +RCOBJS= +STRIP= +ARCHS= +prefix=${prefix-/usr/local} +exec_prefix=${exec_prefix-'${prefix}'} +bindir=${bindir-'${exec_prefix}/bin'} +libdir=${libdir-'${exec_prefix}/lib'} +sharedlibdir=${sharedlibdir-'${libdir}'} +includedir=${includedir-'${prefix}/include'} +mandir=${mandir-'${prefix}/share/man'} +shared_ext='.so' +shared=1 +gzfileops=1 +unalignedok=1 +compat=0 +cover=0 +build32=0 +build64=0 +buildvpclmulqdq=1 +buildacle=1 +buildaltivec=1 +buildpower8=1 +buildpower9=1 +buildneon=1 +builddfltccdeflate=0 +builddfltccinflate=0 +buildcrc32vx=1 +floatabi= +native=0 +forcesse2=0 +# For CPUs that can benefit from AVX512, it seems GCC generates suboptimal +# instruction scheduling unless you specify a reasonable -mtune= target +avx512flag="-mavx512f -mavx512dq -mavx512bw -mavx512vl" +avx512vnniflag="${avx512flag} -mavx512vnni" +avx2flag="-mavx2" +sse2flag="-msse2" +ssse3flag="-mssse3" +sse42flag="-msse4.2" +pclmulflag="-mpclmul" +vpclmulflag="-mvpclmulqdq -mavx512f" +xsaveflag="-mxsave" +acleflag= +neonflag= +noltoflag="-fno-lto" +vgfmaflag="-march=z13" +vmxflag="-maltivec" +symbol_prefix="" +without_optimizations=0 +without_new_strategies=0 +reducedmem=0 +gcc=0 +warn=0 +debug=0 +visibility=1 +old_cc="$CC" +old_cflags="$CFLAGS" +OBJC='$(OBJZ)' +PIC_OBJC='$(PIC_OBJZ)' +INSTALLTARGETS="install-shared install-static" +UNINSTALLTARGETS="uninstall-shared uninstall-static" + +TEST="teststatic" + +# leave this script, optionally in a bad way +leave() +{ + if test "$*" != "0"; then + echo "** $0 aborting." | tee -a configure.log + fi + rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version + echo -------------------- >> configure.log + echo >> configure.log + echo >> configure.log + exit $1 +} + +# process command line options +while test $# -ge 1 +do +case "$1" in + -h* | --help) + echo 'usage:' | tee -a configure.log + echo ' configure [--prefix=PREFIX] [--eprefix=EXPREFIX]' | tee -a configure.log + echo ' [--static] [--32] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log + echo ' [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log + echo ' [--sprefix=SYMBOL_PREFIX] Adds a prefix to all exported symbols' | tee -a configure.log + echo ' [--warn] Enables extra compiler warnings' | tee -a configure.log + echo ' [--debug] Enables extra debug prints during operation' | tee -a configure.log + echo ' [--zlib-compat] Compiles for zlib-compatible API instead of zlib-ng API' | tee -a configure.log + echo ' [--without-unaligned] Compiles without fast unaligned access' | tee -a configure.log + echo ' [--without-gzfileops] Compiles without the gzfile parts of the API enabled' | tee -a configure.log + echo ' [--without-optimizations] Compiles without support for optional instruction sets' | tee -a configure.log + echo ' [--without-new-strategies] Compiles without using new additional deflate strategies' | tee -a configure.log + echo ' [--without-acle] Compiles without ARM C Language Extensions' | tee -a configure.log + echo ' [--without-neon] Compiles without ARM Neon SIMD instruction set' | tee -a configure.log + echo ' [--without-altivec] Compiles without PPC AltiVec support' | tee -a configure.log + echo ' [--without-power8] Compiles without Power8 instruction set' | tee -a configure.log + echo ' [--with-dfltcc-deflate] Use DEFLATE CONVERSION CALL instruction for compression on IBM Z' | tee -a configure.log + echo ' [--with-dfltcc-inflate] Use DEFLATE CONVERSION CALL instruction for decompression on IBM Z' | tee -a configure.log + echo ' [--without-crc32-vx] Build without vectorized CRC32 on IBM Z' | tee -a configure.log + echo ' [--with-reduced-mem] Reduced memory usage for special cases (reduces performance)' | tee -a configure.log + echo ' [--force-sse2] Assume SSE2 instructions are always available (disabled by default on x86, enabled on x86_64)' | tee -a configure.log + echo ' [--native] Compiles with full instruction set supported on this host' | tee -a configure.log + exit 0 ;; + -p*=* | --prefix=*) prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -e*=* | --eprefix=*) exec_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -m*=* | --sprefix=*) symbol_prefix=$(echo $1 | sed 's/.*=//'); shift ;; + -l*=* | --libdir=*) libdir=$(echo $1 | sed 's/.*=//'); shift ;; + --sharedlibdir=*) sharedlibdir=$(echo $1 | sed 's/.*=//'); shift ;; + -i*=* | --includedir=*) includedir=$(echo $1 | sed 's/.*=//');shift ;; + -u*=* | --uname=*) uname=$(echo $1 | sed 's/.*=//');shift ;; + -p* | --prefix) prefix="$2"; shift; shift ;; + -e* | --eprefix) exec_prefix="$2"; shift; shift ;; + -m* | --sprefix) symbol_prefix="$2"; shift; shift ;; + -l* | --libdir) libdir="$2"; shift; shift ;; + -i* | --includedir) includedir="$2"; shift; shift ;; + -s* | --shared | --enable-shared) shared=1; shift ;; + -t | --static) shared=0; shift ;; + --zlib-compat) compat=1; shift ;; + --without-unaligned) unalignedok=0; shift ;; + --without-gzfileops) gzfileops=0; shift ;; + --cover) cover=1; shift ;; + -3* | --32) build32=1; shift ;; + -6* | --64) build64=1; shift ;; + --without-vpclmulqdq) buildvpclmulqdq=0; shift ;; + --without-acle) buildacle=0; shift ;; + --without-neon) buildneon=0; shift ;; + --without-altivec) buildaltivec=0 ; shift ;; + --without-power8) buildpower8=0 ; shift ;; + --without-power9) buildpower9=0 ; shift ;; + --with-dfltcc-deflate) builddfltccdeflate=1; shift ;; + --with-dfltcc-inflate) builddfltccinflate=1; shift ;; + --without-crc32-vx) buildcrc32vx=0; shift ;; + --with-reduced-mem) reducedmem=1; shift ;; + --force-sse2) forcesse2=1; shift ;; + -n | --native) native=1; shift ;; + -a*=* | --archs=*) ARCHS=$(echo $1 | sed 's/.*=//'); shift ;; + --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;; + --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;; + -noopt | --without-optimizations) without_optimizations=1; shift;; + -oldstrat | --without-new-strategies) without_new_strategies=1; shift;; + -w* | --warn) warn=1; shift ;; + -d* | --debug) debug=1; shift ;; + + *) + echo "unknown option: $1" | tee -a configure.log + echo "$0 --help for help" | tee -a configure.log + leave 1;; + esac +done + +# temporary file name +test=ztest$$ + +# put arguments in log, also put test file in log if used in arguments +show() +{ + case "$*" in + *$test.c*) + echo "=== $test.c ===" >> configure.log + cat $test.c >> configure.log + echo "===" >> configure.log;; + esac + echo $* >> configure.log +} + +# check for gcc vs. cc and set compile and link flags based on the system identified by uname +cat > $test.c <&1) in + *gcc*) gcc=1 ;; + *clang*) gcc=1 ;; +esac + +if test $native -eq 1; then + avx512flag="" + avx512vnniflag="" + avx2flag="" + sse2flag="" + ssse3flag="" + sse42flag="" + pclmulflag="" + vpclmulflag="" + xsaveflag="" + noltoflag="" +fi + +if test $build32 -eq 1; then + CFLAGS="${CFLAGS} -m32" + SFLAGS="${SFLAGS} -m32" + LDFLAGS="${LDFLAGS} -m32" +fi +if test $build64 -eq 1; then + CFLAGS="${CFLAGS} -m64" + SFLAGS="${SFLAGS} -m64" + LDFLAGS="${LDFLAGS} -m64" +fi + +# Set library name depending on zlib-compat option +if test $compat -eq 0; then + LIBNAME=libz-ng + LIBNAME2=zlib-ng + SUFFIX=-ng +else + LIBNAME=libz + LIBNAME2=zlib + SUFFIX="" +fi + +STATICLIB=${LIBNAME}.a +MAPNAME=${LIBNAME2}.map + +# extract zlib version numbers from zlib.h +if test $compat -eq 0; then + VER=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER3=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER2=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) + VER1=$(sed -n -e '/ZLIBNG_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib-ng.h.in) +else + VER=$(sed -n -e '/ZLIB_VERSION "/s/.*"\(.*\)".*/\1/p' < ${SRCDIR}/zlib.h.in) + VER3=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/p' < ${SRCDIR}/zlib.h.in) + VER2=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\.[0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) + VER1=$(sed -n -e '/ZLIB_VERSION "/s/.*"\([0-9]*\)\..*/\1/p' < ${SRCDIR}/zlib.h.in) +fi + +show $cc -c $test.c +if test "$gcc" -eq 1 && ($cc $CFLAGS -c $test.c) >> configure.log 2>&1; then + echo "$cc" | tee -a configure.log + CC="$cc" + CFLAGS="${CFLAGS} -std=c11" + + # Re-check ARCH if the compiler is a cross-compiler. + if $CC -print-multiarch 1> /dev/null 2>&1 && test -n "$($CC -print-multiarch)" 1> /dev/null 2>&1; then + CC_ARCH=$($CC $CFLAGS -print-multiarch | sed 's/-.*//g') + else + CC_ARCH=$($CC $CFLAGS -dumpmachine | sed 's/-.*//g') + fi + case $CC_ARCH in + i386 | i486 | i586 | i686) + # Honor user choice if gcc is multilib and 64-bit is requested + if test $build64 -eq 1; then + ARCH=x86_64 + else + ARCH=$CC_ARCH + fi ;; + x86_64) + # Honor user choice if gcc is multilib and 32-bit is requested + if test $build32 -ne 1; then + ARCH=$CC_ARCH + fi ;; + arm | armeb) + if test $native -eq 0; then + ARCH=arm + else + ARCH=native + fi + if test "${uname}" = "eabi"; then + # No ACLE support + uname=arm + if test $buildacle -eq 1; then + echo ACLE support not available + buildacle=0 + fi + fi + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH=armv8-a+crc + fi + fi ;; + armv8l) + if test $native -eq 0; then + ARCH=armv8-a + else + ARCH=native + fi ;; + aarch64 | aarch64_be | arm64) + if test "${uname}" = "elf"; then + uname=aarch64 + fi + if test $native -eq 0; then + ARCH=aarch64 + else + ARCH=native + fi ;; + powerpc | ppc) + ARCH=powerpc ;; + powerpc64 | ppc64) + ARCH=powerpc64 ;; + powerpc64le | ppc64le) + ARCH=powerpc64le ;; + esac + CFLAGS="-O2 ${CFLAGS}" + if test -n "${ARCHS}"; then + CFLAGS="${CFLAGS} ${ARCHS}" + LDFLAGS="${LDFLAGS} ${ARCHS}" + fi + CFLAGS="${CFLAGS} -Wall" + SFLAGS="${CFLAGS} -fPIC" + if test $native -eq 1; then + case $ARCH in + powerpc*) + NATIVE_FLAG="-mcpu=native" ;; + *) + NATIVE_FLAG="-march=native" ;; + esac + CFLAGS="${CFLAGS} ${NATIVE_FLAG}" + SFLAGS="${SFLAGS} ${NATIVE_FLAG}" + fi + if test "$warn" -eq 1; then + CFLAGS="${CFLAGS} -Wextra" + fi + if test $debug -eq 1; then + CFLAGS="${CFLAGS} -DZLIB_DEBUG" + SFLAGS="${SFLAGS} -DZLIB_DEBUG" + else + CFLAGS="${CFLAGS} -DNDEBUG" + SFLAGS="${SFLAGS} -DNDEBUG" + fi + if test -z "$uname"; then + uname=$((uname -s || echo unknown) 2>/dev/null) + fi + case "$uname" in + Linux* | linux* | GNU | GNU/* | solaris*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" ;; + *BSD | *bsd* | DragonFly) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1},--version-script,${SRCDIR}/${MAPNAME}" + LDCONFIG="ldconfig -m" ;; + CYGWIN* | Cygwin* | cygwin*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=cygz-ng$shared_ext + else + SHAREDLIB=cygz$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB},--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MSYS* | msys*) + visibility=0 + ARFLAGS="rcs" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + if test $compat -eq 0; then + SHAREDLIB=msys-z-ng$shared_ext + else + SHAREDLIB=msys-z$shared_ext + fi + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib,${IMPORTLIB}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + MINGW* | mingw*) + visibility=0 + ARFLAGS="rcs" + CFLAGS="${CFLAGS} -D_POSIX_C_SOURCE=200809L -D_GNU_SOURCE=1 -Wno-pedantic-ms-format" + SFLAGS="${CFLAGS}" + shared_ext='.dll' + sharedlibdir='${bindir}' + SHAREDLIB=${LIBNAME}-$VER1$shared_ext + SHAREDLIBM='' + SHAREDLIBV='' + SHAREDTARGET=$SHAREDLIB + IMPORTLIB="${LIBNAME}.dll.a" + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,--out-implib=${IMPORTLIB} -Wl,--version-script=${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="" + if test $gzfileops -eq 0; then + DEFFILE='win32/${LIBNAME2}.def' + fi + RC="${CROSS_PREFIX}windres" + RCFLAGS="-I ${BUILDDIR}" + if [ "$CC" == "mingw32-gcc" ]; then + case $ARCH in + i386 | i486 | i586 | i686) RCFLAGS="${RCFLAGS} -F pe-i386";; + esac; + fi + RCOBJS='zlibrc.o' + STRIP="${CROSS_PREFIX}strip" + EXE='.exe' ;; + QNX*) # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4 + # (alain.bonnefoy@icbt.com) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-h${LIBNAME}.so.${VER1}" ;; + HP-UX*) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + Darwin* | darwin*) + shared_ext='.dylib' + SHAREDLIB=${LIBNAME}$shared_ext + SHAREDLIBV=${LIBNAME}.$VER$shared_ext + SHAREDLIBM=${LIBNAME}.$VER1$shared_ext + SHAREDTARGET=$SHAREDLIBV + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3" + if libtool -V 2>&1 | grep Apple > /dev/null; then + AR="libtool" + else + AR="/usr/bin/libtool" + fi + ARFLAGS="-o" ;; + aarch64) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared -Wl,-soname,${LIBNAME}.so.${VER1} -Wl,--version-script,${SRCDIR}/${MAPNAME}" + LDSHAREDLIBC="-Wl,--start-group -lc -lrdimon -Wl,--end-group" ;; + *) + LDSHARED=${LDSHARED-"$cc"} + LDSHAREDFLAGS="-shared" ;; + esac +else + # find system name and corresponding cc options + CC=${CC-cc} + gcc=0 + echo "$CC" | tee -a configure.log + if test -z "$uname"; then + uname=$((uname -sr || echo unknown) 2>/dev/null) + fi + case "$uname" in + HP-UX*) SFLAGS=${CFLAGS-"-O +z"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"ld"} + LDSHAREDFLAGS="-b" + case $((uname -m || echo unknown) 2>/dev/null) in + ia64) + shared_ext='.so' + SHAREDLIB='${LIBNAME}.so' ;; + *) + shared_ext='.sl' + SHAREDLIB='${LIBNAME}.sl' ;; + esac ;; + AIX*) # Courtesy of dbakker@arrayasolutions.com + SFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + CFLAGS=${CFLAGS-"-O -qmaxmem=8192"} + LDSHARED=${LDSHARED-"xlc"} + LDSHAREDFLAGS="-G" ;; + # send working options for other systems to zlib@gzip.org + *) SFLAGS=${CFLAGS-"-O"} + CFLAGS=${CFLAGS-"-O"} + LDSHARED=${LDSHARED-"cc"} + LDSHAREDFLAGS="-shared" ;; + esac +fi + +# Simplify some later conditionals +case "$uname" in +Linux* | linux*) + LINUX=1 ;; +*) + LINUX=0 ;; +esac + +# destination names for shared library if not defined above +SHAREDLIB=${SHAREDLIB-"${LIBNAME}$shared_ext"} +SHAREDLIBV=${SHAREDLIBV-"${LIBNAME}$shared_ext.$VER"} +SHAREDLIBM=${SHAREDLIBM-"${LIBNAME}$shared_ext.$VER1"} +SHAREDTARGET=${SHAREDTARGET-"${LIBNAME}$shared_ext.$VER"} + +echo >> configure.log + +# define functions for testing compiler and library characteristics and logging the results + +cat > $test.c </dev/null; then + try() + { + show $* + test "$(\( $* \) 2>&1 | tee -a configure.log)" = "" + } + echo - using any output from compiler to indicate an error >> configure.log +else + try() + { + show $* + ( $* ) >> configure.log 2>&1 + ret=$? + if test $ret -ne 0; then + echo "(exit code $ret)" >> configure.log + fi + return $ret + } +fi + +cat > $test.c << EOF +int foo() { return 0; } +EOF +echo "Checking for obsessive-compulsive compiler options..." >> configure.log +if try $CC -c $CFLAGS $test.c; then + : +else + echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log + leave 1 +fi + +echo >> configure.log + +# see if shared library build supported +cat > $test.c <> configure.log + +# check for large file support, and if none, check for fseeko() +cat > $test.c < +off64_t dummy = 0; +EOF +if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then + CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1" + SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1" + echo "Checking for off64_t... Yes." | tee -a configure.log + echo "Checking for fseeko... Yes." | tee -a configure.log +else + echo "Checking for off64_t... No." | tee -a configure.log + echo >> configure.log + cat > $test.c < +int main() { + _off64_t dummy = 0; + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for _off64_t... Yes." | tee -a configure.log + else + echo "Checking for _off64_t... No." | tee -a configure.log + fi + echo >> configure.log + cat > $test.c < +int main(void) { + fseeko(NULL, 0, 0); + return 0; +} +EOF + if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for fseeko... Yes." | tee -a configure.log + else + CFLAGS="${CFLAGS} -DNO_FSEEKO" + SFLAGS="${SFLAGS} -DNO_FSEEKO" + echo "Checking for fseeko... No." | tee -a configure.log + fi +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = 0; + int ret = posix_memalign(&ptr, 64, 10); + if (ptr) + free(ptr); + return ret; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for posix_memalign... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_POSIX_MEMALIGN" + SFLAGS="${SFLAGS} -DHAVE_POSIX_MEMALIGN" +else + echo "Checking for posix_memalign... No." | tee -a configure.log +fi +echo >> configure.log + +cat > $test.c < +int main(void) { + void *ptr = aligned_alloc(64, 10); + if (ptr) + free(ptr); + return 0; +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for aligned_alloc... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_ALIGNED_ALLOC" + SFLAGS="${SFLAGS} -DHAVE_ALIGNED_ALLOC" +else + echo "Checking for aligned_alloc... No." | tee -a configure.log +fi +echo >> configure.log + +# check for strerror() for use by gz* functions +cat > $test.c < +#include +int main() { return strlen(strerror(errno)); } +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for strerror... Yes." | tee -a configure.log +else + CFLAGS="${CFLAGS} -DNO_STRERROR" + SFLAGS="${SFLAGS} -DNO_STRERROR" + echo "Checking for strerror... No." | tee -a configure.log +fi + +# check for getauxval() or elf_aux_info() for architecture feature detection at run-time +cat > $test.c < +int main() { +#ifdef __FreeBSD__ + int test; + return elf_aux_info(AT_PAGESZ, &test, sizeof(test)); +#else + return getauxval(0); +#endif +} +EOF +if try $CC $CFLAGS -o $test $test.c $LDSHAREDLIBC; then + echo "Checking for getauxval() or elf_aux_info() in sys/auxv.h... Yes." | tee -a configure.log + CFLAGS="${CFLAGS} -DHAVE_SYS_AUXV_H" + SFLAGS="${SFLAGS} -DHAVE_SYS_AUXV_H" +else + echo "Checking for getauxval() in sys/auxv.h... No." | tee -a configure.log +fi + +# We need to remove consigured files (zconf.h etc) from source directory if building outside of it +if [ "$SRCDIR" != "$BUILDDIR" ]; then + rm -f $SRCDIR/zconf${SUFFIX}.h + rm -f $SRCDIR/zlib${SUFFIX}.h + rm -f $SRCDIR/zlib_name_mangling${SUFFIX}.h +fi + +# Rename @ZLIB_SYMBOL_PREFIX@ to $symbol_prefix in gzread.c, zlib.h and zlib_name_mangling.h +sed < $SRCDIR/gzread.c.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > gzread.c +sed < $SRCDIR/zlib${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib${SUFFIX}.h +if [[ ! -z $symbol_prefix ]]; then + sed < $SRCDIR/zlib_name_mangling${SUFFIX}.h.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > zlib_name_mangling${SUFFIX}.h +else + # symbol_prefix is not set, copy the empty mangling header + cp -p $SRCDIR/zlib_name_mangling.h.empty zlib_name_mangling${SUFFIX}.h +fi + +# copy clean zconf.h for subsequent edits +cp -p $SRCDIR/zconf${SUFFIX}.h.in zconf${SUFFIX}.h + +echo >> configure.log + +# check for unistd.h and save result in zconf.h +cat > $test.c < +int main() { return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... Yes." | tee -a configure.log +else + sed < zconf${SUFFIX}.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be set to #if 1/ 0\1 was set to #if 0/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + echo "Checking for unistd.h... No." | tee -a configure.log +fi + +echo >> configure.log + +# check for ptrdiff_t and save result in zconf.h +echo -n "Checking for ptrdiff_t... " | tee -a configure.log +cat > $test.c < +int fun(ptrdiff_t *a) { (void)a; return 0; } +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Yes." | tee -a configure.log +else + echo "No." | tee -a configure.log + sed < zconf${SUFFIX}.h "/^#ifdef NEED_PTRDIFF_T.* may be/s/def NEED_PTRDIFF_T\(.*\) may be/ 1\1 was/" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + + echo -n "Checking for sizeof(void *)... " | tee -a configure.log + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int32_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int32_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int32_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + cat > $test.c < +#define COMPILE_TIME_ASSERT(pred) struct s { int x: (pred) ? 1 : -1; } +COMPILE_TIME_ASSERT(sizeof(int64_t) == sizeof(void *)); +EOF + if try $CC -c $CFLAGS $test.c; then + echo "sizeof(int64_t)." | tee -a configure.log + sed < zconf${SUFFIX}.h "s/^typedef PTRDIFF_TYPE ptrdiff_t;/typedef int64_t ptrdiff_t;/g" > zconf${SUFFIX}.temp.h + mv zconf${SUFFIX}.temp.h zconf${SUFFIX}.h + else + echo "unknown." | tee -a configure.log + exit 1 + fi + fi +fi + +# if --zlib-compat was requested +if test $compat -eq 1; then + gzfileops=1 + CFLAGS="${CFLAGS} -DZLIB_COMPAT" + SFLAGS="${SFLAGS} -DZLIB_COMPAT" + case "$uname" in + CYGWIN* | Cygwin* | cygwin* | MSYS* | msys* | MINGW* | mingw*) + DEFFILE="win32/zlibcompat.def" ;; + esac +fi + +if [[ ! -z $DEFFILE ]]; then + mkdir -p win32 + sed < $SRCDIR/$DEFFILE.in "s/@ZLIB_SYMBOL_PREFIX@/$symbol_prefix/g" > $DEFFILE +fi + +# if --gzfileops was requested +if test $gzfileops -eq 1; then + CFLAGS="${CFLAGS} -DWITH_GZFILEOP" + SFLAGS="${SFLAGS} -DWITH_GZFILEOP" + OBJC="${OBJC} \$(OBJG)" + PIC_OBJC="${PIC_OBJC} \$(PIC_OBJG)" +else + TESTOBJG="\$(OBJG)" + PIC_TESTOBJG="\$(OBJG)" +fi + +# set architecture alignment requirements +if test $unalignedok -eq 0; then + CFLAGS="${CFLAGS} -DNO_UNALIGNED" + SFLAGS="${SFLAGS} -DNO_UNALIGNED" + echo "Unaligned reads manually disabled." | tee -a configure.log +fi + +# enable reduced memory configuration +if test $reducedmem -eq 1; then + echo "Configuring for reduced memory environment." | tee -a configure.log + CFLAGS="${CFLAGS} -DHASH_SIZE=32768u -DGZBUFSIZE=8192" +fi + +# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X +if test $cover -eq 1; then + CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage" + LDFLAGS="${LDFLAGS} -fprofile-arcs -ftest-coverage" + if test -n "$GCC_CLASSIC"; then + CC=$GCC_CLASSIC + fi +fi + +echo >> configure.log + +# Check for ANSI C compliant compiler +cat > $test.c < +#include +#include +#include "zconf${SUFFIX}.h" +int main() { +#ifdef STDC + return 0; +#endif + return 1; +} +EOF +if try $CC -c $CFLAGS $test.c; then + echo "Checking for ANSI C compliant compiler... Yes." | tee -a configure.log + : +else + echo "Checking for ANSI C compliant compiler... No." | tee -a configure.log + echo "Error: ANSI C compatible compiler needed, cannot continue." | tee -a configure.log + leave 1 +fi + +# Check for -fno-semantic-interposition compiler support +echo "" > test.c + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-semantic-interposition... Yes." | tee -a configure.log + SFLAGS="$SFLAGS -fno-semantic-interposition" +else + echo "Checking for -fno-semantic-interposition... No." | tee -a configure.log +fi + +# Check for -fno-lto compiler support +if test $gcc -eq 1 -a $without_optimizations -eq 0 -a $native -eq 0; then + cat > $test.c <> configure.log 2>&1; then + echo "Checking for -fno-lto... Yes." | tee -a configure.log + else + echo "Checking for -fno-lto... No." | tee -a configure.log + noltoflag="" + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using hidden +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(hidden)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(hidden)) support... No." | tee -a configure.log + fi +fi + +# see if we can hide zlib internal symbols that are linked between separate source files using internal +if test "$gcc" -eq 1 && test "$visibility" -eq 1; then + echo >> configure.log + cat > $test.c <> configure.log + echo "Checking for attribute(visibility(internal)) support... Yes." | tee -a configure.log + else + echo >> configure.log + echo "Checking for attribute(visibility(internal)) support... No." | tee -a configure.log + fi +fi + +# Check for attribute(aligned) support in compiler +cat > $test.c << EOF +int main(void) { + __attribute__((aligned(8))) int test = 0; + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for attribute(aligned) ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_ATTRIBUTE_ALIGNED" + SFLAGS="$SFLAGS -DHAVE_ATTRIBUTE_ALIGNED" +else + echo "Checking for attribute(aligned) ... No." | tee -a configure.log +fi + +# Check for _Thread_local support in compiler +cat > $test.c << EOF +_Thread_local int test; +int main(void) { + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for _Thread_local ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_THREAD_LOCAL" + SFLAGS="$SFLAGS -DHAVE_THREAD_LOCAL" +else + echo "Checking for _Thread_local ... No." | tee -a configure.log +fi + +# Check for __builtin_ctz() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned int zero = 0; + long test = __builtin_ctz(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctz ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZ" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZ" +else + echo "Checking for __builtin_ctz ... No." | tee -a configure.log +fi + +# Check for __builtin_ctzll() support in compiler +cat > $test.c << EOF +int main(void) { + unsigned long long zero = 0; + long test = __builtin_ctzll(zero); + (void)test; + return 0; +} +EOF +if try ${CC} ${CFLAGS} $test.c $LDSHAREDLIBC; then + echo "Checking for __builtin_ctzll ... Yes." | tee -a configure.log + CFLAGS="$CFLAGS -DHAVE_BUILTIN_CTZLL" + SFLAGS="$SFLAGS -DHAVE_BUILTIN_CTZLL" +else + echo "Checking for __builtin_ctzll ... No." | tee -a configure.log +fi + +check_avx2_intrinsics() { + # Check whether compiler supports AVX2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m256i x = _mm256_set1_epi16(2); + const __m256i y = _mm256_set1_epi16(1); + x = _mm256_subs_epu16(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx2flag} $test.c; then + echo "Checking for AVX2 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX2_INTRIN=1 + else + echo "Checking for AVX2 intrinsics ... No." | tee -a configure.log + HAVE_AVX2_INTRIN=0 + fi +} + +check_avx512_intrinsics() { + # Check whether compiler supports AVX512 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi32(0x1020304, 0x5060708, 0x90a0b0c, 0xd0e0f10, + 0x11121314, 0x15161718, 0x191a1b1c, 0x1d1e1f20, + 0x21222324, 0x25262728, 0x292a2b2c, 0x2d2e2f30, + 0x31323334, 0x35363738, 0x393a3b3c, 0x3d3e3f40); + x = _mm512_sub_epi8(x, y); + (void)x; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for AVX512 intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512_INTRIN=1 + else + echo "Checking for AVX512 intrinsics ... No." | tee -a configure.log + HAVE_AVX512_INTRIN=0 + fi +} + +check_mtune_skylake_avx512_compiler_flag() { + # Check whether -mtune=skylake-avx512 works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=skylake-avx512 $test.c; then + MTUNE_SKYLAKE_AVX512_AVAILABLE=1 + echo "Check whether -mtune=skylake-avx512 works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=skylake-avx512 works ... No." | tee -a configure.log + MTUNE_SKYLAKE_AVX512_AVAILABLE=0 + fi +} + +check_mtune_cascadelake_compiler_flag() { + # Check whether -mtune=cascadelake works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mtune=cascadelake $test.c; then + MTUNE_CASCADELAKE_AVAILABLE=1 + echo "Check whether -mtune=cascadelake works ... Yes." | tee -a configure.log + else + echo "Check whether -mtune=cascadelake works ... No." | tee -a configure.log + MTUNE_CASCADELAKE_AVAILABLE=0 + check_mtune_skylake_avx512_compiler_flag + fi +} + +check_avx512vnni_intrinsics() { + # Check whether compiler supports AVX512-VNNI intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m512i x = _mm512_set1_epi8(2); + const __m512i y = _mm512_set_epi8(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, 64); + __m512i z = _mm512_setzero_epi32(); + z = _mm512_dpbusd_epi32(z, x, y); + (void)z; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512vnniflag} $test.c; then + echo "Checking for AVX512VNNI intrinsics ... Yes." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=1 + else + echo "Checking for AVX512VNNI intrinsics ... No." | tee -a configure.log + HAVE_AVX512VNNI_INTRIN=0 + fi +} + +check_mask_intrinsics() { + # Check whether compiler supports AVX512 k-mask intrinsics + cat > $test.c << EOF +#include +int main(void) { + __mmask16 a = 0xFF; + a = _knot_mask16(a); + (void)a; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${avx512flag} $test.c; then + echo "Checking for AVX512 k-mask intrinsics ... Yes." | tee -a configure.log + HAVE_MASK_INTRIN=1 + else + echo "Checking for AVX512 k-mask intrinsics ... No." | tee -a configure.log + HAVE_MASK_INTRIN=0 + fi +} + +check_acle_compiler_flag() { + # Check whether -march=armv8-a+crc works correctly + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -march=armv8-a+crc $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc works ... Yes." | tee -a configure.log + else + echo "Check whether -march=armv8-a+crc works ... No." | tee -a configure.log + if try $CC -c $CFLAGS -march=armv8-a+crc+simd $test.c; then + ACLE_AVAILABLE=1 + echo "Check whether -march=armv8-a+crc+simd works ... Yes." | tee -a configure.log + if test "$ARCH" = "armv8-a+crc"; then + ARCH=armv8-a+crc+simd + fi + else + ACLE_AVAILABLE=0 + echo "Check whether -march=armv8-a+crc+simd works ... No." | tee -a configure.log + fi + fi +} + +check_neon_compiler_flag() { + # Check whether -mfpu=neon is available on ARM processors. + cat > $test.c << EOF +#ifdef _M_ARM64 + # include + #else + # include +#endif +int main() { return 0; } +EOF + if try $CC -c $CFLAGS -mfpu=neon $test.c; then + MFPU_NEON_AVAILABLE=1 + echo "Check whether -mfpu=neon is available ... Yes." | tee -a configure.log + else + MFPU_NEON_AVAILABLE=0 + echo "Check whether -mfpu=neon is available ... No." | tee -a configure.log + fi +} + +check_neon_ld4_intrinsics() { + if test $buildneon -eq 1 && test $native -eq 0; then + if test "$CC_ARCH" = "aarch64" || test "$CC_ARCH" = "aarch64_be" || test "$CC_ARCH" = "arm64"; then + neonflag="-march=armv8-a+simd" + elif test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + fi + cat > $test.c << EOF +#ifdef _M_ARM64 +# include +#else +# include +#endif +int main(void) { + int stack_var[16]; + int32x4x4_t v = vld1q_s32_x4(stack_var); + (void)v; + return 0; +} +EOF + if try $CC -c $CFLAGS $neonflag $test.c; then + NEON_HAS_LD4=1 + echo "check whether compiler supports 4 wide register loads ... Yes." | tee -a configure.log + else + NEON_HAS_LD4=0 + echo "check whether compiler supports 4 wide register loads ... No." | tee -a configure.log + fi +} + +check_pclmulqdq_intrinsics() { + # Check whether compiler supports PCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m128i a = _mm_setzero_si128(); + __m128i b = _mm_setzero_si128(); + __m128i c = _mm_clmulepi64_si128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${pclmulflag} $test.c; then + echo "Checking for PCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=1 + else + echo "Checking for PCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_PCLMULQDQ_INTRIN=0 + fi +} + +check_vpclmulqdq_intrinsics() { + # Check whether compiler supports VPCLMULQDQ intrinsics + cat > $test.c << EOF +#include +#include +int main(void) { + __m512i a = _mm512_setzero_si512(); + __m512i b = _mm512_setzero_si512(); + __m512i c = _mm512_clmulepi64_epi128(a, b, 0x10); + (void)c; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${vpclmulflag} $test.c; then + echo "Checking for VPCLMULQDQ intrinsics ... Yes." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=1 + else + echo "Checking for VPCLMULQDQ intrinsics ... No." | tee -a configure.log + HAVE_VPCLMULQDQ_INTRIN=0 + fi +} + +check_xsave_intrinsics() { + # Check whether compiler supports XSAVE intrinsics + cat > $test.c << EOF +#ifdef _WIN32 +# include +#else +# include +#endif +int main(void) { + return _xgetbv(0); +} +EOF + if try ${CC} ${CFLAGS} ${xsaveflag} $test.c; then + echo "Checking for XSAVE intrinsics ... Yes." | tee -a configure.log + HAVE_XSAVE_INTRIN=1 + else + echo "Checking for XSAVE intrinsics ... No." | tee -a configure.log + HAVE_XSAVE_INTRIN=0 + fi +} + +check_ppc_intrinsics() { + cat > $test.c << EOF +#include +int main(void) +{ + vector int a = vec_splats(0); + vector int b = vec_splats(0); + a = vec_add(a, b); + return 0; +} +EOF + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec $test.c; then + echo "Checking for AltiVec intrinsics ... Yes." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=1 + else + echo "Checking for AltiVec intrinsics ... No." | tee -a configure.log + HAVE_ALTIVEC_INTRIN=0 + fi + if test $buildaltivec -eq 1 && try ${CC} ${CFLAGS} -maltivec -mno-vsx $test.c; then + echo "Checking if -mno-vsx is supported ... Yes." | tee -a configure.log + vmxflag="$vmxflag -mno-vsx" + else + echo "Checking if -mno-vsx is supported ... No." | tee -a configure.log + fi + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE_HAS_ALTIVEC); +#else + return (getauxval(AT_HWCAP) & PPC_FEATURE_HAS_ALTIVEC); +#endif +} +EOF + if try $CC -c $CFLAGS -maltivec $test.c; then + HAVE_VMX=1 + echo "Check whether VMX instructions are available ... Yes." | tee -a configure.log + else + HAVE_VMX=0 + echo "Check whether VMX instructions are available ... No." | tee -a configure.log + fi +} + +check_power8_intrinsics() { + # Check whether features needed by POWER8 optimisations are available + cat > $test.c << EOF +#ifdef __FreeBSD__ +#include +#endif +#include +int main() { +#ifdef __FreeBSD__ + unsigned long hwcap; + elf_aux_info(AT_HWCAP2, &hwcap, sizeof(hwcap)); + return (hwcap & PPC_FEATURE2_ARCH_2_07); +#else + return (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07); +#endif +} +EOF + if test $buildpower8 -eq 1 && try $CC -c $CFLAGS -mcpu=power8 $test.c; then + HAVE_POWER8_INTRIN=1 + echo "Check whether POWER8 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER8_INTRIN=0 + echo "Check whether POWER8 instructions are available ... No." | tee -a configure.log + fi +} + +check_power9_intrinsics() { + # Check whether features needed by POWER9 optimisations are available + cat > $test.c << EOF +int main() { return 0; } +EOF + if test $buildpower9 -eq 1 && try $CC -c $CFLAGS -mcpu=power9 $test.c; then + HAVE_POWER9_INTRIN=1 + echo "Check whether POWER9 instructions are available ... Yes." | tee -a configure.log + else + HAVE_POWER9_INTRIN=0 + echo "Check whether POWER9 instructions are available ... No." | tee -a configure.log + fi +} + +check_sse2_intrinsics() { + # Check whether compiler supports SSE2 intrinsics + cat > $test.c << EOF +#include +int main(void) { + __m128i zero = _mm_setzero_si128(); + (void)zero; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse2flag} $test.c; then + echo "Checking for SSE2 intrinsics ... Yes." | tee -a configure.log + HAVE_SSE2_INTRIN=1 + else + echo "Checking for SSE2 intrinsics ... No." | tee -a configure.log + HAVE_SSE2_INTRIN=0 + fi +} + +check_sse42_intrinsics() { + # Check whether compiler supports SSE4.2 CRC inline asm + cat > $test.c << EOF +int main(void) { + unsigned val = 0, h = 0; + __asm__ __volatile__ ( "crc32 %1,%0" : "+r" (h) : "r" (val) ); + return (int) h; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC inline assembly ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=1 + else + echo "Checking for SSE4.2 CRC inline assembly ... No." | tee -a configure.log + HAVE_SSE42CRC_INLINE_ASM=0 + fi + + # Check whether compiler supports SSE4.2 CRC intrinsics + cat > $test.c << EOF +int main(void) { + unsigned crc = 0; + char c = 'c'; + crc = __builtin_ia32_crc32qi(crc, c); + (void)crc; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${sse42flag} $test.c; then + echo "Checking for SSE4.2 CRC intrinsics ... Yes." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=1 + else + echo "Checking for SSE4.2 CRC intrinsics ... No." | tee -a configure.log + HAVE_SSE42CRC_INTRIN=0 + fi +} + +check_ssse3_intrinsics() { + # Check whether compiler supports SSSE3 intrinsics + cat > $test.c << EOF +#include +int main(void) +{ + __m128i u, v, w; + u = _mm_set1_epi32(1); + v = _mm_set1_epi32(2); + w = _mm_hadd_epi32(u, v); + (void)w; + return 0; +} +EOF + if try ${CC} ${CFLAGS} ${ssse3flag} $test.c; then + echo "Checking for SSSE3 intrinsics ... Yes." | tee -a configure.log + HAVE_SSSE3_INTRIN=1 + else + echo "Checking for SSSE3 intrinsics ... No." | tee -a configure.log + HAVE_SSSE3_INTRIN=0 + fi +} + +check_vgfma_intrinsics() { + # Check whether "VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE" intrinsic is available + echo -n "Checking for -mzarch... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -mzarch; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -mzarch" + else + echo No. | tee -a configure.log + fi + echo -n "Checking for -fzvector... " | tee -a configure.log + if try $CC -x c -c /dev/null -o /dev/null -fzvector; then + echo Yes. | tee -a configure.log + vgfmaflag="${vgfmaflag} -fzvector" + else + echo No. | tee -a configure.log + fi + cat > $test.c << EOF +#include +int main(void) { + unsigned long long a __attribute__((vector_size(16))) = { 0 }; + unsigned long long b __attribute__((vector_size(16))) = { 0 }; + unsigned char c __attribute__((vector_size(16))) = { 0 }; + c = vec_gfmsum_accum_128(a, b, c); + return c[0]; +} +EOF + echo -n "Checking for VGFMA support... " | tee -a configure.log + if try $CC -c $CFLAGS $vgfmaflag $test.c; then + HAVE_VGFMA_INTRIN=1 + echo "Yes." | tee -a configure.log + else + HAVE_VGFMA_INTRIN=0 + echo "No." | tee -a configure.log + fi +} + +case "${ARCH}" in + i386 | i486 | i586 | i686 | x86_64) + # Enable deflate_medium at level 1 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_QUICK_STRATEGY" + SFLAGS="${SFLAGS} -DNO_QUICK_STRATEGY" + fi + # Enable deflate_medium at level 4-6 + if test $without_new_strategies -eq 1; then + CFLAGS="${CFLAGS} -DNO_MEDIUM_STRATEGY" + SFLAGS="${SFLAGS} -DNO_MEDIUM_STRATEGY" + fi + ;; +esac + +ARCHDIR='arch/generic' +ARCH_STATIC_OBJS='' +ARCH_SHARED_OBJS='' + +# Set ARCH specific FLAGS +case "${ARCH}" in + # x86/amd64 specific optimizations + i386 | i486 | i586 | i686 |x86_64) + ARCHDIR=arch/x86 + + # Enable arch-specific optimizations + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DX86_FEATURES" + SFLAGS="${SFLAGS} -DX86_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} x86_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} x86_features.lo" + + check_avx2_intrinsics + + if test ${HAVE_AVX2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX2" + SFLAGS="${SFLAGS} -DX86_AVX2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} slide_hash_avx2.o chunkset_avx2.o compare256_avx2.o adler32_avx2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} slide_hash_avx2.lo chunkset_avx2.lo compare256_avx2.lo adler32_avx2.lo" + fi + + check_avx512_intrinsics + + if test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512" + SFLAGS="${SFLAGS} -DX86_AVX512" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512.lo" + + check_mask_intrinsics + + if test ${HAVE_MASK_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_MASK_INTRIN" + SFLAGS="${SFLAGS} -DX86_MASK_INTRIN" + fi + fi + + check_mtune_cascadelake_compiler_flag + + if test ${MTUNE_CASCADELAKE_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=cascadelake" + avx512vnniflag="${avx512vnniflag} -mtune=cascadelake" + else + if test ${MTUNE_SKYLAKE_AVX512_AVAILABLE} -eq 1; then + avx512flag="${avx512flag} -mtune=skylake-avx512" + avx512vnniflag="${avx512vnniflag} -mtune=skylake-avx512" + fi + fi + + check_avx512vnni_intrinsics + + if test ${HAVE_AVX512VNNI_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_AVX512VNNI" + SFLAGS="${SFLAGS} -DX86_AVX512VNNI" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_avx512_vnni.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_avx512_vnni.lo" + fi + + check_sse42_intrinsics + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1 || test ${HAVE_SSE42CRC_INLINE_ASM} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42" + SFLAGS="${SFLAGS} -DX86_SSE42" + + if test ${HAVE_SSE42CRC_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE42_CRC_INTRIN" + SFLAGS="${SFLAGS} -DX86_SSE42_CRC_INTRIN" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_sse42.o insert_string_sse42.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_sse42.lo insert_string_sse42.lo" + fi + + check_sse2_intrinsics + + if test ${HAVE_SSE2_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSE2" + SFLAGS="${SFLAGS} -DX86_SSE2" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} chunkset_sse2.o compare256_sse2.o slide_hash_sse2.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} chunkset_sse2.lo compare256_sse2.lo slide_hash_sse2.lo" + + if test $forcesse2 -eq 1; then + CFLAGS="${CFLAGS} -DX86_NOCHECK_SSE2" + SFLAGS="${SFLAGS} -DX86_NOCHECK_SSE2" + fi + fi + + check_ssse3_intrinsics + + if test ${HAVE_SSSE3_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_SSSE3" + SFLAGS="${SFLAGS} -DX86_SSSE3" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_ssse3.o chunkset_ssse3.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_ssse3.lo chunkset_ssse3.lo" + fi + + check_pclmulqdq_intrinsics + + if test ${HAVE_PCLMULQDQ_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_PCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_PCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_pclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_pclmulqdq.lo" + + if test $buildvpclmulqdq -eq 1; then + check_vpclmulqdq_intrinsics + + if test ${HAVE_VPCLMULQDQ_INTRIN} -eq 1 && test ${HAVE_AVX512_INTRIN} -eq 1; then + CFLAGS="${CFLAGS} -DX86_VPCLMULQDQ_CRC" + SFLAGS="${SFLAGS} -DX86_VPCLMULQDQ_CRC" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_vpclmulqdq.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_vpclmulqdq.lo" + fi + fi + fi + + check_xsave_intrinsics + + if test ${HAVE_XSAVE_INTRIN} -eq 0; then + xsaveflag="" + fi + fi + ;; + + # ARM specific optimizations + arm*) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=arm + ARCHDIR=arch/arm + + if test $without_optimizations -eq 0; then + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + cat > $test.c < +#include +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + else + echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + echo "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + fi + fi + + cat > $test.c << EOF +int main() { return 0; } +EOF + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=softfp && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=softfp" + else + if try $CC -w -c $SFLAGS $test.c -mfloat-abi=hard && + try $LDSHARED $LDSHAREDFLAGS $LDFLAGS -o $test$shared_ext $test.o $LDSHAREDLIBC; then + floatabi="-mfloat-abi=hard" + fi + fi + + if [ -z $floatabi ]; then + echo "ARM floating point arch not auto-detected" | tee -a configure.log + else + echo "ARM floating point arch: ${floatabi}" | tee -a configure.log + + CFLAGS="${CFLAGS} ${floatabi}" + SFLAGS="${SFLAGS} ${floatabi}" + fi + + if test $without_optimizations -eq 0; then + check_acle_compiler_flag + check_neon_compiler_flag + check_neon_ld4_intrinsics + fi + + case "${ARCH}" in + armv[345]*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + armv6l | armv6hl) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + echo NEON support not available + fi + fi + ;; + arm | armv7*) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1; then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a | armv8-a+simd) + if test $without_optimizations -eq 0; then + if test $buildacle -eq 1; then + echo ACLE support not available + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + armv8-a+crc | armv8-a+crc+simd | armv8.[1234]-a | armv8.[1234]-a+simd) + acleflag="-march=${ARCH}" + + if test $without_optimizations -eq 0; then + if test $ACLE_AVAILABLE -eq 1; then + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + + if test $MFPU_NEON_AVAILABLE -eq 1;then + neonflag="-mfpu=neon" + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + ;; + esac + + ;; + # 64-bit ARM specific optimizations + aarch64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=aarch64 + ARCHDIR=arch/arm + + if test $native -eq 0; then + ARCH="armv8-a" + else + ARCH="native" + fi + + if test $without_optimizations -eq 0; then + check_neon_ld4_intrinsics + + CFLAGS="${CFLAGS} -DARM_FEATURES" + SFLAGS="${SFLAGS} -DARM_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} arm_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} arm_features.lo" + + if test $LINUX -eq 1; then + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" + else + echo "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi + fi + + if test $NEON_HAS_LD4 -eq 1; then + CFLAGS="${CFLAGS} -DARM_NEON_HASLD4" + SFLAGS="${SFLAGS} -DARM_NEON_HASLD4" + fi + + if test $buildacle -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+crc" + fi + CFLAGS="${CFLAGS} -DARM_ACLE" + SFLAGS="${SFLAGS} -DARM_ACLE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_acle.o insert_string_acle.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_acle.lo insert_string_acle.lo" + fi + + if test $buildneon -eq 1; then + if test $native -eq 0; then + ARCH="${ARCH}+simd" + fi + CFLAGS="${CFLAGS} -DARM_NEON" + SFLAGS="${SFLAGS} -DARM_NEON" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_neon.o chunkset_neon.o compare256_neon.o slide_hash_neon.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_neon.lo chunkset_neon.lo compare256_neon.lo slide_hash_neon.lo" + fi + fi + + neonflag="-march=${ARCH}" + acleflag="-march=${ARCH}" + ;; + powerpc*) + case "${ARCH}" in + powerpc) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc + ;; + powerpc64) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64 + ;; + powerpc64le) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=ppc64le + ;; + esac + + ARCHDIR=arch/power + + if test $without_optimizations -eq 0; then + + check_ppc_intrinsics + check_power8_intrinsics + check_power9_intrinsics + + if test $HAVE_VMX -eq 1; then + CFLAGS="${CFLAGS} -DPPC_FEATURES" + SFLAGS="${SFLAGS} -DPPC_FEATURES" + fi + if test $HAVE_VMX -eq 1 -o $HAVE_POWER8_INTRIN -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} power_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} power_features.lo" + fi + if test $HAVE_VMX -eq 1 -a $HAVE_ALTIVEC_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPPC_VMX" + SFLAGS="${SFLAGS} -DPPC_VMX" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_vmx.o slide_hash_vmx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_vmx.lo slide_hash_vmx.lo" + fi + if test $HAVE_POWER8_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER8_VSX -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} adler32_power8.o chunkset_power8.o slide_hash_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} adler32_power8.lo chunkset_power8.lo slide_hash_power8.lo" + case "${ARCH}" in + powerpc64*) + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32_power8.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32_power8.lo" + CFLAGS="${CFLAGS} -DPOWER8_VSX_CRC32" + SFLAGS="${SFLAGS} -DPOWER8_VSX_CRC32" + ;; + esac + fi + if test $HAVE_POWER9_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DPOWER9 -DPOWER_FEATURES" + SFLAGS="${SFLAGS} -DPOWER9 -DPOWER_FEATURES" + + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} compare256_power9.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} compare256_power9.lo" + fi + fi + ;; + s390x) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=s390x + ARCHDIR=arch/s390 + + if test $without_optimizations -eq 0; then + if test $buildcrc32vx -eq 1; then + CFLAGS="${CFLAGS} -DS390_FEATURES" + SFLAGS="${SFLAGS} -DS390_FEATURES" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} s390_features.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} s390_features.lo" + fi + + if test $builddfltccdeflate -eq 1 -o $builddfltccinflate -eq 1; then + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_common.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_common.lo" + fi + + if test $builddfltccdeflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_DEFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_DEFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_deflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_deflate.lo" + ARCH="${ARCH}+dfltcc-deflate" + fi + + if test $builddfltccinflate -eq 1; then + CFLAGS="${CFLAGS} -DS390_DFLTCC_INFLATE" + SFLAGS="${SFLAGS} -DS390_DFLTCC_INFLATE" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} dfltcc_inflate.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} dfltcc_inflate.lo" + ARCH="${ARCH}+dfltcc-inflate" + fi + + if test $buildcrc32vx -eq 1; then + check_vgfma_intrinsics + if test $HAVE_VGFMA_INTRIN -eq 1; then + CFLAGS="${CFLAGS} -DS390_CRC32_VX" + SFLAGS="${SFLAGS} -DS390_CRC32_VX" + ARCH_STATIC_OBJS="${ARCH_STATIC_OBJS} crc32-vx.o" + ARCH_SHARED_OBJS="${ARCH_SHARED_OBJS} crc32-vx.lo" + ARCH="${ARCH}+crc32-vx" + fi + fi + fi + ;; + *) + [ ! -z $CROSS_PREFIX ] && QEMU_ARCH=$ARCH + ;; +esac + +echo "ARCH: ${ARCH}" +echo "Using arch directory: ${ARCHDIR}" +echo "Architecture-specific static object files:${ARCH_STATIC_OBJS}" +echo "Architecture-specific shared object files:${ARCH_SHARED_OBJS}" + +# show the results in the log +echo >> configure.log +echo ALL = $ALL >> configure.log +echo AR = $AR >> configure.log +echo ARFLAGS = $ARFLAGS >> configure.log +echo CC = $CC >> configure.log +echo CFLAGS = $CFLAGS >> configure.log +echo EXE = $EXE >> configure.log +echo LDCONFIG = $LDCONFIG >> configure.log +echo LDFLAGS = $LDFLAGS >> configure.log +echo LDSHARED = $LDSHARED >> configure.log +echo LDSHAREDFLAGS = $LDSHAREDFLAGS >> configure.log +echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log +echo DEFFILE = $DEFFILE >> configure.log +echo RC = $RC >> configure.log +echo RCFLAGS = $RCFLAGS >> configure.log +echo RCOBJS = $RCOBJS >> configure.log +echo STRIP = $STRIP >> configure.log +echo OBJC = $OBJC >> configure.log +echo TESTOBJG = $TESTOBJG >> configure.log +echo PIC_TESTOBJG = $PIC_TESTOBJG >> configure.log +echo PIC_OBJC = $PIC_OBJC >> configure.log +echo RANLIB = $RANLIB >> configure.log +echo SFLAGS = $SFLAGS >> configure.log +echo SHAREDLIB = $SHAREDLIB >> configure.log +echo SHAREDLIBM = $SHAREDLIBM >> configure.log +echo SHAREDLIBV = $SHAREDLIBV >> configure.log +echo SHAREDTARGET = $SHAREDTARGET >> configure.log +echo IMPORTLIB = $IMPORTLIB >> configure.log +echo INSTALLTARGETS = $INSTALLTARGETS >> configure.log +echo UNINSTALLTARGETS = $UNINSTALLTARGETS >> configure.log +echo SRCDIR = $SRCDIR >> configure.log +echo BUILDDIR = $BUILDDIR >> configure.log +echo STATICLIB = $STATICLIB >> configure.log +echo TEST = $TEST >> configure.log +echo VER = $VER >> configure.log +echo exec_prefix = $exec_prefix >> configure.log +echo includedir = $includedir >> configure.log +echo bindir = $bindir >> configure.log +echo libdir = $libdir >> configure.log +echo mandir = $mandir >> configure.log +echo prefix = $prefix >> configure.log +echo symbol_prefix = $symbol_prefix >> configure.log +echo sharedlibdir = $sharedlibdir >> configure.log +echo uname = $uname >> configure.log +echo sse2flag = $sse2flag >> configure.log +echo ssse3flag = $ssse3flag >> configure.log +echo sse42flag = $sse42flag >> configure.log +echo pclmulflag = $pclmulflag >> configure.log +echo vpclmulflag = $vpclmulflag >> configure.log +echo xsaveflag = $xsaveflag >> configure.log +echo acleflag = $acleflag >> configure.log +echo neonflag = $neonflag >> configure.log +echo ARCHDIR = ${ARCHDIR} >> configure.log +echo ARCH_STATIC_OBJS = ${ARCH_STATIC_OBJS} >> configure.log +echo ARCH_SHARED_OBJS = ${ARCH_SHARED_OBJS} >> configure.log + +# Handle sed incompatibilities when using -i +replace_in_file() { + if [ "$OS" = 'Darwin' ]; then + sed -i '.tmp' -e "$1" "$2" + else + sed -i'.tmp' -e "$1" "$2" + fi +} + +# update Makefile with the configure results + +INCLUDES="-I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then INCLUDES="-I$BUILDDIR ${INCLUDES}"; fi + +sed < $SRCDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^LIBNAME1 *=/s#=.*#=$LIBNAME# +/^LIBNAME2 *=/s#=.*#=$LIBNAME2# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^SHAREDTARGET *=/s#=.*#=$SHAREDTARGET# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^VER *=/s#=.*#=$VER# +/^VER1 *=/s#=.*#=$VER1# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^LDCONFIG *=/s#=.*#=$LDCONFIG# +/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC# +/^DEFFILE *=/s#=.*#=$DEFFILE# +/^RC *=/s#=.*#=$RC# +/^RCFLAGS *=/s#=.*#=$RCFLAGS# +/^RCOBJS *=/s#=.*#=$RCOBJS# +/^STRIP *=/s#=.*#=$STRIP# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#= $prefix# +/^exec_prefix *=/s#=.*#= $exec_prefix# +/^bindir *=/s#=.*#= $bindir# +/^symbol_prefix *=/s#=.*#= $symbol_prefix# +/^libdir *=/s#=.*#= $libdir# +/^sharedlibdir *=/s#=.*#= $sharedlibdir# +/^includedir *=/s#=.*#= $includedir# +/^mandir *=/s#=.*#= $mandir# +/^SRCDIR *=/s#=.*#=$SRCDIR# +/^INCLUDES *=/s#=.*#=$INCLUDES# +/^OBJC *=/s#=.*#= $OBJC# +/^TESTOBJG *=/s#=.*#= $TESTOBJG# +/^PIC_TESTOBJG *=/s#=.*#= $PIC_TESTOBJG# +/^PIC_OBJC *=/s#=.*#= $PIC_OBJC# +/^all: */s#:.*#: $ALL# +/^install-libs: */s#:.*#: $INSTALLTARGETS# +/^uninstall-libs: */s#:.*#: $UNINSTALLTARGETS# +/^ARCHDIR *=/s#=.*#=$ARCHDIR# +/^ARCH_STATIC_OBJS *=/s#=.*#=$ARCH_STATIC_OBJS# +/^ARCH_SHARED_OBJS *=/s#=.*#=$ARCH_SHARED_OBJS# +" > Makefile + +# Append header files dependences. +for file in $SRCDIR/*.c $SRCDIR/test/*.c $SRCDIR/test/fuzz/*.c $SRCDIR/$ARCHDIR/*.c $SRCDIR/tools/*.c; do + short_name=$(echo $file | sed -e "s#$SRCDIR/##g") + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$ARCHDIR/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + + if grep -q "^$obj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + + # In case this is one of the ARCHDIR files, append a dependence line + # that will force the `$(MAKE) -C $(ARCHDIR)` generic rule. Without this + # we would only execute the copy rule from ARCHDIR to SRCDIR. + if test -e $SRCDIR/$ARCHDIR/$(basename $file); then + echo "$ARCHDIR/$obj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi + fi + + if grep -q "^$lobj:" Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> Makefile + fi +done + +# Generate Makefile in arch dir +mkdir -p $ARCHDIR + +ARCHINCLUDES="-I$SRCDIR/$ARCHDIR -I$SRCDIR" +if [ "$SRCDIR" != "$BUILDDIR" ]; then ARCHINCLUDES="-I$BUILDDIR ${ARCHINCLUDES}"; fi + +sed < $SRCDIR/$ARCHDIR/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^SFLAGS *=/s#=.*#=$SFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^INCLUDES *=/s#=.*#=$ARCHINCLUDES# +/^SUFFIX *=/s#=.*#=$SUFFIX# +/^SRCDIR *=/s#=.*#=$SRCDIR/$ARCHDIR# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^BUILDDIR *=/s#=.*#=$BUILDDIR# +/^AVX2FLAG *=/s#=.*#=$avx2flag# +/^AVX512FLAG *=/s#=.*#=$avx512flag# +/^AVX512VNNIFLAG *=/s#=.*#=$avx512vnniflag# +/^SSE2FLAG *=/s#=.*#=$sse2flag# +/^SSSE3FLAG *=/s#=.*#=$ssse3flag# +/^SSE42FLAG *=/s#=.*#=$sse42flag# +/^PCLMULFLAG *=/s#=.*#=$pclmulflag# +/^VPCLMULFLAG *=/s#=.*#=$vpclmulflag# +/^XSAVEFLAG *=/s#=.*#=$xsaveflag# +/^ACLEFLAG *=/s#=.*#=$acleflag# +/^NEONFLAG *=/s#=.*#=$neonflag# +/^NOLTOFLAG *=/s#=.*#=$noltoflag# +/^VGFMAFLAG *=/s#=.*#=$vgfmaflag# +/^PPCFLAGS *=/s#=.*#=$vmxflag# +" > $ARCHDIR/Makefile + +# Append header files dependences. +for file in $SRCDIR/$ARCHDIR/*.c; do + incs=$(grep -h include $file | sed -n 's/# *\include *"\(.*\.h\)".*/\1/p' | sort | uniq) + includes=$(for i in $incs; do + # Check that the include file exists in the current dir, + # otherwise it may be one of the system include header. + if test -e $SRCDIR/$i; then + echo -n " \$(SRCTOP)/$i" + fi + # We also need to check whether the include file is in the ARCHDIR. + if test -e $SRCDIR/$ARCHDIR/$i; then + echo -n " \$(SRCDIR)/$i" + fi + done) + obj=$(basename $(echo $file | sed -e 's/\.c/\.o/g' -e 's#^\./##g')) + lobj=$(basename $(echo $file | sed -e 's/\.c/\.lo/g' -e 's#^\./##g')) + short_name=$(basename $file) + if grep -q "^$obj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$obj:.*#$obj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$obj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi + + if grep -q "^$lobj:" $ARCHDIR/Makefile; then + # Replace the existing line with a line with all dependences. + $(replace_in_file "s#$lobj:.*#$lobj: \$(SRCDIR)/$short_name $includes#g" $ARCHDIR/Makefile) + else + # Append at the end of Makefile a new line with the header dependences. + echo "$lobj: \$(SRCDIR)/$short_name $includes" >> $ARCHDIR/Makefile + fi +done + +# Emscripten does not support large amounts of data via stdin/out +# https://github.com/emscripten-core/emscripten/issues/16755#issuecomment-1102732849 +if test "$CHOST" != "wasm32"; then + TEST="${TEST} ghtests" +fi + +# Determine emulator to use when running tests +if test -z "$EMU_RUN" && test $QEMU_ARCH; then + EMU_RUN="qemu-$QEMU_ARCH -L /usr/${CHOST}/" +fi +if test -n "$EMU_RUN"; then + echo "Using cross-compile emulator: $EMU_RUN" +fi + +# Generate Makefile in test dir +mkdir -p test +sed < $SRCDIR/test/Makefile.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^EXE *=/s#=.*#=$EXE# +/^alltests: */s#:.*#: $TEST# +/^SRCDIR *=/s#=.*#=$SRCDIR/test# +/^SRCTOP *=/s#=.*#=$SRCDIR# +/^EMU_RUN *=/s#=.*#=$EMU_RUN# +/^LIBNAME *=/s#=.*#=$LIBNAME# +" > test/Makefile + +# create zlib.pc with the configure results +sed < $SRCDIR/zlib.pc.in " +/^CC *=/s#=.*#=$CC# +/^CFLAGS *=/s#=.*#=$CFLAGS# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +/^LDSHARED *=/s#=.*#=$LDSHARED# +/^LDSHAREDFLAGS *=/s#=.*#=$LDSHAREDFLAGS# +/^STATICLIB *=/s#=.*#=$STATICLIB# +/^SHAREDLIB *=/s#=.*#=$SHAREDLIB# +/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV# +/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM# +/^IMPORTLIB *=/s#=.*#=$IMPORTLIB# +/^AR *=/s#=.*#=$AR# +/^ARFLAGS *=/s#=.*#=$ARFLAGS# +/^RANLIB *=/s#=.*#=$RANLIB# +/^EXE *=/s#=.*#=$EXE# +/^prefix *=/s#=.*#=$prefix# +/^exec_prefix *=/s#=.*#=$exec_prefix# +/^bindir *=/s#=.*#=$bindir# +/^symbol_prefix *=/s#=.*#=$symbol_prefix# +/^libdir *=/s#=.*#=$libdir# +/^sharedlibdir *=/s#=.*#=$sharedlibdir# +/^includedir *=/s#=.*#=$includedir# +/^mandir *=/s#=.*#=$mandir# +/^LDFLAGS *=/s#=.*#=$LDFLAGS# +" | sed -e " +s/\@VERSION\@/$VER/g; +s/\@SUFFIX\@/$SUFFIX/g; +" > ${LIBNAME2}.pc + +# done +leave 0 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.c b/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.c new file mode 100644 index 000000000..3585172e5 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.c @@ -0,0 +1,23 @@ +/* cpu_features.c -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "cpu_features.h" +#include + +Z_INTERNAL void cpu_check_features(struct cpu_features *features) { + memset(features, 0, sizeof(struct cpu_features)); +#if defined(X86_FEATURES) + x86_check_features(&features->x86); +#elif defined(ARM_FEATURES) + arm_check_features(&features->arm); +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + power_check_features(&features->power); +#elif defined(S390_FEATURES) + s390_check_features(&features->s390); +#elif defined(RISCV_FEATURES) + riscv_check_features(&features->riscv); +#endif +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.h b/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.h new file mode 100644 index 000000000..647d027f6 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/cpu_features.h @@ -0,0 +1,274 @@ +/* cpu_features.h -- CPU architecture feature check + * Copyright (C) 2017 Hans Kristian Rosbach + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#ifndef CPU_FEATURES_H_ +#define CPU_FEATURES_H_ + +#include "adler32_fold.h" +#include "crc32_fold.h" + +#if defined(X86_FEATURES) +# include "arch/x86/x86_features.h" +# include "fallback_builtins.h" +#elif defined(ARM_FEATURES) +# include "arch/arm/arm_features.h" +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) +# include "arch/power/power_features.h" +#elif defined(S390_FEATURES) +# include "arch/s390/s390_features.h" +#elif defined(RISCV_FEATURES) +# include "arch/riscv/riscv_features.h" +#endif + +struct cpu_features { +#if defined(X86_FEATURES) + struct x86_cpu_features x86; +#elif defined(ARM_FEATURES) + struct arm_cpu_features arm; +#elif defined(PPC_FEATURES) || defined(POWER_FEATURES) + struct power_cpu_features power; +#elif defined(S390_FEATURES) + struct s390_cpu_features s390; +#elif defined(RISCV_FEATURES) + struct riscv_cpu_features riscv; +#else + char empty; +#endif +}; + +extern void cpu_check_features(struct cpu_features *features); + +/* adler32 */ +typedef uint32_t (*adler32_func)(uint32_t adler, const uint8_t *buf, size_t len); + +extern uint32_t adler32_c(uint32_t adler, const uint8_t *buf, size_t len); +#ifdef ARM_NEON +extern uint32_t adler32_neon(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef PPC_VMX +extern uint32_t adler32_vmx(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_SSSE3 +extern uint32_t adler32_ssse3(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_avx2(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_avx512(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_avx512_vnni(uint32_t adler, const uint8_t *buf, size_t len); +#endif +#ifdef POWER8_VSX +extern uint32_t adler32_power8(uint32_t adler, const uint8_t *buf, size_t len); +#endif + +/* adler32 folding */ +#ifdef X86_SSE42 +extern uint32_t adler32_fold_copy_sse42(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX2 +extern uint32_t adler32_fold_copy_avx2(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512 +extern uint32_t adler32_fold_copy_avx512(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif +#ifdef X86_AVX512VNNI +extern uint32_t adler32_fold_copy_avx512_vnni(uint32_t adler, uint8_t *dst, const uint8_t *src, size_t len); +#endif + +/* CRC32 folding */ +#ifdef X86_PCLMULQDQ_CRC +extern uint32_t crc32_fold_pclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_pclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_pclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_pclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_pclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif +#if defined(X86_PCLMULQDQ_CRC) && defined(X86_VPCLMULQDQ_CRC) +extern uint32_t crc32_fold_vpclmulqdq_reset(crc32_fold *crc); +extern void crc32_fold_vpclmulqdq_copy(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +extern void crc32_fold_vpclmulqdq(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +extern uint32_t crc32_fold_vpclmulqdq_final(crc32_fold *crc); +extern uint32_t crc32_vpclmulqdq(uint32_t crc32, const uint8_t *buf, size_t len); +#endif + +/* memory chunking */ +extern uint32_t chunksize_c(void); +extern uint8_t* chunkmemset_safe_c(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#ifdef X86_SSE2 +extern uint32_t chunksize_sse2(void); +extern uint8_t* chunkmemset_safe_sse2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_SSSE3 +extern uint8_t* chunkmemset_safe_ssse3(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef X86_AVX2 +extern uint32_t chunksize_avx2(void); +extern uint8_t* chunkmemset_safe_avx2(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef ARM_NEON +extern uint32_t chunksize_neon(void); +extern uint8_t* chunkmemset_safe_neon(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif +#ifdef POWER8_VSX +extern uint32_t chunksize_power8(void); +extern uint8_t* chunkmemset_safe_power8(uint8_t *out, unsigned dist, unsigned len, unsigned left); +#endif + +#ifdef ZLIB_COMPAT +typedef struct z_stream_s z_stream; +#else +typedef struct zng_stream_s zng_stream; +#endif + +/* inflate fast loop */ +extern void inflate_fast_c(PREFIX3(stream) *strm, uint32_t start); +#ifdef X86_SSE2 +extern void inflate_fast_sse2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_SSSE3 +extern void inflate_fast_ssse3(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef X86_AVX2 +extern void inflate_fast_avx2(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef ARM_NEON +extern void inflate_fast_neon(PREFIX3(stream) *strm, uint32_t start); +#endif +#ifdef POWER8_VSX +extern void inflate_fast_power8(PREFIX3(stream) *strm, uint32_t start); +#endif + +/* CRC32 */ +typedef uint32_t (*crc32_func)(uint32_t crc32, const uint8_t *buf, size_t len); + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); +#ifdef ARM_ACLE +extern uint32_t crc32_acle(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(POWER8_VSX) +extern uint32_t crc32_power8(uint32_t crc, const uint8_t *buf, size_t len); +#elif defined(S390_CRC32_VX) +extern uint32_t crc32_s390_vx(uint32_t crc, const uint8_t *buf, size_t len); +#endif + +/* compare256 */ +typedef uint32_t (*compare256_func)(const uint8_t *src0, const uint8_t *src1); + +extern uint32_t compare256_c(const uint8_t *src0, const uint8_t *src1); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t compare256_unaligned_16(const uint8_t *src0, const uint8_t *src1); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t compare256_unaligned_32(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_unaligned_64(const uint8_t *src0, const uint8_t *src1); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_sse2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t compare256_avx2(const uint8_t *src0, const uint8_t *src1); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t compare256_neon(const uint8_t *src0, const uint8_t *src1); +#endif +#ifdef POWER9 +extern uint32_t compare256_power9(const uint8_t *src0, const uint8_t *src1); +#endif + +#ifdef DEFLATE_H_ +/* insert_string */ +extern void insert_string_c(deflate_state *const s, const uint32_t str, uint32_t count); +#ifdef X86_SSE42 +extern void insert_string_sse42(deflate_state *const s, const uint32_t str, uint32_t count); +#elif defined(ARM_ACLE) +extern void insert_string_acle(deflate_state *const s, const uint32_t str, uint32_t count); +#endif + +/* longest_match */ +extern uint32_t longest_match_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_unaligned_16(deflate_state *const s, Pos cur_match); +#ifdef HAVE_BUILTIN_CTZ +extern uint32_t longest_match_unaligned_32(deflate_state *const s, Pos cur_match); +#endif +#if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_power9(deflate_state *const s, Pos cur_match); +#endif + +/* longest_match_slow */ +extern uint32_t longest_match_slow_c(deflate_state *const s, Pos cur_match); +#if defined(UNALIGNED_OK) && BYTE_ORDER == LITTLE_ENDIAN +extern uint32_t longest_match_slow_unaligned_16(deflate_state *const s, Pos cur_match); +extern uint32_t longest_match_slow_unaligned_32(deflate_state *const s, Pos cur_match); +#ifdef UNALIGNED64_OK +extern uint32_t longest_match_slow_unaligned_64(deflate_state *const s, Pos cur_match); +#endif +#endif +#if defined(X86_SSE2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_sse2(deflate_state *const s, Pos cur_match); +#endif +#if defined(X86_AVX2) && defined(HAVE_BUILTIN_CTZ) +extern uint32_t longest_match_slow_avx2(deflate_state *const s, Pos cur_match); +#endif +#if defined(ARM_NEON) && defined(HAVE_BUILTIN_CTZLL) +extern uint32_t longest_match_slow_neon(deflate_state *const s, Pos cur_match); +#endif +#ifdef POWER9 +extern uint32_t longest_match_slow_power9(deflate_state *const s, Pos cur_match); +#endif + +/* quick_insert_string */ +extern Pos quick_insert_string_c(deflate_state *const s, const uint32_t str); +#ifdef X86_SSE42 +extern Pos quick_insert_string_sse42(deflate_state *const s, const uint32_t str); +#elif defined(ARM_ACLE) +extern Pos quick_insert_string_acle(deflate_state *const s, const uint32_t str); +#endif + +/* slide_hash */ +typedef void (*slide_hash_func)(deflate_state *s); + +#ifdef X86_SSE2 +extern void slide_hash_sse2(deflate_state *s); +#elif defined(ARM_NEON) +extern void slide_hash_neon(deflate_state *s); +#endif +#if defined(PPC_VMX) +extern void slide_hash_vmx(deflate_state *s); +#endif +#if defined(POWER8_VSX) +extern void slide_hash_power8(deflate_state *s); +#endif +#ifdef X86_AVX2 +extern void slide_hash_avx2(deflate_state *s); +#endif + +/* update_hash */ +extern uint32_t update_hash_c(deflate_state *const s, uint32_t h, uint32_t val); +#ifdef X86_SSE42 +extern uint32_t update_hash_sse42(deflate_state *const s, uint32_t h, uint32_t val); +#elif defined(ARM_ACLE) +extern uint32_t update_hash_acle(deflate_state *const s, uint32_t h, uint32_t val); +#endif +#endif + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid.c b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid.c new file mode 100644 index 000000000..96754b53d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid.c @@ -0,0 +1,267 @@ +/* crc32_braid.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "functable.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" + +/* ========================================================================= */ + +const uint32_t * Z_EXPORT PREFIX(get_crc_table)(void) { + return (const uint32_t *)crc_table; +} + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_z)(unsigned long crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return (unsigned long)functable.crc32((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32_z)(uint32_t crc, const unsigned char *buf, size_t len) { + if (buf == NULL) return 0; + + return functable.crc32(crc, buf, len); +} +#endif + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32)(unsigned long crc, const unsigned char *buf, unsigned int len) { + return (unsigned long)PREFIX(crc32_z)((uint32_t)crc, buf, len); +} +#else +uint32_t Z_EXPORT PREFIX(crc32)(uint32_t crc, const unsigned char *buf, uint32_t len) { + return PREFIX(crc32_z)(crc, buf, len); +} +#endif + +/* ========================================================================= */ + +/* + A CRC of a message is computed on N braids of words in the message, where + each word consists of W bytes (4 or 8). If N is 3, for example, then three + running sparse CRCs are calculated respectively on each braid, at these + indices in the array of words: 0, 3, 6, ..., 1, 4, 7, ..., and 2, 5, 8, ... + This is done starting at a word boundary, and continues until as many blocks + of N * W bytes as are available have been processed. The results are combined + into a single CRC at the end. For this code, N must be in the range 1..6 and + W must be 4 or 8. The upper limit on N can be increased if desired by adding + more #if blocks, extending the patterns apparent in the code. In addition, + crc32 tables would need to be regenerated, if the maximum N value is increased. + + N and W are chosen empirically by benchmarking the execution time on a given + processor. The choices for N and W below were based on testing on Intel Kaby + Lake i7, AMD Ryzen 7, ARM Cortex-A57, Sparc64-VII, PowerPC POWER9, and MIPS64 + Octeon II processors. The Intel, AMD, and ARM processors were all fastest + with N=5, W=8. The Sparc, PowerPC, and MIPS64 were all fastest at N=5, W=4. + They were all tested with either gcc or clang, all using the -O3 optimization + level. Your mileage may vary. +*/ + +/* ========================================================================= */ + +#if BYTE_ORDER == LITTLE_ENDIAN +# define ZSWAPWORD(word) (word) +# define BRAID_TABLE crc_braid_table +#elif BYTE_ORDER == BIG_ENDIAN +# if W == 8 +# define ZSWAPWORD(word) ZSWAP64(word) +# elif W == 4 +# define ZSWAPWORD(word) ZSWAP32(word) +# endif +# define BRAID_TABLE crc_braid_big_table +#else +# error "No endian defined" +#endif +#define DO1 c = crc_table[(c ^ *buf++) & 0xff] ^ (c >> 8) +#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 + +/* ========================================================================= */ +#ifdef W +/* + Return the CRC of the W bytes in the word_t data, taking the + least-significant byte of the word as the first byte of data, without any pre + or post conditioning. This is used to combine the CRCs of each braid. + */ +#if BYTE_ORDER == LITTLE_ENDIAN +static uint32_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data >> 8) ^ crc_table[data & 0xff]; + return (uint32_t)data; +} +#elif BYTE_ORDER == BIG_ENDIAN +static z_word_t crc_word(z_word_t data) { + int k; + for (k = 0; k < W; k++) + data = (data << 8) ^ + crc_big_table[(data >> ((W - 1) << 3)) & 0xff]; + return data; +} +#endif /* BYTE_ORDER */ + +#endif /* W */ + +/* ========================================================================= */ +Z_INTERNAL uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len) { + Z_REGISTER uint32_t c; + + /* Pre-condition the CRC */ + c = (~crc) & 0xffffffff; + +#ifdef W + /* If provided enough bytes, do a braided CRC calculation. */ + if (len >= N * W + W - 1) { + size_t blks; + z_word_t const *words; + int k; + + /* Compute the CRC up to a z_word_t boundary. */ + while (len && ((uintptr_t)buf & (W - 1)) != 0) { + len--; + DO1; + } + + /* Compute the CRC on as many N z_word_t blocks as are available. */ + blks = len / (N * W); + len -= blks * N * W; + words = (z_word_t const *)buf; + + z_word_t crc0, word0, comb; +#if N > 1 + z_word_t crc1, word1; +#if N > 2 + z_word_t crc2, word2; +#if N > 3 + z_word_t crc3, word3; +#if N > 4 + z_word_t crc4, word4; +#if N > 5 + z_word_t crc5, word5; +#endif +#endif +#endif +#endif +#endif + /* Initialize the CRC for each braid. */ + crc0 = ZSWAPWORD(c); +#if N > 1 + crc1 = 0; +#if N > 2 + crc2 = 0; +#if N > 3 + crc3 = 0; +#if N > 4 + crc4 = 0; +#if N > 5 + crc5 = 0; +#endif +#endif +#endif +#endif +#endif + /* Process the first blks-1 blocks, computing the CRCs on each braid independently. */ + while (--blks) { + /* Load the word for each braid into registers. */ + word0 = crc0 ^ words[0]; +#if N > 1 + word1 = crc1 ^ words[1]; +#if N > 2 + word2 = crc2 ^ words[2]; +#if N > 3 + word3 = crc3 ^ words[3]; +#if N > 4 + word4 = crc4 ^ words[4]; +#if N > 5 + word5 = crc5 ^ words[5]; +#endif +#endif +#endif +#endif +#endif + words += N; + + /* Compute and update the CRC for each word. The loop should get unrolled. */ + crc0 = BRAID_TABLE[0][word0 & 0xff]; +#if N > 1 + crc1 = BRAID_TABLE[0][word1 & 0xff]; +#if N > 2 + crc2 = BRAID_TABLE[0][word2 & 0xff]; +#if N > 3 + crc3 = BRAID_TABLE[0][word3 & 0xff]; +#if N > 4 + crc4 = BRAID_TABLE[0][word4 & 0xff]; +#if N > 5 + crc5 = BRAID_TABLE[0][word5 & 0xff]; +#endif +#endif +#endif +#endif +#endif + for (k = 1; k < W; k++) { + crc0 ^= BRAID_TABLE[k][(word0 >> (k << 3)) & 0xff]; +#if N > 1 + crc1 ^= BRAID_TABLE[k][(word1 >> (k << 3)) & 0xff]; +#if N > 2 + crc2 ^= BRAID_TABLE[k][(word2 >> (k << 3)) & 0xff]; +#if N > 3 + crc3 ^= BRAID_TABLE[k][(word3 >> (k << 3)) & 0xff]; +#if N > 4 + crc4 ^= BRAID_TABLE[k][(word4 >> (k << 3)) & 0xff]; +#if N > 5 + crc5 ^= BRAID_TABLE[k][(word5 >> (k << 3)) & 0xff]; +#endif +#endif +#endif +#endif +#endif + } + } + + /* Process the last block, combining the CRCs of the N braids at the same time. */ + comb = crc_word(crc0 ^ words[0]); +#if N > 1 + comb = crc_word(crc1 ^ words[1] ^ comb); +#if N > 2 + comb = crc_word(crc2 ^ words[2] ^ comb); +#if N > 3 + comb = crc_word(crc3 ^ words[3] ^ comb); +#if N > 4 + comb = crc_word(crc4 ^ words[4] ^ comb); +#if N > 5 + comb = crc_word(crc5 ^ words[5] ^ comb); +#endif +#endif +#endif +#endif +#endif + words += N; + c = ZSWAPWORD(comb); + + /* Update the pointer to the remaining bytes to process. */ + buf = (const unsigned char *)words; + } + +#endif /* W */ + + /* Complete the computation of the CRC on any remaining bytes. */ + while (len >= 8) { + len -= 8; + DO8; + } + while (len) { + len--; + DO1; + } + + /* Return the CRC, post-conditioned. */ + return c ^ 0xffffffff; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb.c b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb.c new file mode 100644 index 000000000..75fb47425 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb.c @@ -0,0 +1,57 @@ +/* crc32_braid_comb.c -- compute the CRC-32 of a data stream + * Copyright (C) 1995-2022 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + * This interleaved implementation of a CRC makes use of pipelined multiple + * arithmetic-logic units, commonly found in modern CPU cores. It is due to + * Kadatch and Jenkins (2010). See doc/crc-doc.1.0.pdf in this distribution. + */ + +#include "zbuild.h" +#include "zutil.h" +#include "crc32_braid_p.h" +#include "crc32_braid_tbl.h" +#include "crc32_braid_comb_p.h" + +/* ========================================================================= */ +static uint32_t crc32_combine_(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return multmodp(x2nmodp(len2, 3), crc1) ^ crc2; +} +static uint32_t crc32_combine_gen_(z_off64_t len2) { + return x2nmodp(len2, 3); +} +static uint32_t crc32_combine_op_(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return multmodp(op, crc1) ^ crc2; +} + +/* ========================================================================= */ + +#ifdef ZLIB_COMPAT +unsigned long Z_EXPORT PREFIX(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine)(unsigned long crc1, unsigned long crc2, z_off64_t len2) { + return (unsigned long)crc32_combine_((uint32_t)crc1, (uint32_t)crc2, len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_gen)(z_off_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX4(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +unsigned long Z_EXPORT PREFIX(crc32_combine_op)(unsigned long crc1, unsigned long crc2, const unsigned long op) { + return (unsigned long)crc32_combine_op_((uint32_t)crc1, (uint32_t)crc2, (uint32_t)op); +} +#else +uint32_t Z_EXPORT PREFIX4(crc32_combine)(uint32_t crc1, uint32_t crc2, z_off64_t len2) { + return crc32_combine_(crc1, crc2, len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_gen)(z_off64_t len2) { + return crc32_combine_gen_(len2); +} +uint32_t Z_EXPORT PREFIX(crc32_combine_op)(uint32_t crc1, uint32_t crc2, const uint32_t op) { + return crc32_combine_op_(crc1, crc2, op); +} +#endif + +/* ========================================================================= */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb_p.h new file mode 100644 index 000000000..a269e7f5b --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_comb_p.h @@ -0,0 +1,42 @@ +#ifndef CRC32_BRAID_COMB_P_H_ +#define CRC32_BRAID_COMB_P_H_ + +/* + Return a(x) multiplied by b(x) modulo p(x), where p(x) is the CRC polynomial, + reflected. For speed, this requires that a not be zero. + */ +static uint32_t multmodp(uint32_t a, uint32_t b) { + uint32_t m, p; + + m = (uint32_t)1 << 31; + p = 0; + for (;;) { + if (a & m) { + p ^= b; + if ((a & (m - 1)) == 0) + break; + } + m >>= 1; + b = b & 1 ? (b >> 1) ^ POLY : b >> 1; + } + return p; +} + +/* + Return x^(n * 2^k) modulo p(x). Requires that x2n_table[] has been + initialized. + */ +static uint32_t x2nmodp(z_off64_t n, unsigned k) { + uint32_t p; + + p = (uint32_t)1 << 31; /* x^0 == 1 */ + while (n) { + if (n & 1) + p = multmodp(x2n_table[k & 31], p); + n >>= 1; + k++; + } + return p; +} + +#endif /* CRC32_BRAID_COMB_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_p.h new file mode 100644 index 000000000..1d8a07068 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_p.h @@ -0,0 +1,50 @@ +#ifndef CRC32_BRAID_P_H_ +#define CRC32_BRAID_P_H_ + +#include "zbuild.h" +#include "zendian.h" + +/* Define N */ +#ifdef Z_TESTN +# define N Z_TESTN +#else +# define N 5 +#endif +#if N < 1 || N > 6 +# error N must be in 1..6 +#endif + +/* + Define W and the associated z_word_t type. If W is not defined, then a + braided calculation is not used, and the associated tables and code are not + compiled. + */ +#ifdef Z_TESTW +# if Z_TESTW-1 != -1 +# define W Z_TESTW +# endif +#else +# ifndef W +# if defined(__x86_64__) || defined(__aarch64__) || defined(__powerpc64__) +# define W 8 +# else +# define W 4 +# endif +# endif +#endif +#ifdef W +# if W == 8 + typedef uint64_t z_word_t; +# else +# undef W +# define W 4 + typedef uint32_t z_word_t; +# endif +#endif + +/* CRC polynomial. */ +#define POLY 0xedb88320 /* p(x) reflected, with x^32 implied */ + +extern uint32_t PREFIX(crc32_braid)(uint32_t crc, const uint8_t *buf, size_t len); + +#endif /* CRC32_BRAID_P_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_tbl.h b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_tbl.h new file mode 100644 index 000000000..84d79a69e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_braid_tbl.h @@ -0,0 +1,9446 @@ +#ifndef CRC32_BRAID_TBL_H_ +#define CRC32_BRAID_TBL_H_ + +/* crc32_braid_tbl.h -- tables for braided CRC calculation + * Generated automatically by makecrct.c + */ + +static const uint32_t crc_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}; + +#ifdef W + +#if W == 8 + +static const z_word_t crc_big_table[] = { + 0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}; + +#else /* W == 4 */ + +static const z_word_t crc_big_table[] = { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}; + +#endif + +#endif /* W */ + +#if N == 1 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}, + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x9630077700000000, 0x2c610eee00000000, + 0xba51099900000000, 0x19c46d0700000000, 0x8ff46a7000000000, + 0x35a563e900000000, 0xa395649e00000000, 0x3288db0e00000000, + 0xa4b8dc7900000000, 0x1ee9d5e000000000, 0x88d9d29700000000, + 0x2b4cb60900000000, 0xbd7cb17e00000000, 0x072db8e700000000, + 0x911dbf9000000000, 0x6410b71d00000000, 0xf220b06a00000000, + 0x4871b9f300000000, 0xde41be8400000000, 0x7dd4da1a00000000, + 0xebe4dd6d00000000, 0x51b5d4f400000000, 0xc785d38300000000, + 0x56986c1300000000, 0xc0a86b6400000000, 0x7af962fd00000000, + 0xecc9658a00000000, 0x4f5c011400000000, 0xd96c066300000000, + 0x633d0ffa00000000, 0xf50d088d00000000, 0xc8206e3b00000000, + 0x5e10694c00000000, 0xe44160d500000000, 0x727167a200000000, + 0xd1e4033c00000000, 0x47d4044b00000000, 0xfd850dd200000000, + 0x6bb50aa500000000, 0xfaa8b53500000000, 0x6c98b24200000000, + 0xd6c9bbdb00000000, 0x40f9bcac00000000, 0xe36cd83200000000, + 0x755cdf4500000000, 0xcf0dd6dc00000000, 0x593dd1ab00000000, + 0xac30d92600000000, 0x3a00de5100000000, 0x8051d7c800000000, + 0x1661d0bf00000000, 0xb5f4b42100000000, 0x23c4b35600000000, + 0x9995bacf00000000, 0x0fa5bdb800000000, 0x9eb8022800000000, + 0x0888055f00000000, 0xb2d90cc600000000, 0x24e90bb100000000, + 0x877c6f2f00000000, 0x114c685800000000, 0xab1d61c100000000, + 0x3d2d66b600000000, 0x9041dc7600000000, 0x0671db0100000000, + 0xbc20d29800000000, 0x2a10d5ef00000000, 0x8985b17100000000, + 0x1fb5b60600000000, 0xa5e4bf9f00000000, 0x33d4b8e800000000, + 0xa2c9077800000000, 0x34f9000f00000000, 0x8ea8099600000000, + 0x18980ee100000000, 0xbb0d6a7f00000000, 0x2d3d6d0800000000, + 0x976c649100000000, 0x015c63e600000000, 0xf4516b6b00000000, + 0x62616c1c00000000, 0xd830658500000000, 0x4e0062f200000000, + 0xed95066c00000000, 0x7ba5011b00000000, 0xc1f4088200000000, + 0x57c40ff500000000, 0xc6d9b06500000000, 0x50e9b71200000000, + 0xeab8be8b00000000, 0x7c88b9fc00000000, 0xdf1ddd6200000000, + 0x492dda1500000000, 0xf37cd38c00000000, 0x654cd4fb00000000, + 0x5861b24d00000000, 0xce51b53a00000000, 0x7400bca300000000, + 0xe230bbd400000000, 0x41a5df4a00000000, 0xd795d83d00000000, + 0x6dc4d1a400000000, 0xfbf4d6d300000000, 0x6ae9694300000000, + 0xfcd96e3400000000, 0x468867ad00000000, 0xd0b860da00000000, + 0x732d044400000000, 0xe51d033300000000, 0x5f4c0aaa00000000, + 0xc97c0ddd00000000, 0x3c71055000000000, 0xaa41022700000000, + 0x10100bbe00000000, 0x86200cc900000000, 0x25b5685700000000, + 0xb3856f2000000000, 0x09d466b900000000, 0x9fe461ce00000000, + 0x0ef9de5e00000000, 0x98c9d92900000000, 0x2298d0b000000000, + 0xb4a8d7c700000000, 0x173db35900000000, 0x810db42e00000000, + 0x3b5cbdb700000000, 0xad6cbac000000000, 0x2083b8ed00000000, + 0xb6b3bf9a00000000, 0x0ce2b60300000000, 0x9ad2b17400000000, + 0x3947d5ea00000000, 0xaf77d29d00000000, 0x1526db0400000000, + 0x8316dc7300000000, 0x120b63e300000000, 0x843b649400000000, + 0x3e6a6d0d00000000, 0xa85a6a7a00000000, 0x0bcf0ee400000000, + 0x9dff099300000000, 0x27ae000a00000000, 0xb19e077d00000000, + 0x44930ff000000000, 0xd2a3088700000000, 0x68f2011e00000000, + 0xfec2066900000000, 0x5d5762f700000000, 0xcb67658000000000, + 0x71366c1900000000, 0xe7066b6e00000000, 0x761bd4fe00000000, + 0xe02bd38900000000, 0x5a7ada1000000000, 0xcc4add6700000000, + 0x6fdfb9f900000000, 0xf9efbe8e00000000, 0x43beb71700000000, + 0xd58eb06000000000, 0xe8a3d6d600000000, 0x7e93d1a100000000, + 0xc4c2d83800000000, 0x52f2df4f00000000, 0xf167bbd100000000, + 0x6757bca600000000, 0xdd06b53f00000000, 0x4b36b24800000000, + 0xda2b0dd800000000, 0x4c1b0aaf00000000, 0xf64a033600000000, + 0x607a044100000000, 0xc3ef60df00000000, 0x55df67a800000000, + 0xef8e6e3100000000, 0x79be694600000000, 0x8cb361cb00000000, + 0x1a8366bc00000000, 0xa0d26f2500000000, 0x36e2685200000000, + 0x95770ccc00000000, 0x03470bbb00000000, 0xb916022200000000, + 0x2f26055500000000, 0xbe3bbac500000000, 0x280bbdb200000000, + 0x925ab42b00000000, 0x046ab35c00000000, 0xa7ffd7c200000000, + 0x31cfd0b500000000, 0x8b9ed92c00000000, 0x1daede5b00000000, + 0xb0c2649b00000000, 0x26f263ec00000000, 0x9ca36a7500000000, + 0x0a936d0200000000, 0xa906099c00000000, 0x3f360eeb00000000, + 0x8567077200000000, 0x1357000500000000, 0x824abf9500000000, + 0x147ab8e200000000, 0xae2bb17b00000000, 0x381bb60c00000000, + 0x9b8ed29200000000, 0x0dbed5e500000000, 0xb7efdc7c00000000, + 0x21dfdb0b00000000, 0xd4d2d38600000000, 0x42e2d4f100000000, + 0xf8b3dd6800000000, 0x6e83da1f00000000, 0xcd16be8100000000, + 0x5b26b9f600000000, 0xe177b06f00000000, 0x7747b71800000000, + 0xe65a088800000000, 0x706a0fff00000000, 0xca3b066600000000, + 0x5c0b011100000000, 0xff9e658f00000000, 0x69ae62f800000000, + 0xd3ff6b6100000000, 0x45cf6c1600000000, 0x78e20aa000000000, + 0xeed20dd700000000, 0x5483044e00000000, 0xc2b3033900000000, + 0x612667a700000000, 0xf71660d000000000, 0x4d47694900000000, + 0xdb776e3e00000000, 0x4a6ad1ae00000000, 0xdc5ad6d900000000, + 0x660bdf4000000000, 0xf03bd83700000000, 0x53aebca900000000, + 0xc59ebbde00000000, 0x7fcfb24700000000, 0xe9ffb53000000000, + 0x1cf2bdbd00000000, 0x8ac2baca00000000, 0x3093b35300000000, + 0xa6a3b42400000000, 0x0536d0ba00000000, 0x9306d7cd00000000, + 0x2957de5400000000, 0xbf67d92300000000, 0x2e7a66b300000000, + 0xb84a61c400000000, 0x021b685d00000000, 0x942b6f2a00000000, + 0x37be0bb400000000, 0xa18e0cc300000000, 0x1bdf055a00000000, + 0x8def022d00000000}, + {0x0000000000000000, 0x41311b1900000000, 0x8262363200000000, + 0xc3532d2b00000000, 0x04c56c6400000000, 0x45f4777d00000000, + 0x86a75a5600000000, 0xc796414f00000000, 0x088ad9c800000000, + 0x49bbc2d100000000, 0x8ae8effa00000000, 0xcbd9f4e300000000, + 0x0c4fb5ac00000000, 0x4d7eaeb500000000, 0x8e2d839e00000000, + 0xcf1c988700000000, 0x5112c24a00000000, 0x1023d95300000000, + 0xd370f47800000000, 0x9241ef6100000000, 0x55d7ae2e00000000, + 0x14e6b53700000000, 0xd7b5981c00000000, 0x9684830500000000, + 0x59981b8200000000, 0x18a9009b00000000, 0xdbfa2db000000000, + 0x9acb36a900000000, 0x5d5d77e600000000, 0x1c6c6cff00000000, + 0xdf3f41d400000000, 0x9e0e5acd00000000, 0xa224849500000000, + 0xe3159f8c00000000, 0x2046b2a700000000, 0x6177a9be00000000, + 0xa6e1e8f100000000, 0xe7d0f3e800000000, 0x2483dec300000000, + 0x65b2c5da00000000, 0xaaae5d5d00000000, 0xeb9f464400000000, + 0x28cc6b6f00000000, 0x69fd707600000000, 0xae6b313900000000, + 0xef5a2a2000000000, 0x2c09070b00000000, 0x6d381c1200000000, + 0xf33646df00000000, 0xb2075dc600000000, 0x715470ed00000000, + 0x30656bf400000000, 0xf7f32abb00000000, 0xb6c231a200000000, + 0x75911c8900000000, 0x34a0079000000000, 0xfbbc9f1700000000, + 0xba8d840e00000000, 0x79dea92500000000, 0x38efb23c00000000, + 0xff79f37300000000, 0xbe48e86a00000000, 0x7d1bc54100000000, + 0x3c2ade5800000000, 0x054f79f000000000, 0x447e62e900000000, + 0x872d4fc200000000, 0xc61c54db00000000, 0x018a159400000000, + 0x40bb0e8d00000000, 0x83e823a600000000, 0xc2d938bf00000000, + 0x0dc5a03800000000, 0x4cf4bb2100000000, 0x8fa7960a00000000, + 0xce968d1300000000, 0x0900cc5c00000000, 0x4831d74500000000, + 0x8b62fa6e00000000, 0xca53e17700000000, 0x545dbbba00000000, + 0x156ca0a300000000, 0xd63f8d8800000000, 0x970e969100000000, + 0x5098d7de00000000, 0x11a9ccc700000000, 0xd2fae1ec00000000, + 0x93cbfaf500000000, 0x5cd7627200000000, 0x1de6796b00000000, + 0xdeb5544000000000, 0x9f844f5900000000, 0x58120e1600000000, + 0x1923150f00000000, 0xda70382400000000, 0x9b41233d00000000, + 0xa76bfd6500000000, 0xe65ae67c00000000, 0x2509cb5700000000, + 0x6438d04e00000000, 0xa3ae910100000000, 0xe29f8a1800000000, + 0x21cca73300000000, 0x60fdbc2a00000000, 0xafe124ad00000000, + 0xeed03fb400000000, 0x2d83129f00000000, 0x6cb2098600000000, + 0xab2448c900000000, 0xea1553d000000000, 0x29467efb00000000, + 0x687765e200000000, 0xf6793f2f00000000, 0xb748243600000000, + 0x741b091d00000000, 0x352a120400000000, 0xf2bc534b00000000, + 0xb38d485200000000, 0x70de657900000000, 0x31ef7e6000000000, + 0xfef3e6e700000000, 0xbfc2fdfe00000000, 0x7c91d0d500000000, + 0x3da0cbcc00000000, 0xfa368a8300000000, 0xbb07919a00000000, + 0x7854bcb100000000, 0x3965a7a800000000, 0x4b98833b00000000, + 0x0aa9982200000000, 0xc9fab50900000000, 0x88cbae1000000000, + 0x4f5def5f00000000, 0x0e6cf44600000000, 0xcd3fd96d00000000, + 0x8c0ec27400000000, 0x43125af300000000, 0x022341ea00000000, + 0xc1706cc100000000, 0x804177d800000000, 0x47d7369700000000, + 0x06e62d8e00000000, 0xc5b500a500000000, 0x84841bbc00000000, + 0x1a8a417100000000, 0x5bbb5a6800000000, 0x98e8774300000000, + 0xd9d96c5a00000000, 0x1e4f2d1500000000, 0x5f7e360c00000000, + 0x9c2d1b2700000000, 0xdd1c003e00000000, 0x120098b900000000, + 0x533183a000000000, 0x9062ae8b00000000, 0xd153b59200000000, + 0x16c5f4dd00000000, 0x57f4efc400000000, 0x94a7c2ef00000000, + 0xd596d9f600000000, 0xe9bc07ae00000000, 0xa88d1cb700000000, + 0x6bde319c00000000, 0x2aef2a8500000000, 0xed796bca00000000, + 0xac4870d300000000, 0x6f1b5df800000000, 0x2e2a46e100000000, + 0xe136de6600000000, 0xa007c57f00000000, 0x6354e85400000000, + 0x2265f34d00000000, 0xe5f3b20200000000, 0xa4c2a91b00000000, + 0x6791843000000000, 0x26a09f2900000000, 0xb8aec5e400000000, + 0xf99fdefd00000000, 0x3accf3d600000000, 0x7bfde8cf00000000, + 0xbc6ba98000000000, 0xfd5ab29900000000, 0x3e099fb200000000, + 0x7f3884ab00000000, 0xb0241c2c00000000, 0xf115073500000000, + 0x32462a1e00000000, 0x7377310700000000, 0xb4e1704800000000, + 0xf5d06b5100000000, 0x3683467a00000000, 0x77b25d6300000000, + 0x4ed7facb00000000, 0x0fe6e1d200000000, 0xccb5ccf900000000, + 0x8d84d7e000000000, 0x4a1296af00000000, 0x0b238db600000000, + 0xc870a09d00000000, 0x8941bb8400000000, 0x465d230300000000, + 0x076c381a00000000, 0xc43f153100000000, 0x850e0e2800000000, + 0x42984f6700000000, 0x03a9547e00000000, 0xc0fa795500000000, + 0x81cb624c00000000, 0x1fc5388100000000, 0x5ef4239800000000, + 0x9da70eb300000000, 0xdc9615aa00000000, 0x1b0054e500000000, + 0x5a314ffc00000000, 0x996262d700000000, 0xd85379ce00000000, + 0x174fe14900000000, 0x567efa5000000000, 0x952dd77b00000000, + 0xd41ccc6200000000, 0x138a8d2d00000000, 0x52bb963400000000, + 0x91e8bb1f00000000, 0xd0d9a00600000000, 0xecf37e5e00000000, + 0xadc2654700000000, 0x6e91486c00000000, 0x2fa0537500000000, + 0xe836123a00000000, 0xa907092300000000, 0x6a54240800000000, + 0x2b653f1100000000, 0xe479a79600000000, 0xa548bc8f00000000, + 0x661b91a400000000, 0x272a8abd00000000, 0xe0bccbf200000000, + 0xa18dd0eb00000000, 0x62defdc000000000, 0x23efe6d900000000, + 0xbde1bc1400000000, 0xfcd0a70d00000000, 0x3f838a2600000000, + 0x7eb2913f00000000, 0xb924d07000000000, 0xf815cb6900000000, + 0x3b46e64200000000, 0x7a77fd5b00000000, 0xb56b65dc00000000, + 0xf45a7ec500000000, 0x370953ee00000000, 0x763848f700000000, + 0xb1ae09b800000000, 0xf09f12a100000000, 0x33cc3f8a00000000, + 0x72fd249300000000}, + {0x0000000000000000, 0x376ac20100000000, 0x6ed4840300000000, + 0x59be460200000000, 0xdca8090700000000, 0xebc2cb0600000000, + 0xb27c8d0400000000, 0x85164f0500000000, 0xb851130e00000000, + 0x8f3bd10f00000000, 0xd685970d00000000, 0xe1ef550c00000000, + 0x64f91a0900000000, 0x5393d80800000000, 0x0a2d9e0a00000000, + 0x3d475c0b00000000, 0x70a3261c00000000, 0x47c9e41d00000000, + 0x1e77a21f00000000, 0x291d601e00000000, 0xac0b2f1b00000000, + 0x9b61ed1a00000000, 0xc2dfab1800000000, 0xf5b5691900000000, + 0xc8f2351200000000, 0xff98f71300000000, 0xa626b11100000000, + 0x914c731000000000, 0x145a3c1500000000, 0x2330fe1400000000, + 0x7a8eb81600000000, 0x4de47a1700000000, 0xe0464d3800000000, + 0xd72c8f3900000000, 0x8e92c93b00000000, 0xb9f80b3a00000000, + 0x3cee443f00000000, 0x0b84863e00000000, 0x523ac03c00000000, + 0x6550023d00000000, 0x58175e3600000000, 0x6f7d9c3700000000, + 0x36c3da3500000000, 0x01a9183400000000, 0x84bf573100000000, + 0xb3d5953000000000, 0xea6bd33200000000, 0xdd01113300000000, + 0x90e56b2400000000, 0xa78fa92500000000, 0xfe31ef2700000000, + 0xc95b2d2600000000, 0x4c4d622300000000, 0x7b27a02200000000, + 0x2299e62000000000, 0x15f3242100000000, 0x28b4782a00000000, + 0x1fdeba2b00000000, 0x4660fc2900000000, 0x710a3e2800000000, + 0xf41c712d00000000, 0xc376b32c00000000, 0x9ac8f52e00000000, + 0xada2372f00000000, 0xc08d9a7000000000, 0xf7e7587100000000, + 0xae591e7300000000, 0x9933dc7200000000, 0x1c25937700000000, + 0x2b4f517600000000, 0x72f1177400000000, 0x459bd57500000000, + 0x78dc897e00000000, 0x4fb64b7f00000000, 0x16080d7d00000000, + 0x2162cf7c00000000, 0xa474807900000000, 0x931e427800000000, + 0xcaa0047a00000000, 0xfdcac67b00000000, 0xb02ebc6c00000000, + 0x87447e6d00000000, 0xdefa386f00000000, 0xe990fa6e00000000, + 0x6c86b56b00000000, 0x5bec776a00000000, 0x0252316800000000, + 0x3538f36900000000, 0x087faf6200000000, 0x3f156d6300000000, + 0x66ab2b6100000000, 0x51c1e96000000000, 0xd4d7a66500000000, + 0xe3bd646400000000, 0xba03226600000000, 0x8d69e06700000000, + 0x20cbd74800000000, 0x17a1154900000000, 0x4e1f534b00000000, + 0x7975914a00000000, 0xfc63de4f00000000, 0xcb091c4e00000000, + 0x92b75a4c00000000, 0xa5dd984d00000000, 0x989ac44600000000, + 0xaff0064700000000, 0xf64e404500000000, 0xc124824400000000, + 0x4432cd4100000000, 0x73580f4000000000, 0x2ae6494200000000, + 0x1d8c8b4300000000, 0x5068f15400000000, 0x6702335500000000, + 0x3ebc755700000000, 0x09d6b75600000000, 0x8cc0f85300000000, + 0xbbaa3a5200000000, 0xe2147c5000000000, 0xd57ebe5100000000, + 0xe839e25a00000000, 0xdf53205b00000000, 0x86ed665900000000, + 0xb187a45800000000, 0x3491eb5d00000000, 0x03fb295c00000000, + 0x5a456f5e00000000, 0x6d2fad5f00000000, 0x801b35e100000000, + 0xb771f7e000000000, 0xeecfb1e200000000, 0xd9a573e300000000, + 0x5cb33ce600000000, 0x6bd9fee700000000, 0x3267b8e500000000, + 0x050d7ae400000000, 0x384a26ef00000000, 0x0f20e4ee00000000, + 0x569ea2ec00000000, 0x61f460ed00000000, 0xe4e22fe800000000, + 0xd388ede900000000, 0x8a36abeb00000000, 0xbd5c69ea00000000, + 0xf0b813fd00000000, 0xc7d2d1fc00000000, 0x9e6c97fe00000000, + 0xa90655ff00000000, 0x2c101afa00000000, 0x1b7ad8fb00000000, + 0x42c49ef900000000, 0x75ae5cf800000000, 0x48e900f300000000, + 0x7f83c2f200000000, 0x263d84f000000000, 0x115746f100000000, + 0x944109f400000000, 0xa32bcbf500000000, 0xfa958df700000000, + 0xcdff4ff600000000, 0x605d78d900000000, 0x5737bad800000000, + 0x0e89fcda00000000, 0x39e33edb00000000, 0xbcf571de00000000, + 0x8b9fb3df00000000, 0xd221f5dd00000000, 0xe54b37dc00000000, + 0xd80c6bd700000000, 0xef66a9d600000000, 0xb6d8efd400000000, + 0x81b22dd500000000, 0x04a462d000000000, 0x33cea0d100000000, + 0x6a70e6d300000000, 0x5d1a24d200000000, 0x10fe5ec500000000, + 0x27949cc400000000, 0x7e2adac600000000, 0x494018c700000000, + 0xcc5657c200000000, 0xfb3c95c300000000, 0xa282d3c100000000, + 0x95e811c000000000, 0xa8af4dcb00000000, 0x9fc58fca00000000, + 0xc67bc9c800000000, 0xf1110bc900000000, 0x740744cc00000000, + 0x436d86cd00000000, 0x1ad3c0cf00000000, 0x2db902ce00000000, + 0x4096af9100000000, 0x77fc6d9000000000, 0x2e422b9200000000, + 0x1928e99300000000, 0x9c3ea69600000000, 0xab54649700000000, + 0xf2ea229500000000, 0xc580e09400000000, 0xf8c7bc9f00000000, + 0xcfad7e9e00000000, 0x9613389c00000000, 0xa179fa9d00000000, + 0x246fb59800000000, 0x1305779900000000, 0x4abb319b00000000, + 0x7dd1f39a00000000, 0x3035898d00000000, 0x075f4b8c00000000, + 0x5ee10d8e00000000, 0x698bcf8f00000000, 0xec9d808a00000000, + 0xdbf7428b00000000, 0x8249048900000000, 0xb523c68800000000, + 0x88649a8300000000, 0xbf0e588200000000, 0xe6b01e8000000000, + 0xd1dadc8100000000, 0x54cc938400000000, 0x63a6518500000000, + 0x3a18178700000000, 0x0d72d58600000000, 0xa0d0e2a900000000, + 0x97ba20a800000000, 0xce0466aa00000000, 0xf96ea4ab00000000, + 0x7c78ebae00000000, 0x4b1229af00000000, 0x12ac6fad00000000, + 0x25c6adac00000000, 0x1881f1a700000000, 0x2feb33a600000000, + 0x765575a400000000, 0x413fb7a500000000, 0xc429f8a000000000, + 0xf3433aa100000000, 0xaafd7ca300000000, 0x9d97bea200000000, + 0xd073c4b500000000, 0xe71906b400000000, 0xbea740b600000000, + 0x89cd82b700000000, 0x0cdbcdb200000000, 0x3bb10fb300000000, + 0x620f49b100000000, 0x55658bb000000000, 0x6822d7bb00000000, + 0x5f4815ba00000000, 0x06f653b800000000, 0x319c91b900000000, + 0xb48adebc00000000, 0x83e01cbd00000000, 0xda5e5abf00000000, + 0xed3498be00000000}, + {0x0000000000000000, 0x6567bcb800000000, 0x8bc809aa00000000, + 0xeeafb51200000000, 0x5797628f00000000, 0x32f0de3700000000, + 0xdc5f6b2500000000, 0xb938d79d00000000, 0xef28b4c500000000, + 0x8a4f087d00000000, 0x64e0bd6f00000000, 0x018701d700000000, + 0xb8bfd64a00000000, 0xddd86af200000000, 0x3377dfe000000000, + 0x5610635800000000, 0x9f57195000000000, 0xfa30a5e800000000, + 0x149f10fa00000000, 0x71f8ac4200000000, 0xc8c07bdf00000000, + 0xada7c76700000000, 0x4308727500000000, 0x266fcecd00000000, + 0x707fad9500000000, 0x1518112d00000000, 0xfbb7a43f00000000, + 0x9ed0188700000000, 0x27e8cf1a00000000, 0x428f73a200000000, + 0xac20c6b000000000, 0xc9477a0800000000, 0x3eaf32a000000000, + 0x5bc88e1800000000, 0xb5673b0a00000000, 0xd00087b200000000, + 0x6938502f00000000, 0x0c5fec9700000000, 0xe2f0598500000000, + 0x8797e53d00000000, 0xd187866500000000, 0xb4e03add00000000, + 0x5a4f8fcf00000000, 0x3f28337700000000, 0x8610e4ea00000000, + 0xe377585200000000, 0x0dd8ed4000000000, 0x68bf51f800000000, + 0xa1f82bf000000000, 0xc49f974800000000, 0x2a30225a00000000, + 0x4f579ee200000000, 0xf66f497f00000000, 0x9308f5c700000000, + 0x7da740d500000000, 0x18c0fc6d00000000, 0x4ed09f3500000000, + 0x2bb7238d00000000, 0xc518969f00000000, 0xa07f2a2700000000, + 0x1947fdba00000000, 0x7c20410200000000, 0x928ff41000000000, + 0xf7e848a800000000, 0x3d58149b00000000, 0x583fa82300000000, + 0xb6901d3100000000, 0xd3f7a18900000000, 0x6acf761400000000, + 0x0fa8caac00000000, 0xe1077fbe00000000, 0x8460c30600000000, + 0xd270a05e00000000, 0xb7171ce600000000, 0x59b8a9f400000000, + 0x3cdf154c00000000, 0x85e7c2d100000000, 0xe0807e6900000000, + 0x0e2fcb7b00000000, 0x6b4877c300000000, 0xa20f0dcb00000000, + 0xc768b17300000000, 0x29c7046100000000, 0x4ca0b8d900000000, + 0xf5986f4400000000, 0x90ffd3fc00000000, 0x7e5066ee00000000, + 0x1b37da5600000000, 0x4d27b90e00000000, 0x284005b600000000, + 0xc6efb0a400000000, 0xa3880c1c00000000, 0x1ab0db8100000000, + 0x7fd7673900000000, 0x9178d22b00000000, 0xf41f6e9300000000, + 0x03f7263b00000000, 0x66909a8300000000, 0x883f2f9100000000, + 0xed58932900000000, 0x546044b400000000, 0x3107f80c00000000, + 0xdfa84d1e00000000, 0xbacff1a600000000, 0xecdf92fe00000000, + 0x89b82e4600000000, 0x67179b5400000000, 0x027027ec00000000, + 0xbb48f07100000000, 0xde2f4cc900000000, 0x3080f9db00000000, + 0x55e7456300000000, 0x9ca03f6b00000000, 0xf9c783d300000000, + 0x176836c100000000, 0x720f8a7900000000, 0xcb375de400000000, + 0xae50e15c00000000, 0x40ff544e00000000, 0x2598e8f600000000, + 0x73888bae00000000, 0x16ef371600000000, 0xf840820400000000, + 0x9d273ebc00000000, 0x241fe92100000000, 0x4178559900000000, + 0xafd7e08b00000000, 0xcab05c3300000000, 0x3bb659ed00000000, + 0x5ed1e55500000000, 0xb07e504700000000, 0xd519ecff00000000, + 0x6c213b6200000000, 0x094687da00000000, 0xe7e932c800000000, + 0x828e8e7000000000, 0xd49eed2800000000, 0xb1f9519000000000, + 0x5f56e48200000000, 0x3a31583a00000000, 0x83098fa700000000, + 0xe66e331f00000000, 0x08c1860d00000000, 0x6da63ab500000000, + 0xa4e140bd00000000, 0xc186fc0500000000, 0x2f29491700000000, + 0x4a4ef5af00000000, 0xf376223200000000, 0x96119e8a00000000, + 0x78be2b9800000000, 0x1dd9972000000000, 0x4bc9f47800000000, + 0x2eae48c000000000, 0xc001fdd200000000, 0xa566416a00000000, + 0x1c5e96f700000000, 0x79392a4f00000000, 0x97969f5d00000000, + 0xf2f123e500000000, 0x05196b4d00000000, 0x607ed7f500000000, + 0x8ed162e700000000, 0xebb6de5f00000000, 0x528e09c200000000, + 0x37e9b57a00000000, 0xd946006800000000, 0xbc21bcd000000000, + 0xea31df8800000000, 0x8f56633000000000, 0x61f9d62200000000, + 0x049e6a9a00000000, 0xbda6bd0700000000, 0xd8c101bf00000000, + 0x366eb4ad00000000, 0x5309081500000000, 0x9a4e721d00000000, + 0xff29cea500000000, 0x11867bb700000000, 0x74e1c70f00000000, + 0xcdd9109200000000, 0xa8beac2a00000000, 0x4611193800000000, + 0x2376a58000000000, 0x7566c6d800000000, 0x10017a6000000000, + 0xfeaecf7200000000, 0x9bc973ca00000000, 0x22f1a45700000000, + 0x479618ef00000000, 0xa939adfd00000000, 0xcc5e114500000000, + 0x06ee4d7600000000, 0x6389f1ce00000000, 0x8d2644dc00000000, + 0xe841f86400000000, 0x51792ff900000000, 0x341e934100000000, + 0xdab1265300000000, 0xbfd69aeb00000000, 0xe9c6f9b300000000, + 0x8ca1450b00000000, 0x620ef01900000000, 0x07694ca100000000, + 0xbe519b3c00000000, 0xdb36278400000000, 0x3599929600000000, + 0x50fe2e2e00000000, 0x99b9542600000000, 0xfcdee89e00000000, + 0x12715d8c00000000, 0x7716e13400000000, 0xce2e36a900000000, + 0xab498a1100000000, 0x45e63f0300000000, 0x208183bb00000000, + 0x7691e0e300000000, 0x13f65c5b00000000, 0xfd59e94900000000, + 0x983e55f100000000, 0x2106826c00000000, 0x44613ed400000000, + 0xaace8bc600000000, 0xcfa9377e00000000, 0x38417fd600000000, + 0x5d26c36e00000000, 0xb389767c00000000, 0xd6eecac400000000, + 0x6fd61d5900000000, 0x0ab1a1e100000000, 0xe41e14f300000000, + 0x8179a84b00000000, 0xd769cb1300000000, 0xb20e77ab00000000, + 0x5ca1c2b900000000, 0x39c67e0100000000, 0x80fea99c00000000, + 0xe599152400000000, 0x0b36a03600000000, 0x6e511c8e00000000, + 0xa716668600000000, 0xc271da3e00000000, 0x2cde6f2c00000000, + 0x49b9d39400000000, 0xf081040900000000, 0x95e6b8b100000000, + 0x7b490da300000000, 0x1e2eb11b00000000, 0x483ed24300000000, + 0x2d596efb00000000, 0xc3f6dbe900000000, 0xa691675100000000, + 0x1fa9b0cc00000000, 0x7ace0c7400000000, 0x9461b96600000000, + 0xf10605de00000000}, + {0x0000000000000000, 0xb029603d00000000, 0x6053c07a00000000, + 0xd07aa04700000000, 0xc0a680f500000000, 0x708fe0c800000000, + 0xa0f5408f00000000, 0x10dc20b200000000, 0xc14b703000000000, + 0x7162100d00000000, 0xa118b04a00000000, 0x1131d07700000000, + 0x01edf0c500000000, 0xb1c490f800000000, 0x61be30bf00000000, + 0xd197508200000000, 0x8297e06000000000, 0x32be805d00000000, + 0xe2c4201a00000000, 0x52ed402700000000, 0x4231609500000000, + 0xf21800a800000000, 0x2262a0ef00000000, 0x924bc0d200000000, + 0x43dc905000000000, 0xf3f5f06d00000000, 0x238f502a00000000, + 0x93a6301700000000, 0x837a10a500000000, 0x3353709800000000, + 0xe329d0df00000000, 0x5300b0e200000000, 0x042fc1c100000000, + 0xb406a1fc00000000, 0x647c01bb00000000, 0xd455618600000000, + 0xc489413400000000, 0x74a0210900000000, 0xa4da814e00000000, + 0x14f3e17300000000, 0xc564b1f100000000, 0x754dd1cc00000000, + 0xa537718b00000000, 0x151e11b600000000, 0x05c2310400000000, + 0xb5eb513900000000, 0x6591f17e00000000, 0xd5b8914300000000, + 0x86b821a100000000, 0x3691419c00000000, 0xe6ebe1db00000000, + 0x56c281e600000000, 0x461ea15400000000, 0xf637c16900000000, + 0x264d612e00000000, 0x9664011300000000, 0x47f3519100000000, + 0xf7da31ac00000000, 0x27a091eb00000000, 0x9789f1d600000000, + 0x8755d16400000000, 0x377cb15900000000, 0xe706111e00000000, + 0x572f712300000000, 0x4958f35800000000, 0xf971936500000000, + 0x290b332200000000, 0x9922531f00000000, 0x89fe73ad00000000, + 0x39d7139000000000, 0xe9adb3d700000000, 0x5984d3ea00000000, + 0x8813836800000000, 0x383ae35500000000, 0xe840431200000000, + 0x5869232f00000000, 0x48b5039d00000000, 0xf89c63a000000000, + 0x28e6c3e700000000, 0x98cfa3da00000000, 0xcbcf133800000000, + 0x7be6730500000000, 0xab9cd34200000000, 0x1bb5b37f00000000, + 0x0b6993cd00000000, 0xbb40f3f000000000, 0x6b3a53b700000000, + 0xdb13338a00000000, 0x0a84630800000000, 0xbaad033500000000, + 0x6ad7a37200000000, 0xdafec34f00000000, 0xca22e3fd00000000, + 0x7a0b83c000000000, 0xaa71238700000000, 0x1a5843ba00000000, + 0x4d77329900000000, 0xfd5e52a400000000, 0x2d24f2e300000000, + 0x9d0d92de00000000, 0x8dd1b26c00000000, 0x3df8d25100000000, + 0xed82721600000000, 0x5dab122b00000000, 0x8c3c42a900000000, + 0x3c15229400000000, 0xec6f82d300000000, 0x5c46e2ee00000000, + 0x4c9ac25c00000000, 0xfcb3a26100000000, 0x2cc9022600000000, + 0x9ce0621b00000000, 0xcfe0d2f900000000, 0x7fc9b2c400000000, + 0xafb3128300000000, 0x1f9a72be00000000, 0x0f46520c00000000, + 0xbf6f323100000000, 0x6f15927600000000, 0xdf3cf24b00000000, + 0x0eaba2c900000000, 0xbe82c2f400000000, 0x6ef862b300000000, + 0xded1028e00000000, 0xce0d223c00000000, 0x7e24420100000000, + 0xae5ee24600000000, 0x1e77827b00000000, 0x92b0e6b100000000, + 0x2299868c00000000, 0xf2e326cb00000000, 0x42ca46f600000000, + 0x5216664400000000, 0xe23f067900000000, 0x3245a63e00000000, + 0x826cc60300000000, 0x53fb968100000000, 0xe3d2f6bc00000000, + 0x33a856fb00000000, 0x838136c600000000, 0x935d167400000000, + 0x2374764900000000, 0xf30ed60e00000000, 0x4327b63300000000, + 0x102706d100000000, 0xa00e66ec00000000, 0x7074c6ab00000000, + 0xc05da69600000000, 0xd081862400000000, 0x60a8e61900000000, + 0xb0d2465e00000000, 0x00fb266300000000, 0xd16c76e100000000, + 0x614516dc00000000, 0xb13fb69b00000000, 0x0116d6a600000000, + 0x11caf61400000000, 0xa1e3962900000000, 0x7199366e00000000, + 0xc1b0565300000000, 0x969f277000000000, 0x26b6474d00000000, + 0xf6cce70a00000000, 0x46e5873700000000, 0x5639a78500000000, + 0xe610c7b800000000, 0x366a67ff00000000, 0x864307c200000000, + 0x57d4574000000000, 0xe7fd377d00000000, 0x3787973a00000000, + 0x87aef70700000000, 0x9772d7b500000000, 0x275bb78800000000, + 0xf72117cf00000000, 0x470877f200000000, 0x1408c71000000000, + 0xa421a72d00000000, 0x745b076a00000000, 0xc472675700000000, + 0xd4ae47e500000000, 0x648727d800000000, 0xb4fd879f00000000, + 0x04d4e7a200000000, 0xd543b72000000000, 0x656ad71d00000000, + 0xb510775a00000000, 0x0539176700000000, 0x15e537d500000000, + 0xa5cc57e800000000, 0x75b6f7af00000000, 0xc59f979200000000, + 0xdbe815e900000000, 0x6bc175d400000000, 0xbbbbd59300000000, + 0x0b92b5ae00000000, 0x1b4e951c00000000, 0xab67f52100000000, + 0x7b1d556600000000, 0xcb34355b00000000, 0x1aa365d900000000, + 0xaa8a05e400000000, 0x7af0a5a300000000, 0xcad9c59e00000000, + 0xda05e52c00000000, 0x6a2c851100000000, 0xba56255600000000, + 0x0a7f456b00000000, 0x597ff58900000000, 0xe95695b400000000, + 0x392c35f300000000, 0x890555ce00000000, 0x99d9757c00000000, + 0x29f0154100000000, 0xf98ab50600000000, 0x49a3d53b00000000, + 0x983485b900000000, 0x281de58400000000, 0xf86745c300000000, + 0x484e25fe00000000, 0x5892054c00000000, 0xe8bb657100000000, + 0x38c1c53600000000, 0x88e8a50b00000000, 0xdfc7d42800000000, + 0x6feeb41500000000, 0xbf94145200000000, 0x0fbd746f00000000, + 0x1f6154dd00000000, 0xaf4834e000000000, 0x7f3294a700000000, + 0xcf1bf49a00000000, 0x1e8ca41800000000, 0xaea5c42500000000, + 0x7edf646200000000, 0xcef6045f00000000, 0xde2a24ed00000000, + 0x6e0344d000000000, 0xbe79e49700000000, 0x0e5084aa00000000, + 0x5d50344800000000, 0xed79547500000000, 0x3d03f43200000000, + 0x8d2a940f00000000, 0x9df6b4bd00000000, 0x2ddfd48000000000, + 0xfda574c700000000, 0x4d8c14fa00000000, 0x9c1b447800000000, + 0x2c32244500000000, 0xfc48840200000000, 0x4c61e43f00000000, + 0x5cbdc48d00000000, 0xec94a4b000000000, 0x3cee04f700000000, + 0x8cc764ca00000000}, + {0x0000000000000000, 0xa5d35ccb00000000, 0x0ba1c84d00000000, + 0xae72948600000000, 0x1642919b00000000, 0xb391cd5000000000, + 0x1de359d600000000, 0xb830051d00000000, 0x6d8253ec00000000, + 0xc8510f2700000000, 0x66239ba100000000, 0xc3f0c76a00000000, + 0x7bc0c27700000000, 0xde139ebc00000000, 0x70610a3a00000000, + 0xd5b256f100000000, 0x9b02d60300000000, 0x3ed18ac800000000, + 0x90a31e4e00000000, 0x3570428500000000, 0x8d40479800000000, + 0x28931b5300000000, 0x86e18fd500000000, 0x2332d31e00000000, + 0xf68085ef00000000, 0x5353d92400000000, 0xfd214da200000000, + 0x58f2116900000000, 0xe0c2147400000000, 0x451148bf00000000, + 0xeb63dc3900000000, 0x4eb080f200000000, 0x3605ac0700000000, + 0x93d6f0cc00000000, 0x3da4644a00000000, 0x9877388100000000, + 0x20473d9c00000000, 0x8594615700000000, 0x2be6f5d100000000, + 0x8e35a91a00000000, 0x5b87ffeb00000000, 0xfe54a32000000000, + 0x502637a600000000, 0xf5f56b6d00000000, 0x4dc56e7000000000, + 0xe81632bb00000000, 0x4664a63d00000000, 0xe3b7faf600000000, + 0xad077a0400000000, 0x08d426cf00000000, 0xa6a6b24900000000, + 0x0375ee8200000000, 0xbb45eb9f00000000, 0x1e96b75400000000, + 0xb0e423d200000000, 0x15377f1900000000, 0xc08529e800000000, + 0x6556752300000000, 0xcb24e1a500000000, 0x6ef7bd6e00000000, + 0xd6c7b87300000000, 0x7314e4b800000000, 0xdd66703e00000000, + 0x78b52cf500000000, 0x6c0a580f00000000, 0xc9d904c400000000, + 0x67ab904200000000, 0xc278cc8900000000, 0x7a48c99400000000, + 0xdf9b955f00000000, 0x71e901d900000000, 0xd43a5d1200000000, + 0x01880be300000000, 0xa45b572800000000, 0x0a29c3ae00000000, + 0xaffa9f6500000000, 0x17ca9a7800000000, 0xb219c6b300000000, + 0x1c6b523500000000, 0xb9b80efe00000000, 0xf7088e0c00000000, + 0x52dbd2c700000000, 0xfca9464100000000, 0x597a1a8a00000000, + 0xe14a1f9700000000, 0x4499435c00000000, 0xeaebd7da00000000, + 0x4f388b1100000000, 0x9a8adde000000000, 0x3f59812b00000000, + 0x912b15ad00000000, 0x34f8496600000000, 0x8cc84c7b00000000, + 0x291b10b000000000, 0x8769843600000000, 0x22bad8fd00000000, + 0x5a0ff40800000000, 0xffdca8c300000000, 0x51ae3c4500000000, + 0xf47d608e00000000, 0x4c4d659300000000, 0xe99e395800000000, + 0x47ecadde00000000, 0xe23ff11500000000, 0x378da7e400000000, + 0x925efb2f00000000, 0x3c2c6fa900000000, 0x99ff336200000000, + 0x21cf367f00000000, 0x841c6ab400000000, 0x2a6efe3200000000, + 0x8fbda2f900000000, 0xc10d220b00000000, 0x64de7ec000000000, + 0xcaacea4600000000, 0x6f7fb68d00000000, 0xd74fb39000000000, + 0x729cef5b00000000, 0xdcee7bdd00000000, 0x793d271600000000, + 0xac8f71e700000000, 0x095c2d2c00000000, 0xa72eb9aa00000000, + 0x02fde56100000000, 0xbacde07c00000000, 0x1f1ebcb700000000, + 0xb16c283100000000, 0x14bf74fa00000000, 0xd814b01e00000000, + 0x7dc7ecd500000000, 0xd3b5785300000000, 0x7666249800000000, + 0xce56218500000000, 0x6b857d4e00000000, 0xc5f7e9c800000000, + 0x6024b50300000000, 0xb596e3f200000000, 0x1045bf3900000000, + 0xbe372bbf00000000, 0x1be4777400000000, 0xa3d4726900000000, + 0x06072ea200000000, 0xa875ba2400000000, 0x0da6e6ef00000000, + 0x4316661d00000000, 0xe6c53ad600000000, 0x48b7ae5000000000, + 0xed64f29b00000000, 0x5554f78600000000, 0xf087ab4d00000000, + 0x5ef53fcb00000000, 0xfb26630000000000, 0x2e9435f100000000, + 0x8b47693a00000000, 0x2535fdbc00000000, 0x80e6a17700000000, + 0x38d6a46a00000000, 0x9d05f8a100000000, 0x33776c2700000000, + 0x96a430ec00000000, 0xee111c1900000000, 0x4bc240d200000000, + 0xe5b0d45400000000, 0x4063889f00000000, 0xf8538d8200000000, + 0x5d80d14900000000, 0xf3f245cf00000000, 0x5621190400000000, + 0x83934ff500000000, 0x2640133e00000000, 0x883287b800000000, + 0x2de1db7300000000, 0x95d1de6e00000000, 0x300282a500000000, + 0x9e70162300000000, 0x3ba34ae800000000, 0x7513ca1a00000000, + 0xd0c096d100000000, 0x7eb2025700000000, 0xdb615e9c00000000, + 0x63515b8100000000, 0xc682074a00000000, 0x68f093cc00000000, + 0xcd23cf0700000000, 0x189199f600000000, 0xbd42c53d00000000, + 0x133051bb00000000, 0xb6e30d7000000000, 0x0ed3086d00000000, + 0xab0054a600000000, 0x0572c02000000000, 0xa0a19ceb00000000, + 0xb41ee81100000000, 0x11cdb4da00000000, 0xbfbf205c00000000, + 0x1a6c7c9700000000, 0xa25c798a00000000, 0x078f254100000000, + 0xa9fdb1c700000000, 0x0c2eed0c00000000, 0xd99cbbfd00000000, + 0x7c4fe73600000000, 0xd23d73b000000000, 0x77ee2f7b00000000, + 0xcfde2a6600000000, 0x6a0d76ad00000000, 0xc47fe22b00000000, + 0x61acbee000000000, 0x2f1c3e1200000000, 0x8acf62d900000000, + 0x24bdf65f00000000, 0x816eaa9400000000, 0x395eaf8900000000, + 0x9c8df34200000000, 0x32ff67c400000000, 0x972c3b0f00000000, + 0x429e6dfe00000000, 0xe74d313500000000, 0x493fa5b300000000, + 0xececf97800000000, 0x54dcfc6500000000, 0xf10fa0ae00000000, + 0x5f7d342800000000, 0xfaae68e300000000, 0x821b441600000000, + 0x27c818dd00000000, 0x89ba8c5b00000000, 0x2c69d09000000000, + 0x9459d58d00000000, 0x318a894600000000, 0x9ff81dc000000000, + 0x3a2b410b00000000, 0xef9917fa00000000, 0x4a4a4b3100000000, + 0xe438dfb700000000, 0x41eb837c00000000, 0xf9db866100000000, + 0x5c08daaa00000000, 0xf27a4e2c00000000, 0x57a912e700000000, + 0x1919921500000000, 0xbccacede00000000, 0x12b85a5800000000, + 0xb76b069300000000, 0x0f5b038e00000000, 0xaa885f4500000000, + 0x04facbc300000000, 0xa129970800000000, 0x749bc1f900000000, + 0xd1489d3200000000, 0x7f3a09b400000000, 0xdae9557f00000000, + 0x62d9506200000000, 0xc70a0ca900000000, 0x6978982f00000000, + 0xccabc4e400000000}, + {0x0000000000000000, 0xb40b77a600000000, 0x29119f9700000000, + 0x9d1ae83100000000, 0x13244ff400000000, 0xa72f385200000000, + 0x3a35d06300000000, 0x8e3ea7c500000000, 0x674eef3300000000, + 0xd345989500000000, 0x4e5f70a400000000, 0xfa54070200000000, + 0x746aa0c700000000, 0xc061d76100000000, 0x5d7b3f5000000000, + 0xe97048f600000000, 0xce9cde6700000000, 0x7a97a9c100000000, + 0xe78d41f000000000, 0x5386365600000000, 0xddb8919300000000, + 0x69b3e63500000000, 0xf4a90e0400000000, 0x40a279a200000000, + 0xa9d2315400000000, 0x1dd946f200000000, 0x80c3aec300000000, + 0x34c8d96500000000, 0xbaf67ea000000000, 0x0efd090600000000, + 0x93e7e13700000000, 0x27ec969100000000, 0x9c39bdcf00000000, + 0x2832ca6900000000, 0xb528225800000000, 0x012355fe00000000, + 0x8f1df23b00000000, 0x3b16859d00000000, 0xa60c6dac00000000, + 0x12071a0a00000000, 0xfb7752fc00000000, 0x4f7c255a00000000, + 0xd266cd6b00000000, 0x666dbacd00000000, 0xe8531d0800000000, + 0x5c586aae00000000, 0xc142829f00000000, 0x7549f53900000000, + 0x52a563a800000000, 0xe6ae140e00000000, 0x7bb4fc3f00000000, + 0xcfbf8b9900000000, 0x41812c5c00000000, 0xf58a5bfa00000000, + 0x6890b3cb00000000, 0xdc9bc46d00000000, 0x35eb8c9b00000000, + 0x81e0fb3d00000000, 0x1cfa130c00000000, 0xa8f164aa00000000, + 0x26cfc36f00000000, 0x92c4b4c900000000, 0x0fde5cf800000000, + 0xbbd52b5e00000000, 0x79750b4400000000, 0xcd7e7ce200000000, + 0x506494d300000000, 0xe46fe37500000000, 0x6a5144b000000000, + 0xde5a331600000000, 0x4340db2700000000, 0xf74bac8100000000, + 0x1e3be47700000000, 0xaa3093d100000000, 0x372a7be000000000, + 0x83210c4600000000, 0x0d1fab8300000000, 0xb914dc2500000000, + 0x240e341400000000, 0x900543b200000000, 0xb7e9d52300000000, + 0x03e2a28500000000, 0x9ef84ab400000000, 0x2af33d1200000000, + 0xa4cd9ad700000000, 0x10c6ed7100000000, 0x8ddc054000000000, + 0x39d772e600000000, 0xd0a73a1000000000, 0x64ac4db600000000, + 0xf9b6a58700000000, 0x4dbdd22100000000, 0xc38375e400000000, + 0x7788024200000000, 0xea92ea7300000000, 0x5e999dd500000000, + 0xe54cb68b00000000, 0x5147c12d00000000, 0xcc5d291c00000000, + 0x78565eba00000000, 0xf668f97f00000000, 0x42638ed900000000, + 0xdf7966e800000000, 0x6b72114e00000000, 0x820259b800000000, + 0x36092e1e00000000, 0xab13c62f00000000, 0x1f18b18900000000, + 0x9126164c00000000, 0x252d61ea00000000, 0xb83789db00000000, + 0x0c3cfe7d00000000, 0x2bd068ec00000000, 0x9fdb1f4a00000000, + 0x02c1f77b00000000, 0xb6ca80dd00000000, 0x38f4271800000000, + 0x8cff50be00000000, 0x11e5b88f00000000, 0xa5eecf2900000000, + 0x4c9e87df00000000, 0xf895f07900000000, 0x658f184800000000, + 0xd1846fee00000000, 0x5fbac82b00000000, 0xebb1bf8d00000000, + 0x76ab57bc00000000, 0xc2a0201a00000000, 0xf2ea168800000000, + 0x46e1612e00000000, 0xdbfb891f00000000, 0x6ff0feb900000000, + 0xe1ce597c00000000, 0x55c52eda00000000, 0xc8dfc6eb00000000, + 0x7cd4b14d00000000, 0x95a4f9bb00000000, 0x21af8e1d00000000, + 0xbcb5662c00000000, 0x08be118a00000000, 0x8680b64f00000000, + 0x328bc1e900000000, 0xaf9129d800000000, 0x1b9a5e7e00000000, + 0x3c76c8ef00000000, 0x887dbf4900000000, 0x1567577800000000, + 0xa16c20de00000000, 0x2f52871b00000000, 0x9b59f0bd00000000, + 0x0643188c00000000, 0xb2486f2a00000000, 0x5b3827dc00000000, + 0xef33507a00000000, 0x7229b84b00000000, 0xc622cfed00000000, + 0x481c682800000000, 0xfc171f8e00000000, 0x610df7bf00000000, + 0xd506801900000000, 0x6ed3ab4700000000, 0xdad8dce100000000, + 0x47c234d000000000, 0xf3c9437600000000, 0x7df7e4b300000000, + 0xc9fc931500000000, 0x54e67b2400000000, 0xe0ed0c8200000000, + 0x099d447400000000, 0xbd9633d200000000, 0x208cdbe300000000, + 0x9487ac4500000000, 0x1ab90b8000000000, 0xaeb27c2600000000, + 0x33a8941700000000, 0x87a3e3b100000000, 0xa04f752000000000, + 0x1444028600000000, 0x895eeab700000000, 0x3d559d1100000000, + 0xb36b3ad400000000, 0x07604d7200000000, 0x9a7aa54300000000, + 0x2e71d2e500000000, 0xc7019a1300000000, 0x730aedb500000000, + 0xee10058400000000, 0x5a1b722200000000, 0xd425d5e700000000, + 0x602ea24100000000, 0xfd344a7000000000, 0x493f3dd600000000, + 0x8b9f1dcc00000000, 0x3f946a6a00000000, 0xa28e825b00000000, + 0x1685f5fd00000000, 0x98bb523800000000, 0x2cb0259e00000000, + 0xb1aacdaf00000000, 0x05a1ba0900000000, 0xecd1f2ff00000000, + 0x58da855900000000, 0xc5c06d6800000000, 0x71cb1ace00000000, + 0xfff5bd0b00000000, 0x4bfecaad00000000, 0xd6e4229c00000000, + 0x62ef553a00000000, 0x4503c3ab00000000, 0xf108b40d00000000, + 0x6c125c3c00000000, 0xd8192b9a00000000, 0x56278c5f00000000, + 0xe22cfbf900000000, 0x7f3613c800000000, 0xcb3d646e00000000, + 0x224d2c9800000000, 0x96465b3e00000000, 0x0b5cb30f00000000, + 0xbf57c4a900000000, 0x3169636c00000000, 0x856214ca00000000, + 0x1878fcfb00000000, 0xac738b5d00000000, 0x17a6a00300000000, + 0xa3add7a500000000, 0x3eb73f9400000000, 0x8abc483200000000, + 0x0482eff700000000, 0xb089985100000000, 0x2d93706000000000, + 0x999807c600000000, 0x70e84f3000000000, 0xc4e3389600000000, + 0x59f9d0a700000000, 0xedf2a70100000000, 0x63cc00c400000000, + 0xd7c7776200000000, 0x4add9f5300000000, 0xfed6e8f500000000, + 0xd93a7e6400000000, 0x6d3109c200000000, 0xf02be1f300000000, + 0x4420965500000000, 0xca1e319000000000, 0x7e15463600000000, + 0xe30fae0700000000, 0x5704d9a100000000, 0xbe74915700000000, + 0x0a7fe6f100000000, 0x97650ec000000000, 0x236e796600000000, + 0xad50dea300000000, 0x195ba90500000000, 0x8441413400000000, + 0x304a369200000000}, + {0x0000000000000000, 0x9e00aacc00000000, 0x7d07254200000000, + 0xe3078f8e00000000, 0xfa0e4a8400000000, 0x640ee04800000000, + 0x87096fc600000000, 0x1909c50a00000000, 0xb51be5d300000000, + 0x2b1b4f1f00000000, 0xc81cc09100000000, 0x561c6a5d00000000, + 0x4f15af5700000000, 0xd115059b00000000, 0x32128a1500000000, + 0xac1220d900000000, 0x2b31bb7c00000000, 0xb53111b000000000, + 0x56369e3e00000000, 0xc83634f200000000, 0xd13ff1f800000000, + 0x4f3f5b3400000000, 0xac38d4ba00000000, 0x32387e7600000000, + 0x9e2a5eaf00000000, 0x002af46300000000, 0xe32d7bed00000000, + 0x7d2dd12100000000, 0x6424142b00000000, 0xfa24bee700000000, + 0x1923316900000000, 0x87239ba500000000, 0x566276f900000000, + 0xc862dc3500000000, 0x2b6553bb00000000, 0xb565f97700000000, + 0xac6c3c7d00000000, 0x326c96b100000000, 0xd16b193f00000000, + 0x4f6bb3f300000000, 0xe379932a00000000, 0x7d7939e600000000, + 0x9e7eb66800000000, 0x007e1ca400000000, 0x1977d9ae00000000, + 0x8777736200000000, 0x6470fcec00000000, 0xfa70562000000000, + 0x7d53cd8500000000, 0xe353674900000000, 0x0054e8c700000000, + 0x9e54420b00000000, 0x875d870100000000, 0x195d2dcd00000000, + 0xfa5aa24300000000, 0x645a088f00000000, 0xc848285600000000, + 0x5648829a00000000, 0xb54f0d1400000000, 0x2b4fa7d800000000, + 0x324662d200000000, 0xac46c81e00000000, 0x4f41479000000000, + 0xd141ed5c00000000, 0xedc29d2900000000, 0x73c237e500000000, + 0x90c5b86b00000000, 0x0ec512a700000000, 0x17ccd7ad00000000, + 0x89cc7d6100000000, 0x6acbf2ef00000000, 0xf4cb582300000000, + 0x58d978fa00000000, 0xc6d9d23600000000, 0x25de5db800000000, + 0xbbdef77400000000, 0xa2d7327e00000000, 0x3cd798b200000000, + 0xdfd0173c00000000, 0x41d0bdf000000000, 0xc6f3265500000000, + 0x58f38c9900000000, 0xbbf4031700000000, 0x25f4a9db00000000, + 0x3cfd6cd100000000, 0xa2fdc61d00000000, 0x41fa499300000000, + 0xdffae35f00000000, 0x73e8c38600000000, 0xede8694a00000000, + 0x0eefe6c400000000, 0x90ef4c0800000000, 0x89e6890200000000, + 0x17e623ce00000000, 0xf4e1ac4000000000, 0x6ae1068c00000000, + 0xbba0ebd000000000, 0x25a0411c00000000, 0xc6a7ce9200000000, + 0x58a7645e00000000, 0x41aea15400000000, 0xdfae0b9800000000, + 0x3ca9841600000000, 0xa2a92eda00000000, 0x0ebb0e0300000000, + 0x90bba4cf00000000, 0x73bc2b4100000000, 0xedbc818d00000000, + 0xf4b5448700000000, 0x6ab5ee4b00000000, 0x89b261c500000000, + 0x17b2cb0900000000, 0x909150ac00000000, 0x0e91fa6000000000, + 0xed9675ee00000000, 0x7396df2200000000, 0x6a9f1a2800000000, + 0xf49fb0e400000000, 0x17983f6a00000000, 0x899895a600000000, + 0x258ab57f00000000, 0xbb8a1fb300000000, 0x588d903d00000000, + 0xc68d3af100000000, 0xdf84fffb00000000, 0x4184553700000000, + 0xa283dab900000000, 0x3c83707500000000, 0xda853b5300000000, + 0x4485919f00000000, 0xa7821e1100000000, 0x3982b4dd00000000, + 0x208b71d700000000, 0xbe8bdb1b00000000, 0x5d8c549500000000, + 0xc38cfe5900000000, 0x6f9ede8000000000, 0xf19e744c00000000, + 0x1299fbc200000000, 0x8c99510e00000000, 0x9590940400000000, + 0x0b903ec800000000, 0xe897b14600000000, 0x76971b8a00000000, + 0xf1b4802f00000000, 0x6fb42ae300000000, 0x8cb3a56d00000000, + 0x12b30fa100000000, 0x0bbacaab00000000, 0x95ba606700000000, + 0x76bdefe900000000, 0xe8bd452500000000, 0x44af65fc00000000, + 0xdaafcf3000000000, 0x39a840be00000000, 0xa7a8ea7200000000, + 0xbea12f7800000000, 0x20a185b400000000, 0xc3a60a3a00000000, + 0x5da6a0f600000000, 0x8ce74daa00000000, 0x12e7e76600000000, + 0xf1e068e800000000, 0x6fe0c22400000000, 0x76e9072e00000000, + 0xe8e9ade200000000, 0x0bee226c00000000, 0x95ee88a000000000, + 0x39fca87900000000, 0xa7fc02b500000000, 0x44fb8d3b00000000, + 0xdafb27f700000000, 0xc3f2e2fd00000000, 0x5df2483100000000, + 0xbef5c7bf00000000, 0x20f56d7300000000, 0xa7d6f6d600000000, + 0x39d65c1a00000000, 0xdad1d39400000000, 0x44d1795800000000, + 0x5dd8bc5200000000, 0xc3d8169e00000000, 0x20df991000000000, + 0xbedf33dc00000000, 0x12cd130500000000, 0x8ccdb9c900000000, + 0x6fca364700000000, 0xf1ca9c8b00000000, 0xe8c3598100000000, + 0x76c3f34d00000000, 0x95c47cc300000000, 0x0bc4d60f00000000, + 0x3747a67a00000000, 0xa9470cb600000000, 0x4a40833800000000, + 0xd44029f400000000, 0xcd49ecfe00000000, 0x5349463200000000, + 0xb04ec9bc00000000, 0x2e4e637000000000, 0x825c43a900000000, + 0x1c5ce96500000000, 0xff5b66eb00000000, 0x615bcc2700000000, + 0x7852092d00000000, 0xe652a3e100000000, 0x05552c6f00000000, + 0x9b5586a300000000, 0x1c761d0600000000, 0x8276b7ca00000000, + 0x6171384400000000, 0xff71928800000000, 0xe678578200000000, + 0x7878fd4e00000000, 0x9b7f72c000000000, 0x057fd80c00000000, + 0xa96df8d500000000, 0x376d521900000000, 0xd46add9700000000, + 0x4a6a775b00000000, 0x5363b25100000000, 0xcd63189d00000000, + 0x2e64971300000000, 0xb0643ddf00000000, 0x6125d08300000000, + 0xff257a4f00000000, 0x1c22f5c100000000, 0x82225f0d00000000, + 0x9b2b9a0700000000, 0x052b30cb00000000, 0xe62cbf4500000000, + 0x782c158900000000, 0xd43e355000000000, 0x4a3e9f9c00000000, + 0xa939101200000000, 0x3739bade00000000, 0x2e307fd400000000, + 0xb030d51800000000, 0x53375a9600000000, 0xcd37f05a00000000, + 0x4a146bff00000000, 0xd414c13300000000, 0x37134ebd00000000, + 0xa913e47100000000, 0xb01a217b00000000, 0x2e1a8bb700000000, + 0xcd1d043900000000, 0x531daef500000000, 0xff0f8e2c00000000, + 0x610f24e000000000, 0x8208ab6e00000000, 0x1c0801a200000000, + 0x0501c4a800000000, 0x9b016e6400000000, 0x7806e1ea00000000, + 0xe6064b2600000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xb8bc6765, 0xaa09c88b, 0x12b5afee, 0x8f629757, + 0x37def032, 0x256b5fdc, 0x9dd738b9, 0xc5b428ef, 0x7d084f8a, + 0x6fbde064, 0xd7018701, 0x4ad6bfb8, 0xf26ad8dd, 0xe0df7733, + 0x58631056, 0x5019579f, 0xe8a530fa, 0xfa109f14, 0x42acf871, + 0xdf7bc0c8, 0x67c7a7ad, 0x75720843, 0xcdce6f26, 0x95ad7f70, + 0x2d111815, 0x3fa4b7fb, 0x8718d09e, 0x1acfe827, 0xa2738f42, + 0xb0c620ac, 0x087a47c9, 0xa032af3e, 0x188ec85b, 0x0a3b67b5, + 0xb28700d0, 0x2f503869, 0x97ec5f0c, 0x8559f0e2, 0x3de59787, + 0x658687d1, 0xdd3ae0b4, 0xcf8f4f5a, 0x7733283f, 0xeae41086, + 0x525877e3, 0x40edd80d, 0xf851bf68, 0xf02bf8a1, 0x48979fc4, + 0x5a22302a, 0xe29e574f, 0x7f496ff6, 0xc7f50893, 0xd540a77d, + 0x6dfcc018, 0x359fd04e, 0x8d23b72b, 0x9f9618c5, 0x272a7fa0, + 0xbafd4719, 0x0241207c, 0x10f48f92, 0xa848e8f7, 0x9b14583d, + 0x23a83f58, 0x311d90b6, 0x89a1f7d3, 0x1476cf6a, 0xaccaa80f, + 0xbe7f07e1, 0x06c36084, 0x5ea070d2, 0xe61c17b7, 0xf4a9b859, + 0x4c15df3c, 0xd1c2e785, 0x697e80e0, 0x7bcb2f0e, 0xc377486b, + 0xcb0d0fa2, 0x73b168c7, 0x6104c729, 0xd9b8a04c, 0x446f98f5, + 0xfcd3ff90, 0xee66507e, 0x56da371b, 0x0eb9274d, 0xb6054028, + 0xa4b0efc6, 0x1c0c88a3, 0x81dbb01a, 0x3967d77f, 0x2bd27891, + 0x936e1ff4, 0x3b26f703, 0x839a9066, 0x912f3f88, 0x299358ed, + 0xb4446054, 0x0cf80731, 0x1e4da8df, 0xa6f1cfba, 0xfe92dfec, + 0x462eb889, 0x549b1767, 0xec277002, 0x71f048bb, 0xc94c2fde, + 0xdbf98030, 0x6345e755, 0x6b3fa09c, 0xd383c7f9, 0xc1366817, + 0x798a0f72, 0xe45d37cb, 0x5ce150ae, 0x4e54ff40, 0xf6e89825, + 0xae8b8873, 0x1637ef16, 0x048240f8, 0xbc3e279d, 0x21e91f24, + 0x99557841, 0x8be0d7af, 0x335cb0ca, 0xed59b63b, 0x55e5d15e, + 0x47507eb0, 0xffec19d5, 0x623b216c, 0xda874609, 0xc832e9e7, + 0x708e8e82, 0x28ed9ed4, 0x9051f9b1, 0x82e4565f, 0x3a58313a, + 0xa78f0983, 0x1f336ee6, 0x0d86c108, 0xb53aa66d, 0xbd40e1a4, + 0x05fc86c1, 0x1749292f, 0xaff54e4a, 0x322276f3, 0x8a9e1196, + 0x982bbe78, 0x2097d91d, 0x78f4c94b, 0xc048ae2e, 0xd2fd01c0, + 0x6a4166a5, 0xf7965e1c, 0x4f2a3979, 0x5d9f9697, 0xe523f1f2, + 0x4d6b1905, 0xf5d77e60, 0xe762d18e, 0x5fdeb6eb, 0xc2098e52, + 0x7ab5e937, 0x680046d9, 0xd0bc21bc, 0x88df31ea, 0x3063568f, + 0x22d6f961, 0x9a6a9e04, 0x07bda6bd, 0xbf01c1d8, 0xadb46e36, + 0x15080953, 0x1d724e9a, 0xa5ce29ff, 0xb77b8611, 0x0fc7e174, + 0x9210d9cd, 0x2aacbea8, 0x38191146, 0x80a57623, 0xd8c66675, + 0x607a0110, 0x72cfaefe, 0xca73c99b, 0x57a4f122, 0xef189647, + 0xfdad39a9, 0x45115ecc, 0x764dee06, 0xcef18963, 0xdc44268d, + 0x64f841e8, 0xf92f7951, 0x41931e34, 0x5326b1da, 0xeb9ad6bf, + 0xb3f9c6e9, 0x0b45a18c, 0x19f00e62, 0xa14c6907, 0x3c9b51be, + 0x842736db, 0x96929935, 0x2e2efe50, 0x2654b999, 0x9ee8defc, + 0x8c5d7112, 0x34e11677, 0xa9362ece, 0x118a49ab, 0x033fe645, + 0xbb838120, 0xe3e09176, 0x5b5cf613, 0x49e959fd, 0xf1553e98, + 0x6c820621, 0xd43e6144, 0xc68bceaa, 0x7e37a9cf, 0xd67f4138, + 0x6ec3265d, 0x7c7689b3, 0xc4caeed6, 0x591dd66f, 0xe1a1b10a, + 0xf3141ee4, 0x4ba87981, 0x13cb69d7, 0xab770eb2, 0xb9c2a15c, + 0x017ec639, 0x9ca9fe80, 0x241599e5, 0x36a0360b, 0x8e1c516e, + 0x866616a7, 0x3eda71c2, 0x2c6fde2c, 0x94d3b949, 0x090481f0, + 0xb1b8e695, 0xa30d497b, 0x1bb12e1e, 0x43d23e48, 0xfb6e592d, + 0xe9dbf6c3, 0x516791a6, 0xccb0a91f, 0x740cce7a, 0x66b96194, + 0xde0506f1}, + {0x00000000, 0x01c26a37, 0x0384d46e, 0x0246be59, 0x0709a8dc, + 0x06cbc2eb, 0x048d7cb2, 0x054f1685, 0x0e1351b8, 0x0fd13b8f, + 0x0d9785d6, 0x0c55efe1, 0x091af964, 0x08d89353, 0x0a9e2d0a, + 0x0b5c473d, 0x1c26a370, 0x1de4c947, 0x1fa2771e, 0x1e601d29, + 0x1b2f0bac, 0x1aed619b, 0x18abdfc2, 0x1969b5f5, 0x1235f2c8, + 0x13f798ff, 0x11b126a6, 0x10734c91, 0x153c5a14, 0x14fe3023, + 0x16b88e7a, 0x177ae44d, 0x384d46e0, 0x398f2cd7, 0x3bc9928e, + 0x3a0bf8b9, 0x3f44ee3c, 0x3e86840b, 0x3cc03a52, 0x3d025065, + 0x365e1758, 0x379c7d6f, 0x35dac336, 0x3418a901, 0x3157bf84, + 0x3095d5b3, 0x32d36bea, 0x331101dd, 0x246be590, 0x25a98fa7, + 0x27ef31fe, 0x262d5bc9, 0x23624d4c, 0x22a0277b, 0x20e69922, + 0x2124f315, 0x2a78b428, 0x2bbade1f, 0x29fc6046, 0x283e0a71, + 0x2d711cf4, 0x2cb376c3, 0x2ef5c89a, 0x2f37a2ad, 0x709a8dc0, + 0x7158e7f7, 0x731e59ae, 0x72dc3399, 0x7793251c, 0x76514f2b, + 0x7417f172, 0x75d59b45, 0x7e89dc78, 0x7f4bb64f, 0x7d0d0816, + 0x7ccf6221, 0x798074a4, 0x78421e93, 0x7a04a0ca, 0x7bc6cafd, + 0x6cbc2eb0, 0x6d7e4487, 0x6f38fade, 0x6efa90e9, 0x6bb5866c, + 0x6a77ec5b, 0x68315202, 0x69f33835, 0x62af7f08, 0x636d153f, + 0x612bab66, 0x60e9c151, 0x65a6d7d4, 0x6464bde3, 0x662203ba, + 0x67e0698d, 0x48d7cb20, 0x4915a117, 0x4b531f4e, 0x4a917579, + 0x4fde63fc, 0x4e1c09cb, 0x4c5ab792, 0x4d98dda5, 0x46c49a98, + 0x4706f0af, 0x45404ef6, 0x448224c1, 0x41cd3244, 0x400f5873, + 0x4249e62a, 0x438b8c1d, 0x54f16850, 0x55330267, 0x5775bc3e, + 0x56b7d609, 0x53f8c08c, 0x523aaabb, 0x507c14e2, 0x51be7ed5, + 0x5ae239e8, 0x5b2053df, 0x5966ed86, 0x58a487b1, 0x5deb9134, + 0x5c29fb03, 0x5e6f455a, 0x5fad2f6d, 0xe1351b80, 0xe0f771b7, + 0xe2b1cfee, 0xe373a5d9, 0xe63cb35c, 0xe7fed96b, 0xe5b86732, + 0xe47a0d05, 0xef264a38, 0xeee4200f, 0xeca29e56, 0xed60f461, + 0xe82fe2e4, 0xe9ed88d3, 0xebab368a, 0xea695cbd, 0xfd13b8f0, + 0xfcd1d2c7, 0xfe976c9e, 0xff5506a9, 0xfa1a102c, 0xfbd87a1b, + 0xf99ec442, 0xf85cae75, 0xf300e948, 0xf2c2837f, 0xf0843d26, + 0xf1465711, 0xf4094194, 0xf5cb2ba3, 0xf78d95fa, 0xf64fffcd, + 0xd9785d60, 0xd8ba3757, 0xdafc890e, 0xdb3ee339, 0xde71f5bc, + 0xdfb39f8b, 0xddf521d2, 0xdc374be5, 0xd76b0cd8, 0xd6a966ef, + 0xd4efd8b6, 0xd52db281, 0xd062a404, 0xd1a0ce33, 0xd3e6706a, + 0xd2241a5d, 0xc55efe10, 0xc49c9427, 0xc6da2a7e, 0xc7184049, + 0xc25756cc, 0xc3953cfb, 0xc1d382a2, 0xc011e895, 0xcb4dafa8, + 0xca8fc59f, 0xc8c97bc6, 0xc90b11f1, 0xcc440774, 0xcd866d43, + 0xcfc0d31a, 0xce02b92d, 0x91af9640, 0x906dfc77, 0x922b422e, + 0x93e92819, 0x96a63e9c, 0x976454ab, 0x9522eaf2, 0x94e080c5, + 0x9fbcc7f8, 0x9e7eadcf, 0x9c381396, 0x9dfa79a1, 0x98b56f24, + 0x99770513, 0x9b31bb4a, 0x9af3d17d, 0x8d893530, 0x8c4b5f07, + 0x8e0de15e, 0x8fcf8b69, 0x8a809dec, 0x8b42f7db, 0x89044982, + 0x88c623b5, 0x839a6488, 0x82580ebf, 0x801eb0e6, 0x81dcdad1, + 0x8493cc54, 0x8551a663, 0x8717183a, 0x86d5720d, 0xa9e2d0a0, + 0xa820ba97, 0xaa6604ce, 0xaba46ef9, 0xaeeb787c, 0xaf29124b, + 0xad6fac12, 0xacadc625, 0xa7f18118, 0xa633eb2f, 0xa4755576, + 0xa5b73f41, 0xa0f829c4, 0xa13a43f3, 0xa37cfdaa, 0xa2be979d, + 0xb5c473d0, 0xb40619e7, 0xb640a7be, 0xb782cd89, 0xb2cddb0c, + 0xb30fb13b, 0xb1490f62, 0xb08b6555, 0xbbd72268, 0xba15485f, + 0xb853f606, 0xb9919c31, 0xbcde8ab4, 0xbd1ce083, 0xbf5a5eda, + 0xbe9834ed}, + {0x00000000, 0x191b3141, 0x32366282, 0x2b2d53c3, 0x646cc504, + 0x7d77f445, 0x565aa786, 0x4f4196c7, 0xc8d98a08, 0xd1c2bb49, + 0xfaefe88a, 0xe3f4d9cb, 0xacb54f0c, 0xb5ae7e4d, 0x9e832d8e, + 0x87981ccf, 0x4ac21251, 0x53d92310, 0x78f470d3, 0x61ef4192, + 0x2eaed755, 0x37b5e614, 0x1c98b5d7, 0x05838496, 0x821b9859, + 0x9b00a918, 0xb02dfadb, 0xa936cb9a, 0xe6775d5d, 0xff6c6c1c, + 0xd4413fdf, 0xcd5a0e9e, 0x958424a2, 0x8c9f15e3, 0xa7b24620, + 0xbea97761, 0xf1e8e1a6, 0xe8f3d0e7, 0xc3de8324, 0xdac5b265, + 0x5d5daeaa, 0x44469feb, 0x6f6bcc28, 0x7670fd69, 0x39316bae, + 0x202a5aef, 0x0b07092c, 0x121c386d, 0xdf4636f3, 0xc65d07b2, + 0xed705471, 0xf46b6530, 0xbb2af3f7, 0xa231c2b6, 0x891c9175, + 0x9007a034, 0x179fbcfb, 0x0e848dba, 0x25a9de79, 0x3cb2ef38, + 0x73f379ff, 0x6ae848be, 0x41c51b7d, 0x58de2a3c, 0xf0794f05, + 0xe9627e44, 0xc24f2d87, 0xdb541cc6, 0x94158a01, 0x8d0ebb40, + 0xa623e883, 0xbf38d9c2, 0x38a0c50d, 0x21bbf44c, 0x0a96a78f, + 0x138d96ce, 0x5ccc0009, 0x45d73148, 0x6efa628b, 0x77e153ca, + 0xbabb5d54, 0xa3a06c15, 0x888d3fd6, 0x91960e97, 0xded79850, + 0xc7cca911, 0xece1fad2, 0xf5facb93, 0x7262d75c, 0x6b79e61d, + 0x4054b5de, 0x594f849f, 0x160e1258, 0x0f152319, 0x243870da, + 0x3d23419b, 0x65fd6ba7, 0x7ce65ae6, 0x57cb0925, 0x4ed03864, + 0x0191aea3, 0x188a9fe2, 0x33a7cc21, 0x2abcfd60, 0xad24e1af, + 0xb43fd0ee, 0x9f12832d, 0x8609b26c, 0xc94824ab, 0xd05315ea, + 0xfb7e4629, 0xe2657768, 0x2f3f79f6, 0x362448b7, 0x1d091b74, + 0x04122a35, 0x4b53bcf2, 0x52488db3, 0x7965de70, 0x607eef31, + 0xe7e6f3fe, 0xfefdc2bf, 0xd5d0917c, 0xcccba03d, 0x838a36fa, + 0x9a9107bb, 0xb1bc5478, 0xa8a76539, 0x3b83984b, 0x2298a90a, + 0x09b5fac9, 0x10aecb88, 0x5fef5d4f, 0x46f46c0e, 0x6dd93fcd, + 0x74c20e8c, 0xf35a1243, 0xea412302, 0xc16c70c1, 0xd8774180, + 0x9736d747, 0x8e2de606, 0xa500b5c5, 0xbc1b8484, 0x71418a1a, + 0x685abb5b, 0x4377e898, 0x5a6cd9d9, 0x152d4f1e, 0x0c367e5f, + 0x271b2d9c, 0x3e001cdd, 0xb9980012, 0xa0833153, 0x8bae6290, + 0x92b553d1, 0xddf4c516, 0xc4eff457, 0xefc2a794, 0xf6d996d5, + 0xae07bce9, 0xb71c8da8, 0x9c31de6b, 0x852aef2a, 0xca6b79ed, + 0xd37048ac, 0xf85d1b6f, 0xe1462a2e, 0x66de36e1, 0x7fc507a0, + 0x54e85463, 0x4df36522, 0x02b2f3e5, 0x1ba9c2a4, 0x30849167, + 0x299fa026, 0xe4c5aeb8, 0xfdde9ff9, 0xd6f3cc3a, 0xcfe8fd7b, + 0x80a96bbc, 0x99b25afd, 0xb29f093e, 0xab84387f, 0x2c1c24b0, + 0x350715f1, 0x1e2a4632, 0x07317773, 0x4870e1b4, 0x516bd0f5, + 0x7a468336, 0x635db277, 0xcbfad74e, 0xd2e1e60f, 0xf9ccb5cc, + 0xe0d7848d, 0xaf96124a, 0xb68d230b, 0x9da070c8, 0x84bb4189, + 0x03235d46, 0x1a386c07, 0x31153fc4, 0x280e0e85, 0x674f9842, + 0x7e54a903, 0x5579fac0, 0x4c62cb81, 0x8138c51f, 0x9823f45e, + 0xb30ea79d, 0xaa1596dc, 0xe554001b, 0xfc4f315a, 0xd7626299, + 0xce7953d8, 0x49e14f17, 0x50fa7e56, 0x7bd72d95, 0x62cc1cd4, + 0x2d8d8a13, 0x3496bb52, 0x1fbbe891, 0x06a0d9d0, 0x5e7ef3ec, + 0x4765c2ad, 0x6c48916e, 0x7553a02f, 0x3a1236e8, 0x230907a9, + 0x0824546a, 0x113f652b, 0x96a779e4, 0x8fbc48a5, 0xa4911b66, + 0xbd8a2a27, 0xf2cbbce0, 0xebd08da1, 0xc0fdde62, 0xd9e6ef23, + 0x14bce1bd, 0x0da7d0fc, 0x268a833f, 0x3f91b27e, 0x70d024b9, + 0x69cb15f8, 0x42e6463b, 0x5bfd777a, 0xdc656bb5, 0xc57e5af4, + 0xee530937, 0xf7483876, 0xb809aeb1, 0xa1129ff0, 0x8a3fcc33, + 0x9324fd72}, + {0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, + 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, + 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, + 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856, + 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, + 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, + 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a, + 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, + 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, + 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, + 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e, + 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, + 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, + 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, + 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, + 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010, + 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, + 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, + 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, + 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344, + 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, + 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, + 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c, + 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, + 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, + 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, + 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c, + 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, + 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, + 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278, + 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, + 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66, + 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, + 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, + 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, + 0x2d02ef8d}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x96300777, 0x2c610eee, 0xba510999, 0x19c46d07, + 0x8ff46a70, 0x35a563e9, 0xa395649e, 0x3288db0e, 0xa4b8dc79, + 0x1ee9d5e0, 0x88d9d297, 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, + 0x911dbf90, 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, 0x56986c13, + 0xc0a86b64, 0x7af962fd, 0xecc9658a, 0x4f5c0114, 0xd96c0663, + 0x633d0ffa, 0xf50d088d, 0xc8206e3b, 0x5e10694c, 0xe44160d5, + 0x727167a2, 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, 0xe36cd832, + 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, 0xac30d926, 0x3a00de51, + 0x8051d7c8, 0x1661d0bf, 0xb5f4b421, 0x23c4b356, 0x9995bacf, + 0x0fa5bdb8, 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, 0x9041dc76, + 0x0671db01, 0xbc20d298, 0x2a10d5ef, 0x8985b171, 0x1fb5b606, + 0xa5e4bf9f, 0x33d4b8e8, 0xa2c90778, 0x34f9000f, 0x8ea80996, + 0x18980ee1, 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, 0xed95066c, + 0x7ba5011b, 0xc1f40882, 0x57c40ff5, 0xc6d9b065, 0x50e9b712, + 0xeab8be8b, 0x7c88b9fc, 0xdf1ddd62, 0x492dda15, 0xf37cd38c, + 0x654cd4fb, 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, 0x6ae96943, + 0xfcd96e34, 0x468867ad, 0xd0b860da, 0x732d0444, 0xe51d0333, + 0x5f4c0aaa, 0xc97c0ddd, 0x3c710550, 0xaa410227, 0x10100bbe, + 0x86200cc9, 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, 0x173db359, + 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, 0x2083b8ed, 0xb6b3bf9a, + 0x0ce2b603, 0x9ad2b174, 0x3947d5ea, 0xaf77d29d, 0x1526db04, + 0x8316dc73, 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, 0x44930ff0, + 0xd2a30887, 0x68f2011e, 0xfec20669, 0x5d5762f7, 0xcb676580, + 0x71366c19, 0xe7066b6e, 0x761bd4fe, 0xe02bd389, 0x5a7ada10, + 0xcc4add67, 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, 0xf167bbd1, + 0x6757bca6, 0xdd06b53f, 0x4b36b248, 0xda2b0dd8, 0x4c1b0aaf, + 0xf64a0336, 0x607a0441, 0xc3ef60df, 0x55df67a8, 0xef8e6e31, + 0x79be6946, 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, 0xbe3bbac5, + 0x280bbdb2, 0x925ab42b, 0x046ab35c, 0xa7ffd7c2, 0x31cfd0b5, + 0x8b9ed92c, 0x1daede5b, 0xb0c2649b, 0x26f263ec, 0x9ca36a75, + 0x0a936d02, 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, 0x9b8ed292, + 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, 0xd4d2d386, 0x42e2d4f1, + 0xf8b3dd68, 0x6e83da1f, 0xcd16be81, 0x5b26b9f6, 0xe177b06f, + 0x7747b718, 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, 0x78e20aa0, + 0xeed20dd7, 0x5483044e, 0xc2b30339, 0x612667a7, 0xf71660d0, + 0x4d476949, 0xdb776e3e, 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, + 0xf03bd837, 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, 0x0536d0ba, + 0x9306d7cd, 0x2957de54, 0xbf67d923, 0x2e7a66b3, 0xb84a61c4, + 0x021b685d, 0x942b6f2a, 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, + 0x8def022d}, + {0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, 0x04c56c64, + 0x45f4777d, 0x86a75a56, 0xc796414f, 0x088ad9c8, 0x49bbc2d1, + 0x8ae8effa, 0xcbd9f4e3, 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, + 0xcf1c9887, 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, 0x59981b82, + 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, 0x5d5d77e6, 0x1c6c6cff, + 0xdf3f41d4, 0x9e0e5acd, 0xa2248495, 0xe3159f8c, 0x2046b2a7, + 0x6177a9be, 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, 0xae6b3139, + 0xef5a2a20, 0x2c09070b, 0x6d381c12, 0xf33646df, 0xb2075dc6, + 0x715470ed, 0x30656bf4, 0xf7f32abb, 0xb6c231a2, 0x75911c89, + 0x34a00790, 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, 0x054f79f0, + 0x447e62e9, 0x872d4fc2, 0xc61c54db, 0x018a1594, 0x40bb0e8d, + 0x83e823a6, 0xc2d938bf, 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, + 0xce968d13, 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, 0x5098d7de, + 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, 0x5cd76272, 0x1de6796b, + 0xdeb55440, 0x9f844f59, 0x58120e16, 0x1923150f, 0xda703824, + 0x9b41233d, 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, 0xafe124ad, + 0xeed03fb4, 0x2d83129f, 0x6cb20986, 0xab2448c9, 0xea1553d0, + 0x29467efb, 0x687765e2, 0xf6793f2f, 0xb7482436, 0x741b091d, + 0x352a1204, 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, 0xfa368a83, + 0xbb07919a, 0x7854bcb1, 0x3965a7a8, 0x4b98833b, 0x0aa99822, + 0xc9fab509, 0x88cbae10, 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, + 0x8c0ec274, 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, 0x1a8a4171, + 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, 0x1e4f2d15, 0x5f7e360c, + 0x9c2d1b27, 0xdd1c003e, 0x120098b9, 0x533183a0, 0x9062ae8b, + 0xd153b592, 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, 0xed796bca, + 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, 0xe136de66, 0xa007c57f, + 0x6354e854, 0x2265f34d, 0xe5f3b202, 0xa4c2a91b, 0x67918430, + 0x26a09f29, 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, 0xb0241c2c, + 0xf1150735, 0x32462a1e, 0x73773107, 0xb4e17048, 0xf5d06b51, + 0x3683467a, 0x77b25d63, 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, + 0x8d84d7e0, 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, 0x42984f67, + 0x03a9547e, 0xc0fa7955, 0x81cb624c, 0x1fc53881, 0x5ef42398, + 0x9da70eb3, 0xdc9615aa, 0x1b0054e5, 0x5a314ffc, 0x996262d7, + 0xd85379ce, 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, 0xecf37e5e, + 0xadc26547, 0x6e91486c, 0x2fa05375, 0xe836123a, 0xa9070923, + 0x6a542408, 0x2b653f11, 0xe479a796, 0xa548bc8f, 0x661b91a4, + 0x272a8abd, 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, 0xb924d070, + 0xf815cb69, 0x3b46e642, 0x7a77fd5b, 0xb56b65dc, 0xf45a7ec5, + 0x370953ee, 0x763848f7, 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, + 0x72fd2493}, + {0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, 0xdca80907, + 0xebc2cb06, 0xb27c8d04, 0x85164f05, 0xb851130e, 0x8f3bd10f, + 0xd685970d, 0xe1ef550c, 0x64f91a09, 0x5393d808, 0x0a2d9e0a, + 0x3d475c0b, 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, 0xc8f23512, + 0xff98f713, 0xa626b111, 0x914c7310, 0x145a3c15, 0x2330fe14, + 0x7a8eb816, 0x4de47a17, 0xe0464d38, 0xd72c8f39, 0x8e92c93b, + 0xb9f80b3a, 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, 0x84bf5731, + 0xb3d59530, 0xea6bd332, 0xdd011133, 0x90e56b24, 0xa78fa925, + 0xfe31ef27, 0xc95b2d26, 0x4c4d6223, 0x7b27a022, 0x2299e620, + 0x15f32421, 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, 0xc08d9a70, + 0xf7e75871, 0xae591e73, 0x9933dc72, 0x1c259377, 0x2b4f5176, + 0x72f11774, 0x459bd575, 0x78dc897e, 0x4fb64b7f, 0x16080d7d, + 0x2162cf7c, 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, 0x6c86b56b, + 0x5bec776a, 0x02523168, 0x3538f369, 0x087faf62, 0x3f156d63, + 0x66ab2b61, 0x51c1e960, 0xd4d7a665, 0xe3bd6464, 0xba032266, + 0x8d69e067, 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, 0x989ac446, + 0xaff00647, 0xf64e4045, 0xc1248244, 0x4432cd41, 0x73580f40, + 0x2ae64942, 0x1d8c8b43, 0x5068f154, 0x67023355, 0x3ebc7557, + 0x09d6b756, 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, 0x3491eb5d, + 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, 0x801b35e1, 0xb771f7e0, + 0xeecfb1e2, 0xd9a573e3, 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, + 0x050d7ae4, 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, 0xf0b813fd, + 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, 0x2c101afa, 0x1b7ad8fb, + 0x42c49ef9, 0x75ae5cf8, 0x48e900f3, 0x7f83c2f2, 0x263d84f0, + 0x115746f1, 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, 0xbcf571de, + 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, 0xd80c6bd7, 0xef66a9d6, + 0xb6d8efd4, 0x81b22dd5, 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, + 0x5d1a24d2, 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, 0xa8af4dcb, + 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, 0x740744cc, 0x436d86cd, + 0x1ad3c0cf, 0x2db902ce, 0x4096af91, 0x77fc6d90, 0x2e422b92, + 0x1928e993, 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, 0x246fb598, + 0x13057799, 0x4abb319b, 0x7dd1f39a, 0x3035898d, 0x075f4b8c, + 0x5ee10d8e, 0x698bcf8f, 0xec9d808a, 0xdbf7428b, 0x82490489, + 0xb523c688, 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, 0xa0d0e2a9, + 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, 0x7c78ebae, 0x4b1229af, + 0x12ac6fad, 0x25c6adac, 0x1881f1a7, 0x2feb33a6, 0x765575a4, + 0x413fb7a5, 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, 0x0cdbcdb2, + 0x3bb10fb3, 0x620f49b1, 0x55658bb0, 0x6822d7bb, 0x5f4815ba, + 0x06f653b8, 0x319c91b9, 0xb48adebc, 0x83e01cbd, 0xda5e5abf, + 0xed3498be}, + {0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, 0x5797628f, + 0x32f0de37, 0xdc5f6b25, 0xb938d79d, 0xef28b4c5, 0x8a4f087d, + 0x64e0bd6f, 0x018701d7, 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, + 0x56106358, 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, 0x707fad95, + 0x1518112d, 0xfbb7a43f, 0x9ed01887, 0x27e8cf1a, 0x428f73a2, + 0xac20c6b0, 0xc9477a08, 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, + 0xd00087b2, 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, 0x8610e4ea, + 0xe3775852, 0x0dd8ed40, 0x68bf51f8, 0xa1f82bf0, 0xc49f9748, + 0x2a30225a, 0x4f579ee2, 0xf66f497f, 0x9308f5c7, 0x7da740d5, + 0x18c0fc6d, 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, 0x3d58149b, + 0x583fa823, 0xb6901d31, 0xd3f7a189, 0x6acf7614, 0x0fa8caac, + 0xe1077fbe, 0x8460c306, 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, + 0x3cdf154c, 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, 0xf5986f44, + 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, 0x4d27b90e, 0x284005b6, + 0xc6efb0a4, 0xa3880c1c, 0x1ab0db81, 0x7fd76739, 0x9178d22b, + 0xf41f6e93, 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, 0xecdf92fe, + 0x89b82e46, 0x67179b54, 0x027027ec, 0xbb48f071, 0xde2f4cc9, + 0x3080f9db, 0x55e74563, 0x9ca03f6b, 0xf9c783d3, 0x176836c1, + 0x720f8a79, 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, 0x241fe921, + 0x41785599, 0xafd7e08b, 0xcab05c33, 0x3bb659ed, 0x5ed1e555, + 0xb07e5047, 0xd519ecff, 0x6c213b62, 0x094687da, 0xe7e932c8, + 0x828e8e70, 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, 0xa4e140bd, + 0xc186fc05, 0x2f294917, 0x4a4ef5af, 0xf3762232, 0x96119e8a, + 0x78be2b98, 0x1dd99720, 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, + 0xa566416a, 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, 0x528e09c2, + 0x37e9b57a, 0xd9460068, 0xbc21bcd0, 0xea31df88, 0x8f566330, + 0x61f9d622, 0x049e6a9a, 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, + 0x53090815, 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, 0x7566c6d8, + 0x10017a60, 0xfeaecf72, 0x9bc973ca, 0x22f1a457, 0x479618ef, + 0xa939adfd, 0xcc5e1145, 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, + 0xe841f864, 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, 0xbe519b3c, + 0xdb362784, 0x35999296, 0x50fe2e2e, 0x99b95426, 0xfcdee89e, + 0x12715d8c, 0x7716e134, 0xce2e36a9, 0xab498a11, 0x45e63f03, + 0x208183bb, 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, 0x38417fd6, + 0x5d26c36e, 0xb389767c, 0xd6eecac4, 0x6fd61d59, 0x0ab1a1e1, + 0xe41e14f3, 0x8179a84b, 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, + 0x39c67e01, 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, 0xf0810409, + 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, 0x483ed243, 0x2d596efb, + 0xc3f6dbe9, 0xa6916751, 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, + 0xf10605de}}; + +#endif /* W */ + +#endif /* N == 1 */ +#if N == 2 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}, + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43147b1700000000, 0x8628f62e00000000, + 0xc53c8d3900000000, 0x0c51ec5d00000000, 0x4f45974a00000000, + 0x8a791a7300000000, 0xc96d616400000000, 0x18a2d8bb00000000, + 0x5bb6a3ac00000000, 0x9e8a2e9500000000, 0xdd9e558200000000, + 0x14f334e600000000, 0x57e74ff100000000, 0x92dbc2c800000000, + 0xd1cfb9df00000000, 0x7142c0ac00000000, 0x3256bbbb00000000, + 0xf76a368200000000, 0xb47e4d9500000000, 0x7d132cf100000000, + 0x3e0757e600000000, 0xfb3bdadf00000000, 0xb82fa1c800000000, + 0x69e0181700000000, 0x2af4630000000000, 0xefc8ee3900000000, + 0xacdc952e00000000, 0x65b1f44a00000000, 0x26a58f5d00000000, + 0xe399026400000000, 0xa08d797300000000, 0xa382f18200000000, + 0xe0968a9500000000, 0x25aa07ac00000000, 0x66be7cbb00000000, + 0xafd31ddf00000000, 0xecc766c800000000, 0x29fbebf100000000, + 0x6aef90e600000000, 0xbb20293900000000, 0xf834522e00000000, + 0x3d08df1700000000, 0x7e1ca40000000000, 0xb771c56400000000, + 0xf465be7300000000, 0x3159334a00000000, 0x724d485d00000000, + 0xd2c0312e00000000, 0x91d44a3900000000, 0x54e8c70000000000, + 0x17fcbc1700000000, 0xde91dd7300000000, 0x9d85a66400000000, + 0x58b92b5d00000000, 0x1bad504a00000000, 0xca62e99500000000, + 0x8976928200000000, 0x4c4a1fbb00000000, 0x0f5e64ac00000000, + 0xc63305c800000000, 0x85277edf00000000, 0x401bf3e600000000, + 0x030f88f100000000, 0x070392de00000000, 0x4417e9c900000000, + 0x812b64f000000000, 0xc23f1fe700000000, 0x0b527e8300000000, + 0x4846059400000000, 0x8d7a88ad00000000, 0xce6ef3ba00000000, + 0x1fa14a6500000000, 0x5cb5317200000000, 0x9989bc4b00000000, + 0xda9dc75c00000000, 0x13f0a63800000000, 0x50e4dd2f00000000, + 0x95d8501600000000, 0xd6cc2b0100000000, 0x7641527200000000, + 0x3555296500000000, 0xf069a45c00000000, 0xb37ddf4b00000000, + 0x7a10be2f00000000, 0x3904c53800000000, 0xfc38480100000000, + 0xbf2c331600000000, 0x6ee38ac900000000, 0x2df7f1de00000000, + 0xe8cb7ce700000000, 0xabdf07f000000000, 0x62b2669400000000, + 0x21a61d8300000000, 0xe49a90ba00000000, 0xa78eebad00000000, + 0xa481635c00000000, 0xe795184b00000000, 0x22a9957200000000, + 0x61bdee6500000000, 0xa8d08f0100000000, 0xebc4f41600000000, + 0x2ef8792f00000000, 0x6dec023800000000, 0xbc23bbe700000000, + 0xff37c0f000000000, 0x3a0b4dc900000000, 0x791f36de00000000, + 0xb07257ba00000000, 0xf3662cad00000000, 0x365aa19400000000, + 0x754eda8300000000, 0xd5c3a3f000000000, 0x96d7d8e700000000, + 0x53eb55de00000000, 0x10ff2ec900000000, 0xd9924fad00000000, + 0x9a8634ba00000000, 0x5fbab98300000000, 0x1caec29400000000, + 0xcd617b4b00000000, 0x8e75005c00000000, 0x4b498d6500000000, + 0x085df67200000000, 0xc130971600000000, 0x8224ec0100000000, + 0x4718613800000000, 0x040c1a2f00000000, 0x4f00556600000000, + 0x0c142e7100000000, 0xc928a34800000000, 0x8a3cd85f00000000, + 0x4351b93b00000000, 0x0045c22c00000000, 0xc5794f1500000000, + 0x866d340200000000, 0x57a28ddd00000000, 0x14b6f6ca00000000, + 0xd18a7bf300000000, 0x929e00e400000000, 0x5bf3618000000000, + 0x18e71a9700000000, 0xdddb97ae00000000, 0x9ecfecb900000000, + 0x3e4295ca00000000, 0x7d56eedd00000000, 0xb86a63e400000000, + 0xfb7e18f300000000, 0x3213799700000000, 0x7107028000000000, + 0xb43b8fb900000000, 0xf72ff4ae00000000, 0x26e04d7100000000, + 0x65f4366600000000, 0xa0c8bb5f00000000, 0xe3dcc04800000000, + 0x2ab1a12c00000000, 0x69a5da3b00000000, 0xac99570200000000, + 0xef8d2c1500000000, 0xec82a4e400000000, 0xaf96dff300000000, + 0x6aaa52ca00000000, 0x29be29dd00000000, 0xe0d348b900000000, + 0xa3c733ae00000000, 0x66fbbe9700000000, 0x25efc58000000000, + 0xf4207c5f00000000, 0xb734074800000000, 0x72088a7100000000, + 0x311cf16600000000, 0xf871900200000000, 0xbb65eb1500000000, + 0x7e59662c00000000, 0x3d4d1d3b00000000, 0x9dc0644800000000, + 0xded41f5f00000000, 0x1be8926600000000, 0x58fce97100000000, + 0x9191881500000000, 0xd285f30200000000, 0x17b97e3b00000000, + 0x54ad052c00000000, 0x8562bcf300000000, 0xc676c7e400000000, + 0x034a4add00000000, 0x405e31ca00000000, 0x893350ae00000000, + 0xca272bb900000000, 0x0f1ba68000000000, 0x4c0fdd9700000000, + 0x4803c7b800000000, 0x0b17bcaf00000000, 0xce2b319600000000, + 0x8d3f4a8100000000, 0x44522be500000000, 0x074650f200000000, + 0xc27addcb00000000, 0x816ea6dc00000000, 0x50a11f0300000000, + 0x13b5641400000000, 0xd689e92d00000000, 0x959d923a00000000, + 0x5cf0f35e00000000, 0x1fe4884900000000, 0xdad8057000000000, + 0x99cc7e6700000000, 0x3941071400000000, 0x7a557c0300000000, + 0xbf69f13a00000000, 0xfc7d8a2d00000000, 0x3510eb4900000000, + 0x7604905e00000000, 0xb3381d6700000000, 0xf02c667000000000, + 0x21e3dfaf00000000, 0x62f7a4b800000000, 0xa7cb298100000000, + 0xe4df529600000000, 0x2db233f200000000, 0x6ea648e500000000, + 0xab9ac5dc00000000, 0xe88ebecb00000000, 0xeb81363a00000000, + 0xa8954d2d00000000, 0x6da9c01400000000, 0x2ebdbb0300000000, + 0xe7d0da6700000000, 0xa4c4a17000000000, 0x61f82c4900000000, + 0x22ec575e00000000, 0xf323ee8100000000, 0xb037959600000000, + 0x750b18af00000000, 0x361f63b800000000, 0xff7202dc00000000, + 0xbc6679cb00000000, 0x795af4f200000000, 0x3a4e8fe500000000, + 0x9ac3f69600000000, 0xd9d78d8100000000, 0x1ceb00b800000000, + 0x5fff7baf00000000, 0x96921acb00000000, 0xd58661dc00000000, + 0x10baece500000000, 0x53ae97f200000000, 0x82612e2d00000000, + 0xc175553a00000000, 0x0449d80300000000, 0x475da31400000000, + 0x8e30c27000000000, 0xcd24b96700000000, 0x0818345e00000000, + 0x4b0c4f4900000000}, + {0x0000000000000000, 0x3e6bc2ef00000000, 0x3dd0f50400000000, + 0x03bb37eb00000000, 0x7aa0eb0900000000, 0x44cb29e600000000, + 0x47701e0d00000000, 0x791bdce200000000, 0xf440d71300000000, + 0xca2b15fc00000000, 0xc990221700000000, 0xf7fbe0f800000000, + 0x8ee03c1a00000000, 0xb08bfef500000000, 0xb330c91e00000000, + 0x8d5b0bf100000000, 0xe881ae2700000000, 0xd6ea6cc800000000, + 0xd5515b2300000000, 0xeb3a99cc00000000, 0x9221452e00000000, + 0xac4a87c100000000, 0xaff1b02a00000000, 0x919a72c500000000, + 0x1cc1793400000000, 0x22aabbdb00000000, 0x21118c3000000000, + 0x1f7a4edf00000000, 0x6661923d00000000, 0x580a50d200000000, + 0x5bb1673900000000, 0x65daa5d600000000, 0xd0035d4f00000000, + 0xee689fa000000000, 0xedd3a84b00000000, 0xd3b86aa400000000, + 0xaaa3b64600000000, 0x94c874a900000000, 0x9773434200000000, + 0xa91881ad00000000, 0x24438a5c00000000, 0x1a2848b300000000, + 0x19937f5800000000, 0x27f8bdb700000000, 0x5ee3615500000000, + 0x6088a3ba00000000, 0x6333945100000000, 0x5d5856be00000000, + 0x3882f36800000000, 0x06e9318700000000, 0x0552066c00000000, + 0x3b39c48300000000, 0x4222186100000000, 0x7c49da8e00000000, + 0x7ff2ed6500000000, 0x41992f8a00000000, 0xccc2247b00000000, + 0xf2a9e69400000000, 0xf112d17f00000000, 0xcf79139000000000, + 0xb662cf7200000000, 0x88090d9d00000000, 0x8bb23a7600000000, + 0xb5d9f89900000000, 0xa007ba9e00000000, 0x9e6c787100000000, + 0x9dd74f9a00000000, 0xa3bc8d7500000000, 0xdaa7519700000000, + 0xe4cc937800000000, 0xe777a49300000000, 0xd91c667c00000000, + 0x54476d8d00000000, 0x6a2caf6200000000, 0x6997988900000000, + 0x57fc5a6600000000, 0x2ee7868400000000, 0x108c446b00000000, + 0x1337738000000000, 0x2d5cb16f00000000, 0x488614b900000000, + 0x76edd65600000000, 0x7556e1bd00000000, 0x4b3d235200000000, + 0x3226ffb000000000, 0x0c4d3d5f00000000, 0x0ff60ab400000000, + 0x319dc85b00000000, 0xbcc6c3aa00000000, 0x82ad014500000000, + 0x811636ae00000000, 0xbf7df44100000000, 0xc66628a300000000, + 0xf80dea4c00000000, 0xfbb6dda700000000, 0xc5dd1f4800000000, + 0x7004e7d100000000, 0x4e6f253e00000000, 0x4dd412d500000000, + 0x73bfd03a00000000, 0x0aa40cd800000000, 0x34cfce3700000000, + 0x3774f9dc00000000, 0x091f3b3300000000, 0x844430c200000000, + 0xba2ff22d00000000, 0xb994c5c600000000, 0x87ff072900000000, + 0xfee4dbcb00000000, 0xc08f192400000000, 0xc3342ecf00000000, + 0xfd5fec2000000000, 0x988549f600000000, 0xa6ee8b1900000000, + 0xa555bcf200000000, 0x9b3e7e1d00000000, 0xe225a2ff00000000, + 0xdc4e601000000000, 0xdff557fb00000000, 0xe19e951400000000, + 0x6cc59ee500000000, 0x52ae5c0a00000000, 0x51156be100000000, + 0x6f7ea90e00000000, 0x166575ec00000000, 0x280eb70300000000, + 0x2bb580e800000000, 0x15de420700000000, 0x010905e600000000, + 0x3f62c70900000000, 0x3cd9f0e200000000, 0x02b2320d00000000, + 0x7ba9eeef00000000, 0x45c22c0000000000, 0x46791beb00000000, + 0x7812d90400000000, 0xf549d2f500000000, 0xcb22101a00000000, + 0xc89927f100000000, 0xf6f2e51e00000000, 0x8fe939fc00000000, + 0xb182fb1300000000, 0xb239ccf800000000, 0x8c520e1700000000, + 0xe988abc100000000, 0xd7e3692e00000000, 0xd4585ec500000000, + 0xea339c2a00000000, 0x932840c800000000, 0xad43822700000000, + 0xaef8b5cc00000000, 0x9093772300000000, 0x1dc87cd200000000, + 0x23a3be3d00000000, 0x201889d600000000, 0x1e734b3900000000, + 0x676897db00000000, 0x5903553400000000, 0x5ab862df00000000, + 0x64d3a03000000000, 0xd10a58a900000000, 0xef619a4600000000, + 0xecdaadad00000000, 0xd2b16f4200000000, 0xabaab3a000000000, + 0x95c1714f00000000, 0x967a46a400000000, 0xa811844b00000000, + 0x254a8fba00000000, 0x1b214d5500000000, 0x189a7abe00000000, + 0x26f1b85100000000, 0x5fea64b300000000, 0x6181a65c00000000, + 0x623a91b700000000, 0x5c51535800000000, 0x398bf68e00000000, + 0x07e0346100000000, 0x045b038a00000000, 0x3a30c16500000000, + 0x432b1d8700000000, 0x7d40df6800000000, 0x7efbe88300000000, + 0x40902a6c00000000, 0xcdcb219d00000000, 0xf3a0e37200000000, + 0xf01bd49900000000, 0xce70167600000000, 0xb76bca9400000000, + 0x8900087b00000000, 0x8abb3f9000000000, 0xb4d0fd7f00000000, + 0xa10ebf7800000000, 0x9f657d9700000000, 0x9cde4a7c00000000, + 0xa2b5889300000000, 0xdbae547100000000, 0xe5c5969e00000000, + 0xe67ea17500000000, 0xd815639a00000000, 0x554e686b00000000, + 0x6b25aa8400000000, 0x689e9d6f00000000, 0x56f55f8000000000, + 0x2fee836200000000, 0x1185418d00000000, 0x123e766600000000, + 0x2c55b48900000000, 0x498f115f00000000, 0x77e4d3b000000000, + 0x745fe45b00000000, 0x4a3426b400000000, 0x332ffa5600000000, + 0x0d4438b900000000, 0x0eff0f5200000000, 0x3094cdbd00000000, + 0xbdcfc64c00000000, 0x83a404a300000000, 0x801f334800000000, + 0xbe74f1a700000000, 0xc76f2d4500000000, 0xf904efaa00000000, + 0xfabfd84100000000, 0xc4d41aae00000000, 0x710de23700000000, + 0x4f6620d800000000, 0x4cdd173300000000, 0x72b6d5dc00000000, + 0x0bad093e00000000, 0x35c6cbd100000000, 0x367dfc3a00000000, + 0x08163ed500000000, 0x854d352400000000, 0xbb26f7cb00000000, + 0xb89dc02000000000, 0x86f602cf00000000, 0xffedde2d00000000, + 0xc1861cc200000000, 0xc23d2b2900000000, 0xfc56e9c600000000, + 0x998c4c1000000000, 0xa7e78eff00000000, 0xa45cb91400000000, + 0x9a377bfb00000000, 0xe32ca71900000000, 0xdd4765f600000000, + 0xdefc521d00000000, 0xe09790f200000000, 0x6dcc9b0300000000, + 0x53a759ec00000000, 0x501c6e0700000000, 0x6e77ace800000000, + 0x176c700a00000000, 0x2907b2e500000000, 0x2abc850e00000000, + 0x14d747e100000000}, + {0x0000000000000000, 0xc0df8ec100000000, 0xc1b96c5800000000, + 0x0166e29900000000, 0x8273d9b000000000, 0x42ac577100000000, + 0x43cab5e800000000, 0x83153b2900000000, 0x45e1c3ba00000000, + 0x853e4d7b00000000, 0x8458afe200000000, 0x4487212300000000, + 0xc7921a0a00000000, 0x074d94cb00000000, 0x062b765200000000, + 0xc6f4f89300000000, 0xcbc4f6ae00000000, 0x0b1b786f00000000, + 0x0a7d9af600000000, 0xcaa2143700000000, 0x49b72f1e00000000, + 0x8968a1df00000000, 0x880e434600000000, 0x48d1cd8700000000, + 0x8e25351400000000, 0x4efabbd500000000, 0x4f9c594c00000000, + 0x8f43d78d00000000, 0x0c56eca400000000, 0xcc89626500000000, + 0xcdef80fc00000000, 0x0d300e3d00000000, 0xd78f9c8600000000, + 0x1750124700000000, 0x1636f0de00000000, 0xd6e97e1f00000000, + 0x55fc453600000000, 0x9523cbf700000000, 0x9445296e00000000, + 0x549aa7af00000000, 0x926e5f3c00000000, 0x52b1d1fd00000000, + 0x53d7336400000000, 0x9308bda500000000, 0x101d868c00000000, + 0xd0c2084d00000000, 0xd1a4ead400000000, 0x117b641500000000, + 0x1c4b6a2800000000, 0xdc94e4e900000000, 0xddf2067000000000, + 0x1d2d88b100000000, 0x9e38b39800000000, 0x5ee73d5900000000, + 0x5f81dfc000000000, 0x9f5e510100000000, 0x59aaa99200000000, + 0x9975275300000000, 0x9813c5ca00000000, 0x58cc4b0b00000000, + 0xdbd9702200000000, 0x1b06fee300000000, 0x1a601c7a00000000, + 0xdabf92bb00000000, 0xef1948d600000000, 0x2fc6c61700000000, + 0x2ea0248e00000000, 0xee7faa4f00000000, 0x6d6a916600000000, + 0xadb51fa700000000, 0xacd3fd3e00000000, 0x6c0c73ff00000000, + 0xaaf88b6c00000000, 0x6a2705ad00000000, 0x6b41e73400000000, + 0xab9e69f500000000, 0x288b52dc00000000, 0xe854dc1d00000000, + 0xe9323e8400000000, 0x29edb04500000000, 0x24ddbe7800000000, + 0xe40230b900000000, 0xe564d22000000000, 0x25bb5ce100000000, + 0xa6ae67c800000000, 0x6671e90900000000, 0x67170b9000000000, + 0xa7c8855100000000, 0x613c7dc200000000, 0xa1e3f30300000000, + 0xa085119a00000000, 0x605a9f5b00000000, 0xe34fa47200000000, + 0x23902ab300000000, 0x22f6c82a00000000, 0xe22946eb00000000, + 0x3896d45000000000, 0xf8495a9100000000, 0xf92fb80800000000, + 0x39f036c900000000, 0xbae50de000000000, 0x7a3a832100000000, + 0x7b5c61b800000000, 0xbb83ef7900000000, 0x7d7717ea00000000, + 0xbda8992b00000000, 0xbcce7bb200000000, 0x7c11f57300000000, + 0xff04ce5a00000000, 0x3fdb409b00000000, 0x3ebda20200000000, + 0xfe622cc300000000, 0xf35222fe00000000, 0x338dac3f00000000, + 0x32eb4ea600000000, 0xf234c06700000000, 0x7121fb4e00000000, + 0xb1fe758f00000000, 0xb098971600000000, 0x704719d700000000, + 0xb6b3e14400000000, 0x766c6f8500000000, 0x770a8d1c00000000, + 0xb7d503dd00000000, 0x34c038f400000000, 0xf41fb63500000000, + 0xf57954ac00000000, 0x35a6da6d00000000, 0x9f35e17700000000, + 0x5fea6fb600000000, 0x5e8c8d2f00000000, 0x9e5303ee00000000, + 0x1d4638c700000000, 0xdd99b60600000000, 0xdcff549f00000000, + 0x1c20da5e00000000, 0xdad422cd00000000, 0x1a0bac0c00000000, + 0x1b6d4e9500000000, 0xdbb2c05400000000, 0x58a7fb7d00000000, + 0x987875bc00000000, 0x991e972500000000, 0x59c119e400000000, + 0x54f117d900000000, 0x942e991800000000, 0x95487b8100000000, + 0x5597f54000000000, 0xd682ce6900000000, 0x165d40a800000000, + 0x173ba23100000000, 0xd7e42cf000000000, 0x1110d46300000000, + 0xd1cf5aa200000000, 0xd0a9b83b00000000, 0x107636fa00000000, + 0x93630dd300000000, 0x53bc831200000000, 0x52da618b00000000, + 0x9205ef4a00000000, 0x48ba7df100000000, 0x8865f33000000000, + 0x890311a900000000, 0x49dc9f6800000000, 0xcac9a44100000000, + 0x0a162a8000000000, 0x0b70c81900000000, 0xcbaf46d800000000, + 0x0d5bbe4b00000000, 0xcd84308a00000000, 0xcce2d21300000000, + 0x0c3d5cd200000000, 0x8f2867fb00000000, 0x4ff7e93a00000000, + 0x4e910ba300000000, 0x8e4e856200000000, 0x837e8b5f00000000, + 0x43a1059e00000000, 0x42c7e70700000000, 0x821869c600000000, + 0x010d52ef00000000, 0xc1d2dc2e00000000, 0xc0b43eb700000000, + 0x006bb07600000000, 0xc69f48e500000000, 0x0640c62400000000, + 0x072624bd00000000, 0xc7f9aa7c00000000, 0x44ec915500000000, + 0x84331f9400000000, 0x8555fd0d00000000, 0x458a73cc00000000, + 0x702ca9a100000000, 0xb0f3276000000000, 0xb195c5f900000000, + 0x714a4b3800000000, 0xf25f701100000000, 0x3280fed000000000, + 0x33e61c4900000000, 0xf339928800000000, 0x35cd6a1b00000000, + 0xf512e4da00000000, 0xf474064300000000, 0x34ab888200000000, + 0xb7beb3ab00000000, 0x77613d6a00000000, 0x7607dff300000000, + 0xb6d8513200000000, 0xbbe85f0f00000000, 0x7b37d1ce00000000, + 0x7a51335700000000, 0xba8ebd9600000000, 0x399b86bf00000000, + 0xf944087e00000000, 0xf822eae700000000, 0x38fd642600000000, + 0xfe099cb500000000, 0x3ed6127400000000, 0x3fb0f0ed00000000, + 0xff6f7e2c00000000, 0x7c7a450500000000, 0xbca5cbc400000000, + 0xbdc3295d00000000, 0x7d1ca79c00000000, 0xa7a3352700000000, + 0x677cbbe600000000, 0x661a597f00000000, 0xa6c5d7be00000000, + 0x25d0ec9700000000, 0xe50f625600000000, 0xe46980cf00000000, + 0x24b60e0e00000000, 0xe242f69d00000000, 0x229d785c00000000, + 0x23fb9ac500000000, 0xe324140400000000, 0x60312f2d00000000, + 0xa0eea1ec00000000, 0xa188437500000000, 0x6157cdb400000000, + 0x6c67c38900000000, 0xacb84d4800000000, 0xaddeafd100000000, + 0x6d01211000000000, 0xee141a3900000000, 0x2ecb94f800000000, + 0x2fad766100000000, 0xef72f8a000000000, 0x2986003300000000, + 0xe9598ef200000000, 0xe83f6c6b00000000, 0x28e0e2aa00000000, + 0xabf5d98300000000, 0x6b2a574200000000, 0x6a4cb5db00000000, + 0xaa933b1a00000000}, + {0x0000000000000000, 0x6f4ca59b00000000, 0x9f9e3bec00000000, + 0xf0d29e7700000000, 0x7f3b060300000000, 0x1077a39800000000, + 0xe0a53def00000000, 0x8fe9987400000000, 0xfe760c0600000000, + 0x913aa99d00000000, 0x61e837ea00000000, 0x0ea4927100000000, + 0x814d0a0500000000, 0xee01af9e00000000, 0x1ed331e900000000, + 0x719f947200000000, 0xfced180c00000000, 0x93a1bd9700000000, + 0x637323e000000000, 0x0c3f867b00000000, 0x83d61e0f00000000, + 0xec9abb9400000000, 0x1c4825e300000000, 0x7304807800000000, + 0x029b140a00000000, 0x6dd7b19100000000, 0x9d052fe600000000, + 0xf2498a7d00000000, 0x7da0120900000000, 0x12ecb79200000000, + 0xe23e29e500000000, 0x8d728c7e00000000, 0xf8db311800000000, + 0x9797948300000000, 0x67450af400000000, 0x0809af6f00000000, + 0x87e0371b00000000, 0xe8ac928000000000, 0x187e0cf700000000, + 0x7732a96c00000000, 0x06ad3d1e00000000, 0x69e1988500000000, + 0x993306f200000000, 0xf67fa36900000000, 0x79963b1d00000000, + 0x16da9e8600000000, 0xe60800f100000000, 0x8944a56a00000000, + 0x0436291400000000, 0x6b7a8c8f00000000, 0x9ba812f800000000, + 0xf4e4b76300000000, 0x7b0d2f1700000000, 0x14418a8c00000000, + 0xe49314fb00000000, 0x8bdfb16000000000, 0xfa40251200000000, + 0x950c808900000000, 0x65de1efe00000000, 0x0a92bb6500000000, + 0x857b231100000000, 0xea37868a00000000, 0x1ae518fd00000000, + 0x75a9bd6600000000, 0xf0b7633000000000, 0x9ffbc6ab00000000, + 0x6f2958dc00000000, 0x0065fd4700000000, 0x8f8c653300000000, + 0xe0c0c0a800000000, 0x10125edf00000000, 0x7f5efb4400000000, + 0x0ec16f3600000000, 0x618dcaad00000000, 0x915f54da00000000, + 0xfe13f14100000000, 0x71fa693500000000, 0x1eb6ccae00000000, + 0xee6452d900000000, 0x8128f74200000000, 0x0c5a7b3c00000000, + 0x6316dea700000000, 0x93c440d000000000, 0xfc88e54b00000000, + 0x73617d3f00000000, 0x1c2dd8a400000000, 0xecff46d300000000, + 0x83b3e34800000000, 0xf22c773a00000000, 0x9d60d2a100000000, + 0x6db24cd600000000, 0x02fee94d00000000, 0x8d17713900000000, + 0xe25bd4a200000000, 0x12894ad500000000, 0x7dc5ef4e00000000, + 0x086c522800000000, 0x6720f7b300000000, 0x97f269c400000000, + 0xf8becc5f00000000, 0x7757542b00000000, 0x181bf1b000000000, + 0xe8c96fc700000000, 0x8785ca5c00000000, 0xf61a5e2e00000000, + 0x9956fbb500000000, 0x698465c200000000, 0x06c8c05900000000, + 0x8921582d00000000, 0xe66dfdb600000000, 0x16bf63c100000000, + 0x79f3c65a00000000, 0xf4814a2400000000, 0x9bcdefbf00000000, + 0x6b1f71c800000000, 0x0453d45300000000, 0x8bba4c2700000000, + 0xe4f6e9bc00000000, 0x142477cb00000000, 0x7b68d25000000000, + 0x0af7462200000000, 0x65bbe3b900000000, 0x95697dce00000000, + 0xfa25d85500000000, 0x75cc402100000000, 0x1a80e5ba00000000, + 0xea527bcd00000000, 0x851ede5600000000, 0xe06fc76000000000, + 0x8f2362fb00000000, 0x7ff1fc8c00000000, 0x10bd591700000000, + 0x9f54c16300000000, 0xf01864f800000000, 0x00cafa8f00000000, + 0x6f865f1400000000, 0x1e19cb6600000000, 0x71556efd00000000, + 0x8187f08a00000000, 0xeecb551100000000, 0x6122cd6500000000, + 0x0e6e68fe00000000, 0xfebcf68900000000, 0x91f0531200000000, + 0x1c82df6c00000000, 0x73ce7af700000000, 0x831ce48000000000, + 0xec50411b00000000, 0x63b9d96f00000000, 0x0cf57cf400000000, + 0xfc27e28300000000, 0x936b471800000000, 0xe2f4d36a00000000, + 0x8db876f100000000, 0x7d6ae88600000000, 0x12264d1d00000000, + 0x9dcfd56900000000, 0xf28370f200000000, 0x0251ee8500000000, + 0x6d1d4b1e00000000, 0x18b4f67800000000, 0x77f853e300000000, + 0x872acd9400000000, 0xe866680f00000000, 0x678ff07b00000000, + 0x08c355e000000000, 0xf811cb9700000000, 0x975d6e0c00000000, + 0xe6c2fa7e00000000, 0x898e5fe500000000, 0x795cc19200000000, + 0x1610640900000000, 0x99f9fc7d00000000, 0xf6b559e600000000, + 0x0667c79100000000, 0x692b620a00000000, 0xe459ee7400000000, + 0x8b154bef00000000, 0x7bc7d59800000000, 0x148b700300000000, + 0x9b62e87700000000, 0xf42e4dec00000000, 0x04fcd39b00000000, + 0x6bb0760000000000, 0x1a2fe27200000000, 0x756347e900000000, + 0x85b1d99e00000000, 0xeafd7c0500000000, 0x6514e47100000000, + 0x0a5841ea00000000, 0xfa8adf9d00000000, 0x95c67a0600000000, + 0x10d8a45000000000, 0x7f9401cb00000000, 0x8f469fbc00000000, + 0xe00a3a2700000000, 0x6fe3a25300000000, 0x00af07c800000000, + 0xf07d99bf00000000, 0x9f313c2400000000, 0xeeaea85600000000, + 0x81e20dcd00000000, 0x713093ba00000000, 0x1e7c362100000000, + 0x9195ae5500000000, 0xfed90bce00000000, 0x0e0b95b900000000, + 0x6147302200000000, 0xec35bc5c00000000, 0x837919c700000000, + 0x73ab87b000000000, 0x1ce7222b00000000, 0x930eba5f00000000, + 0xfc421fc400000000, 0x0c9081b300000000, 0x63dc242800000000, + 0x1243b05a00000000, 0x7d0f15c100000000, 0x8ddd8bb600000000, + 0xe2912e2d00000000, 0x6d78b65900000000, 0x023413c200000000, + 0xf2e68db500000000, 0x9daa282e00000000, 0xe803954800000000, + 0x874f30d300000000, 0x779daea400000000, 0x18d10b3f00000000, + 0x9738934b00000000, 0xf87436d000000000, 0x08a6a8a700000000, + 0x67ea0d3c00000000, 0x1675994e00000000, 0x79393cd500000000, + 0x89eba2a200000000, 0xe6a7073900000000, 0x694e9f4d00000000, + 0x06023ad600000000, 0xf6d0a4a100000000, 0x999c013a00000000, + 0x14ee8d4400000000, 0x7ba228df00000000, 0x8b70b6a800000000, + 0xe43c133300000000, 0x6bd58b4700000000, 0x04992edc00000000, + 0xf44bb0ab00000000, 0x9b07153000000000, 0xea98814200000000, + 0x85d424d900000000, 0x7506baae00000000, 0x1a4a1f3500000000, + 0x95a3874100000000, 0xfaef22da00000000, 0x0a3dbcad00000000, + 0x6571193600000000}, + {0x0000000000000000, 0x85d996dd00000000, 0x4bb55c6000000000, + 0xce6ccabd00000000, 0x966ab9c000000000, 0x13b32f1d00000000, + 0xdddfe5a000000000, 0x5806737d00000000, 0x6dd3035a00000000, + 0xe80a958700000000, 0x26665f3a00000000, 0xa3bfc9e700000000, + 0xfbb9ba9a00000000, 0x7e602c4700000000, 0xb00ce6fa00000000, + 0x35d5702700000000, 0xdaa607b400000000, 0x5f7f916900000000, + 0x91135bd400000000, 0x14cacd0900000000, 0x4cccbe7400000000, + 0xc91528a900000000, 0x0779e21400000000, 0x82a074c900000000, + 0xb77504ee00000000, 0x32ac923300000000, 0xfcc0588e00000000, + 0x7919ce5300000000, 0x211fbd2e00000000, 0xa4c62bf300000000, + 0x6aaae14e00000000, 0xef73779300000000, 0xf54b7eb300000000, + 0x7092e86e00000000, 0xbefe22d300000000, 0x3b27b40e00000000, + 0x6321c77300000000, 0xe6f851ae00000000, 0x28949b1300000000, + 0xad4d0dce00000000, 0x98987de900000000, 0x1d41eb3400000000, + 0xd32d218900000000, 0x56f4b75400000000, 0x0ef2c42900000000, + 0x8b2b52f400000000, 0x4547984900000000, 0xc09e0e9400000000, + 0x2fed790700000000, 0xaa34efda00000000, 0x6458256700000000, + 0xe181b3ba00000000, 0xb987c0c700000000, 0x3c5e561a00000000, + 0xf2329ca700000000, 0x77eb0a7a00000000, 0x423e7a5d00000000, + 0xc7e7ec8000000000, 0x098b263d00000000, 0x8c52b0e000000000, + 0xd454c39d00000000, 0x518d554000000000, 0x9fe19ffd00000000, + 0x1a38092000000000, 0xab918dbd00000000, 0x2e481b6000000000, + 0xe024d1dd00000000, 0x65fd470000000000, 0x3dfb347d00000000, + 0xb822a2a000000000, 0x764e681d00000000, 0xf397fec000000000, + 0xc6428ee700000000, 0x439b183a00000000, 0x8df7d28700000000, + 0x082e445a00000000, 0x5028372700000000, 0xd5f1a1fa00000000, + 0x1b9d6b4700000000, 0x9e44fd9a00000000, 0x71378a0900000000, + 0xf4ee1cd400000000, 0x3a82d66900000000, 0xbf5b40b400000000, + 0xe75d33c900000000, 0x6284a51400000000, 0xace86fa900000000, + 0x2931f97400000000, 0x1ce4895300000000, 0x993d1f8e00000000, + 0x5751d53300000000, 0xd28843ee00000000, 0x8a8e309300000000, + 0x0f57a64e00000000, 0xc13b6cf300000000, 0x44e2fa2e00000000, + 0x5edaf30e00000000, 0xdb0365d300000000, 0x156faf6e00000000, + 0x90b639b300000000, 0xc8b04ace00000000, 0x4d69dc1300000000, + 0x830516ae00000000, 0x06dc807300000000, 0x3309f05400000000, + 0xb6d0668900000000, 0x78bcac3400000000, 0xfd653ae900000000, + 0xa563499400000000, 0x20badf4900000000, 0xeed615f400000000, + 0x6b0f832900000000, 0x847cf4ba00000000, 0x01a5626700000000, + 0xcfc9a8da00000000, 0x4a103e0700000000, 0x12164d7a00000000, + 0x97cfdba700000000, 0x59a3111a00000000, 0xdc7a87c700000000, + 0xe9aff7e000000000, 0x6c76613d00000000, 0xa21aab8000000000, + 0x27c33d5d00000000, 0x7fc54e2000000000, 0xfa1cd8fd00000000, + 0x3470124000000000, 0xb1a9849d00000000, 0x17256aa000000000, + 0x92fcfc7d00000000, 0x5c9036c000000000, 0xd949a01d00000000, + 0x814fd36000000000, 0x049645bd00000000, 0xcafa8f0000000000, + 0x4f2319dd00000000, 0x7af669fa00000000, 0xff2fff2700000000, + 0x3143359a00000000, 0xb49aa34700000000, 0xec9cd03a00000000, + 0x694546e700000000, 0xa7298c5a00000000, 0x22f01a8700000000, + 0xcd836d1400000000, 0x485afbc900000000, 0x8636317400000000, + 0x03efa7a900000000, 0x5be9d4d400000000, 0xde30420900000000, + 0x105c88b400000000, 0x95851e6900000000, 0xa0506e4e00000000, + 0x2589f89300000000, 0xebe5322e00000000, 0x6e3ca4f300000000, + 0x363ad78e00000000, 0xb3e3415300000000, 0x7d8f8bee00000000, + 0xf8561d3300000000, 0xe26e141300000000, 0x67b782ce00000000, + 0xa9db487300000000, 0x2c02deae00000000, 0x7404add300000000, + 0xf1dd3b0e00000000, 0x3fb1f1b300000000, 0xba68676e00000000, + 0x8fbd174900000000, 0x0a64819400000000, 0xc4084b2900000000, + 0x41d1ddf400000000, 0x19d7ae8900000000, 0x9c0e385400000000, + 0x5262f2e900000000, 0xd7bb643400000000, 0x38c813a700000000, + 0xbd11857a00000000, 0x737d4fc700000000, 0xf6a4d91a00000000, + 0xaea2aa6700000000, 0x2b7b3cba00000000, 0xe517f60700000000, + 0x60ce60da00000000, 0x551b10fd00000000, 0xd0c2862000000000, + 0x1eae4c9d00000000, 0x9b77da4000000000, 0xc371a93d00000000, + 0x46a83fe000000000, 0x88c4f55d00000000, 0x0d1d638000000000, + 0xbcb4e71d00000000, 0x396d71c000000000, 0xf701bb7d00000000, + 0x72d82da000000000, 0x2ade5edd00000000, 0xaf07c80000000000, + 0x616b02bd00000000, 0xe4b2946000000000, 0xd167e44700000000, + 0x54be729a00000000, 0x9ad2b82700000000, 0x1f0b2efa00000000, + 0x470d5d8700000000, 0xc2d4cb5a00000000, 0x0cb801e700000000, + 0x8961973a00000000, 0x6612e0a900000000, 0xe3cb767400000000, + 0x2da7bcc900000000, 0xa87e2a1400000000, 0xf078596900000000, + 0x75a1cfb400000000, 0xbbcd050900000000, 0x3e1493d400000000, + 0x0bc1e3f300000000, 0x8e18752e00000000, 0x4074bf9300000000, + 0xc5ad294e00000000, 0x9dab5a3300000000, 0x1872ccee00000000, + 0xd61e065300000000, 0x53c7908e00000000, 0x49ff99ae00000000, + 0xcc260f7300000000, 0x024ac5ce00000000, 0x8793531300000000, + 0xdf95206e00000000, 0x5a4cb6b300000000, 0x94207c0e00000000, + 0x11f9ead300000000, 0x242c9af400000000, 0xa1f50c2900000000, + 0x6f99c69400000000, 0xea40504900000000, 0xb246233400000000, + 0x379fb5e900000000, 0xf9f37f5400000000, 0x7c2ae98900000000, + 0x93599e1a00000000, 0x168008c700000000, 0xd8ecc27a00000000, + 0x5d3554a700000000, 0x053327da00000000, 0x80eab10700000000, + 0x4e867bba00000000, 0xcb5fed6700000000, 0xfe8a9d4000000000, + 0x7b530b9d00000000, 0xb53fc12000000000, 0x30e657fd00000000, + 0x68e0248000000000, 0xed39b25d00000000, 0x235578e000000000, + 0xa68cee3d00000000}, + {0x0000000000000000, 0x76e10f9d00000000, 0xadc46ee100000000, + 0xdb25617c00000000, 0x1b8fac1900000000, 0x6d6ea38400000000, + 0xb64bc2f800000000, 0xc0aacd6500000000, 0x361e593300000000, + 0x40ff56ae00000000, 0x9bda37d200000000, 0xed3b384f00000000, + 0x2d91f52a00000000, 0x5b70fab700000000, 0x80559bcb00000000, + 0xf6b4945600000000, 0x6c3cb26600000000, 0x1addbdfb00000000, + 0xc1f8dc8700000000, 0xb719d31a00000000, 0x77b31e7f00000000, + 0x015211e200000000, 0xda77709e00000000, 0xac967f0300000000, + 0x5a22eb5500000000, 0x2cc3e4c800000000, 0xf7e685b400000000, + 0x81078a2900000000, 0x41ad474c00000000, 0x374c48d100000000, + 0xec6929ad00000000, 0x9a88263000000000, 0xd87864cd00000000, + 0xae996b5000000000, 0x75bc0a2c00000000, 0x035d05b100000000, + 0xc3f7c8d400000000, 0xb516c74900000000, 0x6e33a63500000000, + 0x18d2a9a800000000, 0xee663dfe00000000, 0x9887326300000000, + 0x43a2531f00000000, 0x35435c8200000000, 0xf5e991e700000000, + 0x83089e7a00000000, 0x582dff0600000000, 0x2eccf09b00000000, + 0xb444d6ab00000000, 0xc2a5d93600000000, 0x1980b84a00000000, + 0x6f61b7d700000000, 0xafcb7ab200000000, 0xd92a752f00000000, + 0x020f145300000000, 0x74ee1bce00000000, 0x825a8f9800000000, + 0xf4bb800500000000, 0x2f9ee17900000000, 0x597feee400000000, + 0x99d5238100000000, 0xef342c1c00000000, 0x34114d6000000000, + 0x42f042fd00000000, 0xf1f7b94100000000, 0x8716b6dc00000000, + 0x5c33d7a000000000, 0x2ad2d83d00000000, 0xea78155800000000, + 0x9c991ac500000000, 0x47bc7bb900000000, 0x315d742400000000, + 0xc7e9e07200000000, 0xb108efef00000000, 0x6a2d8e9300000000, + 0x1ccc810e00000000, 0xdc664c6b00000000, 0xaa8743f600000000, + 0x71a2228a00000000, 0x07432d1700000000, 0x9dcb0b2700000000, + 0xeb2a04ba00000000, 0x300f65c600000000, 0x46ee6a5b00000000, + 0x8644a73e00000000, 0xf0a5a8a300000000, 0x2b80c9df00000000, + 0x5d61c64200000000, 0xabd5521400000000, 0xdd345d8900000000, + 0x06113cf500000000, 0x70f0336800000000, 0xb05afe0d00000000, + 0xc6bbf19000000000, 0x1d9e90ec00000000, 0x6b7f9f7100000000, + 0x298fdd8c00000000, 0x5f6ed21100000000, 0x844bb36d00000000, + 0xf2aabcf000000000, 0x3200719500000000, 0x44e17e0800000000, + 0x9fc41f7400000000, 0xe92510e900000000, 0x1f9184bf00000000, + 0x69708b2200000000, 0xb255ea5e00000000, 0xc4b4e5c300000000, + 0x041e28a600000000, 0x72ff273b00000000, 0xa9da464700000000, + 0xdf3b49da00000000, 0x45b36fea00000000, 0x3352607700000000, + 0xe877010b00000000, 0x9e960e9600000000, 0x5e3cc3f300000000, + 0x28ddcc6e00000000, 0xf3f8ad1200000000, 0x8519a28f00000000, + 0x73ad36d900000000, 0x054c394400000000, 0xde69583800000000, + 0xa88857a500000000, 0x68229ac000000000, 0x1ec3955d00000000, + 0xc5e6f42100000000, 0xb307fbbc00000000, 0xe2ef738300000000, + 0x940e7c1e00000000, 0x4f2b1d6200000000, 0x39ca12ff00000000, + 0xf960df9a00000000, 0x8f81d00700000000, 0x54a4b17b00000000, + 0x2245bee600000000, 0xd4f12ab000000000, 0xa210252d00000000, + 0x7935445100000000, 0x0fd44bcc00000000, 0xcf7e86a900000000, + 0xb99f893400000000, 0x62bae84800000000, 0x145be7d500000000, + 0x8ed3c1e500000000, 0xf832ce7800000000, 0x2317af0400000000, + 0x55f6a09900000000, 0x955c6dfc00000000, 0xe3bd626100000000, + 0x3898031d00000000, 0x4e790c8000000000, 0xb8cd98d600000000, + 0xce2c974b00000000, 0x1509f63700000000, 0x63e8f9aa00000000, + 0xa34234cf00000000, 0xd5a33b5200000000, 0x0e865a2e00000000, + 0x786755b300000000, 0x3a97174e00000000, 0x4c7618d300000000, + 0x975379af00000000, 0xe1b2763200000000, 0x2118bb5700000000, + 0x57f9b4ca00000000, 0x8cdcd5b600000000, 0xfa3dda2b00000000, + 0x0c894e7d00000000, 0x7a6841e000000000, 0xa14d209c00000000, + 0xd7ac2f0100000000, 0x1706e26400000000, 0x61e7edf900000000, + 0xbac28c8500000000, 0xcc23831800000000, 0x56aba52800000000, + 0x204aaab500000000, 0xfb6fcbc900000000, 0x8d8ec45400000000, + 0x4d24093100000000, 0x3bc506ac00000000, 0xe0e067d000000000, + 0x9601684d00000000, 0x60b5fc1b00000000, 0x1654f38600000000, + 0xcd7192fa00000000, 0xbb909d6700000000, 0x7b3a500200000000, + 0x0ddb5f9f00000000, 0xd6fe3ee300000000, 0xa01f317e00000000, + 0x1318cac200000000, 0x65f9c55f00000000, 0xbedca42300000000, + 0xc83dabbe00000000, 0x089766db00000000, 0x7e76694600000000, + 0xa553083a00000000, 0xd3b207a700000000, 0x250693f100000000, + 0x53e79c6c00000000, 0x88c2fd1000000000, 0xfe23f28d00000000, + 0x3e893fe800000000, 0x4868307500000000, 0x934d510900000000, + 0xe5ac5e9400000000, 0x7f2478a400000000, 0x09c5773900000000, + 0xd2e0164500000000, 0xa40119d800000000, 0x64abd4bd00000000, + 0x124adb2000000000, 0xc96fba5c00000000, 0xbf8eb5c100000000, + 0x493a219700000000, 0x3fdb2e0a00000000, 0xe4fe4f7600000000, + 0x921f40eb00000000, 0x52b58d8e00000000, 0x2454821300000000, + 0xff71e36f00000000, 0x8990ecf200000000, 0xcb60ae0f00000000, + 0xbd81a19200000000, 0x66a4c0ee00000000, 0x1045cf7300000000, + 0xd0ef021600000000, 0xa60e0d8b00000000, 0x7d2b6cf700000000, + 0x0bca636a00000000, 0xfd7ef73c00000000, 0x8b9ff8a100000000, + 0x50ba99dd00000000, 0x265b964000000000, 0xe6f15b2500000000, + 0x901054b800000000, 0x4b3535c400000000, 0x3dd43a5900000000, + 0xa75c1c6900000000, 0xd1bd13f400000000, 0x0a98728800000000, + 0x7c797d1500000000, 0xbcd3b07000000000, 0xca32bfed00000000, + 0x1117de9100000000, 0x67f6d10c00000000, 0x9142455a00000000, + 0xe7a34ac700000000, 0x3c862bbb00000000, 0x4a67242600000000, + 0x8acde94300000000, 0xfc2ce6de00000000, 0x270987a200000000, + 0x51e8883f00000000}, + {0x0000000000000000, 0xe8dbfbb900000000, 0x91b186a800000000, + 0x796a7d1100000000, 0x63657c8a00000000, 0x8bbe873300000000, + 0xf2d4fa2200000000, 0x1a0f019b00000000, 0x87cc89cf00000000, + 0x6f17727600000000, 0x167d0f6700000000, 0xfea6f4de00000000, + 0xe4a9f54500000000, 0x0c720efc00000000, 0x751873ed00000000, + 0x9dc3885400000000, 0x4f9f624400000000, 0xa74499fd00000000, + 0xde2ee4ec00000000, 0x36f51f5500000000, 0x2cfa1ece00000000, + 0xc421e57700000000, 0xbd4b986600000000, 0x559063df00000000, + 0xc853eb8b00000000, 0x2088103200000000, 0x59e26d2300000000, + 0xb139969a00000000, 0xab36970100000000, 0x43ed6cb800000000, + 0x3a8711a900000000, 0xd25cea1000000000, 0x9e3ec58800000000, + 0x76e53e3100000000, 0x0f8f432000000000, 0xe754b89900000000, + 0xfd5bb90200000000, 0x158042bb00000000, 0x6cea3faa00000000, + 0x8431c41300000000, 0x19f24c4700000000, 0xf129b7fe00000000, + 0x8843caef00000000, 0x6098315600000000, 0x7a9730cd00000000, + 0x924ccb7400000000, 0xeb26b66500000000, 0x03fd4ddc00000000, + 0xd1a1a7cc00000000, 0x397a5c7500000000, 0x4010216400000000, + 0xa8cbdadd00000000, 0xb2c4db4600000000, 0x5a1f20ff00000000, + 0x23755dee00000000, 0xcbaea65700000000, 0x566d2e0300000000, + 0xbeb6d5ba00000000, 0xc7dca8ab00000000, 0x2f07531200000000, + 0x3508528900000000, 0xddd3a93000000000, 0xa4b9d42100000000, + 0x4c622f9800000000, 0x7d7bfbca00000000, 0x95a0007300000000, + 0xecca7d6200000000, 0x041186db00000000, 0x1e1e874000000000, + 0xf6c57cf900000000, 0x8faf01e800000000, 0x6774fa5100000000, + 0xfab7720500000000, 0x126c89bc00000000, 0x6b06f4ad00000000, + 0x83dd0f1400000000, 0x99d20e8f00000000, 0x7109f53600000000, + 0x0863882700000000, 0xe0b8739e00000000, 0x32e4998e00000000, + 0xda3f623700000000, 0xa3551f2600000000, 0x4b8ee49f00000000, + 0x5181e50400000000, 0xb95a1ebd00000000, 0xc03063ac00000000, + 0x28eb981500000000, 0xb528104100000000, 0x5df3ebf800000000, + 0x249996e900000000, 0xcc426d5000000000, 0xd64d6ccb00000000, + 0x3e96977200000000, 0x47fcea6300000000, 0xaf2711da00000000, + 0xe3453e4200000000, 0x0b9ec5fb00000000, 0x72f4b8ea00000000, + 0x9a2f435300000000, 0x802042c800000000, 0x68fbb97100000000, + 0x1191c46000000000, 0xf94a3fd900000000, 0x6489b78d00000000, + 0x8c524c3400000000, 0xf538312500000000, 0x1de3ca9c00000000, + 0x07eccb0700000000, 0xef3730be00000000, 0x965d4daf00000000, + 0x7e86b61600000000, 0xacda5c0600000000, 0x4401a7bf00000000, + 0x3d6bdaae00000000, 0xd5b0211700000000, 0xcfbf208c00000000, + 0x2764db3500000000, 0x5e0ea62400000000, 0xb6d55d9d00000000, + 0x2b16d5c900000000, 0xc3cd2e7000000000, 0xbaa7536100000000, + 0x527ca8d800000000, 0x4873a94300000000, 0xa0a852fa00000000, + 0xd9c22feb00000000, 0x3119d45200000000, 0xbbf0874e00000000, + 0x532b7cf700000000, 0x2a4101e600000000, 0xc29afa5f00000000, + 0xd895fbc400000000, 0x304e007d00000000, 0x49247d6c00000000, + 0xa1ff86d500000000, 0x3c3c0e8100000000, 0xd4e7f53800000000, + 0xad8d882900000000, 0x4556739000000000, 0x5f59720b00000000, + 0xb78289b200000000, 0xcee8f4a300000000, 0x26330f1a00000000, + 0xf46fe50a00000000, 0x1cb41eb300000000, 0x65de63a200000000, + 0x8d05981b00000000, 0x970a998000000000, 0x7fd1623900000000, + 0x06bb1f2800000000, 0xee60e49100000000, 0x73a36cc500000000, + 0x9b78977c00000000, 0xe212ea6d00000000, 0x0ac911d400000000, + 0x10c6104f00000000, 0xf81debf600000000, 0x817796e700000000, + 0x69ac6d5e00000000, 0x25ce42c600000000, 0xcd15b97f00000000, + 0xb47fc46e00000000, 0x5ca43fd700000000, 0x46ab3e4c00000000, + 0xae70c5f500000000, 0xd71ab8e400000000, 0x3fc1435d00000000, + 0xa202cb0900000000, 0x4ad930b000000000, 0x33b34da100000000, + 0xdb68b61800000000, 0xc167b78300000000, 0x29bc4c3a00000000, + 0x50d6312b00000000, 0xb80dca9200000000, 0x6a51208200000000, + 0x828adb3b00000000, 0xfbe0a62a00000000, 0x133b5d9300000000, + 0x09345c0800000000, 0xe1efa7b100000000, 0x9885daa000000000, + 0x705e211900000000, 0xed9da94d00000000, 0x054652f400000000, + 0x7c2c2fe500000000, 0x94f7d45c00000000, 0x8ef8d5c700000000, + 0x66232e7e00000000, 0x1f49536f00000000, 0xf792a8d600000000, + 0xc68b7c8400000000, 0x2e50873d00000000, 0x573afa2c00000000, + 0xbfe1019500000000, 0xa5ee000e00000000, 0x4d35fbb700000000, + 0x345f86a600000000, 0xdc847d1f00000000, 0x4147f54b00000000, + 0xa99c0ef200000000, 0xd0f673e300000000, 0x382d885a00000000, + 0x222289c100000000, 0xcaf9727800000000, 0xb3930f6900000000, + 0x5b48f4d000000000, 0x89141ec000000000, 0x61cfe57900000000, + 0x18a5986800000000, 0xf07e63d100000000, 0xea71624a00000000, + 0x02aa99f300000000, 0x7bc0e4e200000000, 0x931b1f5b00000000, + 0x0ed8970f00000000, 0xe6036cb600000000, 0x9f6911a700000000, + 0x77b2ea1e00000000, 0x6dbdeb8500000000, 0x8566103c00000000, + 0xfc0c6d2d00000000, 0x14d7969400000000, 0x58b5b90c00000000, + 0xb06e42b500000000, 0xc9043fa400000000, 0x21dfc41d00000000, + 0x3bd0c58600000000, 0xd30b3e3f00000000, 0xaa61432e00000000, + 0x42bab89700000000, 0xdf7930c300000000, 0x37a2cb7a00000000, + 0x4ec8b66b00000000, 0xa6134dd200000000, 0xbc1c4c4900000000, + 0x54c7b7f000000000, 0x2dadcae100000000, 0xc576315800000000, + 0x172adb4800000000, 0xfff120f100000000, 0x869b5de000000000, + 0x6e40a65900000000, 0x744fa7c200000000, 0x9c945c7b00000000, + 0xe5fe216a00000000, 0x0d25dad300000000, 0x90e6528700000000, + 0x783da93e00000000, 0x0157d42f00000000, 0xe98c2f9600000000, + 0xf3832e0d00000000, 0x1b58d5b400000000, 0x6232a8a500000000, + 0x8ae9531c00000000}, + {0x0000000000000000, 0x919168ae00000000, 0x6325a08700000000, + 0xf2b4c82900000000, 0x874c31d400000000, 0x16dd597a00000000, + 0xe469915300000000, 0x75f8f9fd00000000, 0x4f9f137300000000, + 0xde0e7bdd00000000, 0x2cbab3f400000000, 0xbd2bdb5a00000000, + 0xc8d322a700000000, 0x59424a0900000000, 0xabf6822000000000, + 0x3a67ea8e00000000, 0x9e3e27e600000000, 0x0faf4f4800000000, + 0xfd1b876100000000, 0x6c8aefcf00000000, 0x1972163200000000, + 0x88e37e9c00000000, 0x7a57b6b500000000, 0xebc6de1b00000000, + 0xd1a1349500000000, 0x40305c3b00000000, 0xb284941200000000, + 0x2315fcbc00000000, 0x56ed054100000000, 0xc77c6def00000000, + 0x35c8a5c600000000, 0xa459cd6800000000, 0x7d7b3f1700000000, + 0xecea57b900000000, 0x1e5e9f9000000000, 0x8fcff73e00000000, + 0xfa370ec300000000, 0x6ba6666d00000000, 0x9912ae4400000000, + 0x0883c6ea00000000, 0x32e42c6400000000, 0xa37544ca00000000, + 0x51c18ce300000000, 0xc050e44d00000000, 0xb5a81db000000000, + 0x2439751e00000000, 0xd68dbd3700000000, 0x471cd59900000000, + 0xe34518f100000000, 0x72d4705f00000000, 0x8060b87600000000, + 0x11f1d0d800000000, 0x6409292500000000, 0xf598418b00000000, + 0x072c89a200000000, 0x96bde10c00000000, 0xacda0b8200000000, + 0x3d4b632c00000000, 0xcfffab0500000000, 0x5e6ec3ab00000000, + 0x2b963a5600000000, 0xba0752f800000000, 0x48b39ad100000000, + 0xd922f27f00000000, 0xfaf67e2e00000000, 0x6b67168000000000, + 0x99d3dea900000000, 0x0842b60700000000, 0x7dba4ffa00000000, + 0xec2b275400000000, 0x1e9fef7d00000000, 0x8f0e87d300000000, + 0xb5696d5d00000000, 0x24f805f300000000, 0xd64ccdda00000000, + 0x47dda57400000000, 0x32255c8900000000, 0xa3b4342700000000, + 0x5100fc0e00000000, 0xc09194a000000000, 0x64c859c800000000, + 0xf559316600000000, 0x07edf94f00000000, 0x967c91e100000000, + 0xe384681c00000000, 0x721500b200000000, 0x80a1c89b00000000, + 0x1130a03500000000, 0x2b574abb00000000, 0xbac6221500000000, + 0x4872ea3c00000000, 0xd9e3829200000000, 0xac1b7b6f00000000, + 0x3d8a13c100000000, 0xcf3edbe800000000, 0x5eafb34600000000, + 0x878d413900000000, 0x161c299700000000, 0xe4a8e1be00000000, + 0x7539891000000000, 0x00c170ed00000000, 0x9150184300000000, + 0x63e4d06a00000000, 0xf275b8c400000000, 0xc812524a00000000, + 0x59833ae400000000, 0xab37f2cd00000000, 0x3aa69a6300000000, + 0x4f5e639e00000000, 0xdecf0b3000000000, 0x2c7bc31900000000, + 0xbdeaabb700000000, 0x19b366df00000000, 0x88220e7100000000, + 0x7a96c65800000000, 0xeb07aef600000000, 0x9eff570b00000000, + 0x0f6e3fa500000000, 0xfddaf78c00000000, 0x6c4b9f2200000000, + 0x562c75ac00000000, 0xc7bd1d0200000000, 0x3509d52b00000000, + 0xa498bd8500000000, 0xd160447800000000, 0x40f12cd600000000, + 0xb245e4ff00000000, 0x23d48c5100000000, 0xf4edfd5c00000000, + 0x657c95f200000000, 0x97c85ddb00000000, 0x0659357500000000, + 0x73a1cc8800000000, 0xe230a42600000000, 0x10846c0f00000000, + 0x811504a100000000, 0xbb72ee2f00000000, 0x2ae3868100000000, + 0xd8574ea800000000, 0x49c6260600000000, 0x3c3edffb00000000, + 0xadafb75500000000, 0x5f1b7f7c00000000, 0xce8a17d200000000, + 0x6ad3daba00000000, 0xfb42b21400000000, 0x09f67a3d00000000, + 0x9867129300000000, 0xed9feb6e00000000, 0x7c0e83c000000000, + 0x8eba4be900000000, 0x1f2b234700000000, 0x254cc9c900000000, + 0xb4dda16700000000, 0x4669694e00000000, 0xd7f801e000000000, + 0xa200f81d00000000, 0x339190b300000000, 0xc125589a00000000, + 0x50b4303400000000, 0x8996c24b00000000, 0x1807aae500000000, + 0xeab362cc00000000, 0x7b220a6200000000, 0x0edaf39f00000000, + 0x9f4b9b3100000000, 0x6dff531800000000, 0xfc6e3bb600000000, + 0xc609d13800000000, 0x5798b99600000000, 0xa52c71bf00000000, + 0x34bd191100000000, 0x4145e0ec00000000, 0xd0d4884200000000, + 0x2260406b00000000, 0xb3f128c500000000, 0x17a8e5ad00000000, + 0x86398d0300000000, 0x748d452a00000000, 0xe51c2d8400000000, + 0x90e4d47900000000, 0x0175bcd700000000, 0xf3c174fe00000000, + 0x62501c5000000000, 0x5837f6de00000000, 0xc9a69e7000000000, + 0x3b12565900000000, 0xaa833ef700000000, 0xdf7bc70a00000000, + 0x4eeaafa400000000, 0xbc5e678d00000000, 0x2dcf0f2300000000, + 0x0e1b837200000000, 0x9f8aebdc00000000, 0x6d3e23f500000000, + 0xfcaf4b5b00000000, 0x8957b2a600000000, 0x18c6da0800000000, + 0xea72122100000000, 0x7be37a8f00000000, 0x4184900100000000, + 0xd015f8af00000000, 0x22a1308600000000, 0xb330582800000000, + 0xc6c8a1d500000000, 0x5759c97b00000000, 0xa5ed015200000000, + 0x347c69fc00000000, 0x9025a49400000000, 0x01b4cc3a00000000, + 0xf300041300000000, 0x62916cbd00000000, 0x1769954000000000, + 0x86f8fdee00000000, 0x744c35c700000000, 0xe5dd5d6900000000, + 0xdfbab7e700000000, 0x4e2bdf4900000000, 0xbc9f176000000000, + 0x2d0e7fce00000000, 0x58f6863300000000, 0xc967ee9d00000000, + 0x3bd326b400000000, 0xaa424e1a00000000, 0x7360bc6500000000, + 0xe2f1d4cb00000000, 0x10451ce200000000, 0x81d4744c00000000, + 0xf42c8db100000000, 0x65bde51f00000000, 0x97092d3600000000, + 0x0698459800000000, 0x3cffaf1600000000, 0xad6ec7b800000000, + 0x5fda0f9100000000, 0xce4b673f00000000, 0xbbb39ec200000000, + 0x2a22f66c00000000, 0xd8963e4500000000, 0x490756eb00000000, + 0xed5e9b8300000000, 0x7ccff32d00000000, 0x8e7b3b0400000000, + 0x1fea53aa00000000, 0x6a12aa5700000000, 0xfb83c2f900000000, + 0x09370ad000000000, 0x98a6627e00000000, 0xa2c188f000000000, + 0x3350e05e00000000, 0xc1e4287700000000, 0x507540d900000000, + 0x258db92400000000, 0xb41cd18a00000000, 0x46a819a300000000, + 0xd739710d00000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xccaa009e, 0x4225077d, 0x8e8f07e3, 0x844a0efa, + 0x48e00e64, 0xc66f0987, 0x0ac50919, 0xd3e51bb5, 0x1f4f1b2b, + 0x91c01cc8, 0x5d6a1c56, 0x57af154f, 0x9b0515d1, 0x158a1232, + 0xd92012ac, 0x7cbb312b, 0xb01131b5, 0x3e9e3656, 0xf23436c8, + 0xf8f13fd1, 0x345b3f4f, 0xbad438ac, 0x767e3832, 0xaf5e2a9e, + 0x63f42a00, 0xed7b2de3, 0x21d12d7d, 0x2b142464, 0xe7be24fa, + 0x69312319, 0xa59b2387, 0xf9766256, 0x35dc62c8, 0xbb53652b, + 0x77f965b5, 0x7d3c6cac, 0xb1966c32, 0x3f196bd1, 0xf3b36b4f, + 0x2a9379e3, 0xe639797d, 0x68b67e9e, 0xa41c7e00, 0xaed97719, + 0x62737787, 0xecfc7064, 0x205670fa, 0x85cd537d, 0x496753e3, + 0xc7e85400, 0x0b42549e, 0x01875d87, 0xcd2d5d19, 0x43a25afa, + 0x8f085a64, 0x562848c8, 0x9a824856, 0x140d4fb5, 0xd8a74f2b, + 0xd2624632, 0x1ec846ac, 0x9047414f, 0x5ced41d1, 0x299dc2ed, + 0xe537c273, 0x6bb8c590, 0xa712c50e, 0xadd7cc17, 0x617dcc89, + 0xeff2cb6a, 0x2358cbf4, 0xfa78d958, 0x36d2d9c6, 0xb85dde25, + 0x74f7debb, 0x7e32d7a2, 0xb298d73c, 0x3c17d0df, 0xf0bdd041, + 0x5526f3c6, 0x998cf358, 0x1703f4bb, 0xdba9f425, 0xd16cfd3c, + 0x1dc6fda2, 0x9349fa41, 0x5fe3fadf, 0x86c3e873, 0x4a69e8ed, + 0xc4e6ef0e, 0x084cef90, 0x0289e689, 0xce23e617, 0x40ace1f4, + 0x8c06e16a, 0xd0eba0bb, 0x1c41a025, 0x92cea7c6, 0x5e64a758, + 0x54a1ae41, 0x980baedf, 0x1684a93c, 0xda2ea9a2, 0x030ebb0e, + 0xcfa4bb90, 0x412bbc73, 0x8d81bced, 0x8744b5f4, 0x4beeb56a, + 0xc561b289, 0x09cbb217, 0xac509190, 0x60fa910e, 0xee7596ed, + 0x22df9673, 0x281a9f6a, 0xe4b09ff4, 0x6a3f9817, 0xa6959889, + 0x7fb58a25, 0xb31f8abb, 0x3d908d58, 0xf13a8dc6, 0xfbff84df, + 0x37558441, 0xb9da83a2, 0x7570833c, 0x533b85da, 0x9f918544, + 0x111e82a7, 0xddb48239, 0xd7718b20, 0x1bdb8bbe, 0x95548c5d, + 0x59fe8cc3, 0x80de9e6f, 0x4c749ef1, 0xc2fb9912, 0x0e51998c, + 0x04949095, 0xc83e900b, 0x46b197e8, 0x8a1b9776, 0x2f80b4f1, + 0xe32ab46f, 0x6da5b38c, 0xa10fb312, 0xabcaba0b, 0x6760ba95, + 0xe9efbd76, 0x2545bde8, 0xfc65af44, 0x30cfafda, 0xbe40a839, + 0x72eaa8a7, 0x782fa1be, 0xb485a120, 0x3a0aa6c3, 0xf6a0a65d, + 0xaa4de78c, 0x66e7e712, 0xe868e0f1, 0x24c2e06f, 0x2e07e976, + 0xe2ade9e8, 0x6c22ee0b, 0xa088ee95, 0x79a8fc39, 0xb502fca7, + 0x3b8dfb44, 0xf727fbda, 0xfde2f2c3, 0x3148f25d, 0xbfc7f5be, + 0x736df520, 0xd6f6d6a7, 0x1a5cd639, 0x94d3d1da, 0x5879d144, + 0x52bcd85d, 0x9e16d8c3, 0x1099df20, 0xdc33dfbe, 0x0513cd12, + 0xc9b9cd8c, 0x4736ca6f, 0x8b9ccaf1, 0x8159c3e8, 0x4df3c376, + 0xc37cc495, 0x0fd6c40b, 0x7aa64737, 0xb60c47a9, 0x3883404a, + 0xf42940d4, 0xfeec49cd, 0x32464953, 0xbcc94eb0, 0x70634e2e, + 0xa9435c82, 0x65e95c1c, 0xeb665bff, 0x27cc5b61, 0x2d095278, + 0xe1a352e6, 0x6f2c5505, 0xa386559b, 0x061d761c, 0xcab77682, + 0x44387161, 0x889271ff, 0x825778e6, 0x4efd7878, 0xc0727f9b, + 0x0cd87f05, 0xd5f86da9, 0x19526d37, 0x97dd6ad4, 0x5b776a4a, + 0x51b26353, 0x9d1863cd, 0x1397642e, 0xdf3d64b0, 0x83d02561, + 0x4f7a25ff, 0xc1f5221c, 0x0d5f2282, 0x079a2b9b, 0xcb302b05, + 0x45bf2ce6, 0x89152c78, 0x50353ed4, 0x9c9f3e4a, 0x121039a9, + 0xdeba3937, 0xd47f302e, 0x18d530b0, 0x965a3753, 0x5af037cd, + 0xff6b144a, 0x33c114d4, 0xbd4e1337, 0x71e413a9, 0x7b211ab0, + 0xb78b1a2e, 0x39041dcd, 0xf5ae1d53, 0x2c8e0fff, 0xe0240f61, + 0x6eab0882, 0xa201081c, 0xa8c40105, 0x646e019b, 0xeae10678, + 0x264b06e6}, + {0x00000000, 0xa6770bb4, 0x979f1129, 0x31e81a9d, 0xf44f2413, + 0x52382fa7, 0x63d0353a, 0xc5a73e8e, 0x33ef4e67, 0x959845d3, + 0xa4705f4e, 0x020754fa, 0xc7a06a74, 0x61d761c0, 0x503f7b5d, + 0xf64870e9, 0x67de9cce, 0xc1a9977a, 0xf0418de7, 0x56368653, + 0x9391b8dd, 0x35e6b369, 0x040ea9f4, 0xa279a240, 0x5431d2a9, + 0xf246d91d, 0xc3aec380, 0x65d9c834, 0xa07ef6ba, 0x0609fd0e, + 0x37e1e793, 0x9196ec27, 0xcfbd399c, 0x69ca3228, 0x582228b5, + 0xfe552301, 0x3bf21d8f, 0x9d85163b, 0xac6d0ca6, 0x0a1a0712, + 0xfc5277fb, 0x5a257c4f, 0x6bcd66d2, 0xcdba6d66, 0x081d53e8, + 0xae6a585c, 0x9f8242c1, 0x39f54975, 0xa863a552, 0x0e14aee6, + 0x3ffcb47b, 0x998bbfcf, 0x5c2c8141, 0xfa5b8af5, 0xcbb39068, + 0x6dc49bdc, 0x9b8ceb35, 0x3dfbe081, 0x0c13fa1c, 0xaa64f1a8, + 0x6fc3cf26, 0xc9b4c492, 0xf85cde0f, 0x5e2bd5bb, 0x440b7579, + 0xe27c7ecd, 0xd3946450, 0x75e36fe4, 0xb044516a, 0x16335ade, + 0x27db4043, 0x81ac4bf7, 0x77e43b1e, 0xd19330aa, 0xe07b2a37, + 0x460c2183, 0x83ab1f0d, 0x25dc14b9, 0x14340e24, 0xb2430590, + 0x23d5e9b7, 0x85a2e203, 0xb44af89e, 0x123df32a, 0xd79acda4, + 0x71edc610, 0x4005dc8d, 0xe672d739, 0x103aa7d0, 0xb64dac64, + 0x87a5b6f9, 0x21d2bd4d, 0xe47583c3, 0x42028877, 0x73ea92ea, + 0xd59d995e, 0x8bb64ce5, 0x2dc14751, 0x1c295dcc, 0xba5e5678, + 0x7ff968f6, 0xd98e6342, 0xe86679df, 0x4e11726b, 0xb8590282, + 0x1e2e0936, 0x2fc613ab, 0x89b1181f, 0x4c162691, 0xea612d25, + 0xdb8937b8, 0x7dfe3c0c, 0xec68d02b, 0x4a1fdb9f, 0x7bf7c102, + 0xdd80cab6, 0x1827f438, 0xbe50ff8c, 0x8fb8e511, 0x29cfeea5, + 0xdf879e4c, 0x79f095f8, 0x48188f65, 0xee6f84d1, 0x2bc8ba5f, + 0x8dbfb1eb, 0xbc57ab76, 0x1a20a0c2, 0x8816eaf2, 0x2e61e146, + 0x1f89fbdb, 0xb9fef06f, 0x7c59cee1, 0xda2ec555, 0xebc6dfc8, + 0x4db1d47c, 0xbbf9a495, 0x1d8eaf21, 0x2c66b5bc, 0x8a11be08, + 0x4fb68086, 0xe9c18b32, 0xd82991af, 0x7e5e9a1b, 0xefc8763c, + 0x49bf7d88, 0x78576715, 0xde206ca1, 0x1b87522f, 0xbdf0599b, + 0x8c184306, 0x2a6f48b2, 0xdc27385b, 0x7a5033ef, 0x4bb82972, + 0xedcf22c6, 0x28681c48, 0x8e1f17fc, 0xbff70d61, 0x198006d5, + 0x47abd36e, 0xe1dcd8da, 0xd034c247, 0x7643c9f3, 0xb3e4f77d, + 0x1593fcc9, 0x247be654, 0x820cede0, 0x74449d09, 0xd23396bd, + 0xe3db8c20, 0x45ac8794, 0x800bb91a, 0x267cb2ae, 0x1794a833, + 0xb1e3a387, 0x20754fa0, 0x86024414, 0xb7ea5e89, 0x119d553d, + 0xd43a6bb3, 0x724d6007, 0x43a57a9a, 0xe5d2712e, 0x139a01c7, + 0xb5ed0a73, 0x840510ee, 0x22721b5a, 0xe7d525d4, 0x41a22e60, + 0x704a34fd, 0xd63d3f49, 0xcc1d9f8b, 0x6a6a943f, 0x5b828ea2, + 0xfdf58516, 0x3852bb98, 0x9e25b02c, 0xafcdaab1, 0x09baa105, + 0xfff2d1ec, 0x5985da58, 0x686dc0c5, 0xce1acb71, 0x0bbdf5ff, + 0xadcafe4b, 0x9c22e4d6, 0x3a55ef62, 0xabc30345, 0x0db408f1, + 0x3c5c126c, 0x9a2b19d8, 0x5f8c2756, 0xf9fb2ce2, 0xc813367f, + 0x6e643dcb, 0x982c4d22, 0x3e5b4696, 0x0fb35c0b, 0xa9c457bf, + 0x6c636931, 0xca146285, 0xfbfc7818, 0x5d8b73ac, 0x03a0a617, + 0xa5d7ada3, 0x943fb73e, 0x3248bc8a, 0xf7ef8204, 0x519889b0, + 0x6070932d, 0xc6079899, 0x304fe870, 0x9638e3c4, 0xa7d0f959, + 0x01a7f2ed, 0xc400cc63, 0x6277c7d7, 0x539fdd4a, 0xf5e8d6fe, + 0x647e3ad9, 0xc209316d, 0xf3e12bf0, 0x55962044, 0x90311eca, + 0x3646157e, 0x07ae0fe3, 0xa1d90457, 0x579174be, 0xf1e67f0a, + 0xc00e6597, 0x66796e23, 0xa3de50ad, 0x05a95b19, 0x34414184, + 0x92364a30}, + {0x00000000, 0xcb5cd3a5, 0x4dc8a10b, 0x869472ae, 0x9b914216, + 0x50cd91b3, 0xd659e31d, 0x1d0530b8, 0xec53826d, 0x270f51c8, + 0xa19b2366, 0x6ac7f0c3, 0x77c2c07b, 0xbc9e13de, 0x3a0a6170, + 0xf156b2d5, 0x03d6029b, 0xc88ad13e, 0x4e1ea390, 0x85427035, + 0x9847408d, 0x531b9328, 0xd58fe186, 0x1ed33223, 0xef8580f6, + 0x24d95353, 0xa24d21fd, 0x6911f258, 0x7414c2e0, 0xbf481145, + 0x39dc63eb, 0xf280b04e, 0x07ac0536, 0xccf0d693, 0x4a64a43d, + 0x81387798, 0x9c3d4720, 0x57619485, 0xd1f5e62b, 0x1aa9358e, + 0xebff875b, 0x20a354fe, 0xa6372650, 0x6d6bf5f5, 0x706ec54d, + 0xbb3216e8, 0x3da66446, 0xf6fab7e3, 0x047a07ad, 0xcf26d408, + 0x49b2a6a6, 0x82ee7503, 0x9feb45bb, 0x54b7961e, 0xd223e4b0, + 0x197f3715, 0xe82985c0, 0x23755665, 0xa5e124cb, 0x6ebdf76e, + 0x73b8c7d6, 0xb8e41473, 0x3e7066dd, 0xf52cb578, 0x0f580a6c, + 0xc404d9c9, 0x4290ab67, 0x89cc78c2, 0x94c9487a, 0x5f959bdf, + 0xd901e971, 0x125d3ad4, 0xe30b8801, 0x28575ba4, 0xaec3290a, + 0x659ffaaf, 0x789aca17, 0xb3c619b2, 0x35526b1c, 0xfe0eb8b9, + 0x0c8e08f7, 0xc7d2db52, 0x4146a9fc, 0x8a1a7a59, 0x971f4ae1, + 0x5c439944, 0xdad7ebea, 0x118b384f, 0xe0dd8a9a, 0x2b81593f, + 0xad152b91, 0x6649f834, 0x7b4cc88c, 0xb0101b29, 0x36846987, + 0xfdd8ba22, 0x08f40f5a, 0xc3a8dcff, 0x453cae51, 0x8e607df4, + 0x93654d4c, 0x58399ee9, 0xdeadec47, 0x15f13fe2, 0xe4a78d37, + 0x2ffb5e92, 0xa96f2c3c, 0x6233ff99, 0x7f36cf21, 0xb46a1c84, + 0x32fe6e2a, 0xf9a2bd8f, 0x0b220dc1, 0xc07ede64, 0x46eaacca, + 0x8db67f6f, 0x90b34fd7, 0x5bef9c72, 0xdd7beedc, 0x16273d79, + 0xe7718fac, 0x2c2d5c09, 0xaab92ea7, 0x61e5fd02, 0x7ce0cdba, + 0xb7bc1e1f, 0x31286cb1, 0xfa74bf14, 0x1eb014d8, 0xd5ecc77d, + 0x5378b5d3, 0x98246676, 0x852156ce, 0x4e7d856b, 0xc8e9f7c5, + 0x03b52460, 0xf2e396b5, 0x39bf4510, 0xbf2b37be, 0x7477e41b, + 0x6972d4a3, 0xa22e0706, 0x24ba75a8, 0xefe6a60d, 0x1d661643, + 0xd63ac5e6, 0x50aeb748, 0x9bf264ed, 0x86f75455, 0x4dab87f0, + 0xcb3ff55e, 0x006326fb, 0xf135942e, 0x3a69478b, 0xbcfd3525, + 0x77a1e680, 0x6aa4d638, 0xa1f8059d, 0x276c7733, 0xec30a496, + 0x191c11ee, 0xd240c24b, 0x54d4b0e5, 0x9f886340, 0x828d53f8, + 0x49d1805d, 0xcf45f2f3, 0x04192156, 0xf54f9383, 0x3e134026, + 0xb8873288, 0x73dbe12d, 0x6eded195, 0xa5820230, 0x2316709e, + 0xe84aa33b, 0x1aca1375, 0xd196c0d0, 0x5702b27e, 0x9c5e61db, + 0x815b5163, 0x4a0782c6, 0xcc93f068, 0x07cf23cd, 0xf6999118, + 0x3dc542bd, 0xbb513013, 0x700de3b6, 0x6d08d30e, 0xa65400ab, + 0x20c07205, 0xeb9ca1a0, 0x11e81eb4, 0xdab4cd11, 0x5c20bfbf, + 0x977c6c1a, 0x8a795ca2, 0x41258f07, 0xc7b1fda9, 0x0ced2e0c, + 0xfdbb9cd9, 0x36e74f7c, 0xb0733dd2, 0x7b2fee77, 0x662adecf, + 0xad760d6a, 0x2be27fc4, 0xe0beac61, 0x123e1c2f, 0xd962cf8a, + 0x5ff6bd24, 0x94aa6e81, 0x89af5e39, 0x42f38d9c, 0xc467ff32, + 0x0f3b2c97, 0xfe6d9e42, 0x35314de7, 0xb3a53f49, 0x78f9ecec, + 0x65fcdc54, 0xaea00ff1, 0x28347d5f, 0xe368aefa, 0x16441b82, + 0xdd18c827, 0x5b8cba89, 0x90d0692c, 0x8dd55994, 0x46898a31, + 0xc01df89f, 0x0b412b3a, 0xfa1799ef, 0x314b4a4a, 0xb7df38e4, + 0x7c83eb41, 0x6186dbf9, 0xaada085c, 0x2c4e7af2, 0xe712a957, + 0x15921919, 0xdececabc, 0x585ab812, 0x93066bb7, 0x8e035b0f, + 0x455f88aa, 0xc3cbfa04, 0x089729a1, 0xf9c19b74, 0x329d48d1, + 0xb4093a7f, 0x7f55e9da, 0x6250d962, 0xa90c0ac7, 0x2f987869, + 0xe4c4abcc}, + {0x00000000, 0x3d6029b0, 0x7ac05360, 0x47a07ad0, 0xf580a6c0, + 0xc8e08f70, 0x8f40f5a0, 0xb220dc10, 0x30704bc1, 0x0d106271, + 0x4ab018a1, 0x77d03111, 0xc5f0ed01, 0xf890c4b1, 0xbf30be61, + 0x825097d1, 0x60e09782, 0x5d80be32, 0x1a20c4e2, 0x2740ed52, + 0x95603142, 0xa80018f2, 0xefa06222, 0xd2c04b92, 0x5090dc43, + 0x6df0f5f3, 0x2a508f23, 0x1730a693, 0xa5107a83, 0x98705333, + 0xdfd029e3, 0xe2b00053, 0xc1c12f04, 0xfca106b4, 0xbb017c64, + 0x866155d4, 0x344189c4, 0x0921a074, 0x4e81daa4, 0x73e1f314, + 0xf1b164c5, 0xccd14d75, 0x8b7137a5, 0xb6111e15, 0x0431c205, + 0x3951ebb5, 0x7ef19165, 0x4391b8d5, 0xa121b886, 0x9c419136, + 0xdbe1ebe6, 0xe681c256, 0x54a11e46, 0x69c137f6, 0x2e614d26, + 0x13016496, 0x9151f347, 0xac31daf7, 0xeb91a027, 0xd6f18997, + 0x64d15587, 0x59b17c37, 0x1e1106e7, 0x23712f57, 0x58f35849, + 0x659371f9, 0x22330b29, 0x1f532299, 0xad73fe89, 0x9013d739, + 0xd7b3ade9, 0xead38459, 0x68831388, 0x55e33a38, 0x124340e8, + 0x2f236958, 0x9d03b548, 0xa0639cf8, 0xe7c3e628, 0xdaa3cf98, + 0x3813cfcb, 0x0573e67b, 0x42d39cab, 0x7fb3b51b, 0xcd93690b, + 0xf0f340bb, 0xb7533a6b, 0x8a3313db, 0x0863840a, 0x3503adba, + 0x72a3d76a, 0x4fc3feda, 0xfde322ca, 0xc0830b7a, 0x872371aa, + 0xba43581a, 0x9932774d, 0xa4525efd, 0xe3f2242d, 0xde920d9d, + 0x6cb2d18d, 0x51d2f83d, 0x167282ed, 0x2b12ab5d, 0xa9423c8c, + 0x9422153c, 0xd3826fec, 0xeee2465c, 0x5cc29a4c, 0x61a2b3fc, + 0x2602c92c, 0x1b62e09c, 0xf9d2e0cf, 0xc4b2c97f, 0x8312b3af, + 0xbe729a1f, 0x0c52460f, 0x31326fbf, 0x7692156f, 0x4bf23cdf, + 0xc9a2ab0e, 0xf4c282be, 0xb362f86e, 0x8e02d1de, 0x3c220dce, + 0x0142247e, 0x46e25eae, 0x7b82771e, 0xb1e6b092, 0x8c869922, + 0xcb26e3f2, 0xf646ca42, 0x44661652, 0x79063fe2, 0x3ea64532, + 0x03c66c82, 0x8196fb53, 0xbcf6d2e3, 0xfb56a833, 0xc6368183, + 0x74165d93, 0x49767423, 0x0ed60ef3, 0x33b62743, 0xd1062710, + 0xec660ea0, 0xabc67470, 0x96a65dc0, 0x248681d0, 0x19e6a860, + 0x5e46d2b0, 0x6326fb00, 0xe1766cd1, 0xdc164561, 0x9bb63fb1, + 0xa6d61601, 0x14f6ca11, 0x2996e3a1, 0x6e369971, 0x5356b0c1, + 0x70279f96, 0x4d47b626, 0x0ae7ccf6, 0x3787e546, 0x85a73956, + 0xb8c710e6, 0xff676a36, 0xc2074386, 0x4057d457, 0x7d37fde7, + 0x3a978737, 0x07f7ae87, 0xb5d77297, 0x88b75b27, 0xcf1721f7, + 0xf2770847, 0x10c70814, 0x2da721a4, 0x6a075b74, 0x576772c4, + 0xe547aed4, 0xd8278764, 0x9f87fdb4, 0xa2e7d404, 0x20b743d5, + 0x1dd76a65, 0x5a7710b5, 0x67173905, 0xd537e515, 0xe857cca5, + 0xaff7b675, 0x92979fc5, 0xe915e8db, 0xd475c16b, 0x93d5bbbb, + 0xaeb5920b, 0x1c954e1b, 0x21f567ab, 0x66551d7b, 0x5b3534cb, + 0xd965a31a, 0xe4058aaa, 0xa3a5f07a, 0x9ec5d9ca, 0x2ce505da, + 0x11852c6a, 0x562556ba, 0x6b457f0a, 0x89f57f59, 0xb49556e9, + 0xf3352c39, 0xce550589, 0x7c75d999, 0x4115f029, 0x06b58af9, + 0x3bd5a349, 0xb9853498, 0x84e51d28, 0xc34567f8, 0xfe254e48, + 0x4c059258, 0x7165bbe8, 0x36c5c138, 0x0ba5e888, 0x28d4c7df, + 0x15b4ee6f, 0x521494bf, 0x6f74bd0f, 0xdd54611f, 0xe03448af, + 0xa794327f, 0x9af41bcf, 0x18a48c1e, 0x25c4a5ae, 0x6264df7e, + 0x5f04f6ce, 0xed242ade, 0xd044036e, 0x97e479be, 0xaa84500e, + 0x4834505d, 0x755479ed, 0x32f4033d, 0x0f942a8d, 0xbdb4f69d, + 0x80d4df2d, 0xc774a5fd, 0xfa148c4d, 0x78441b9c, 0x4524322c, + 0x028448fc, 0x3fe4614c, 0x8dc4bd5c, 0xb0a494ec, 0xf704ee3c, + 0xca64c78c}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, 0xc0a680f5, + 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, 0xc14b7030, 0x7162100d, + 0xa118b04a, 0x1131d077, 0x01edf0c5, 0xb1c490f8, 0x61be30bf, + 0xd1975082, 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, 0x43dc9050, + 0xf3f5f06d, 0x238f502a, 0x93a63017, 0x837a10a5, 0x33537098, + 0xe329d0df, 0x5300b0e2, 0x042fc1c1, 0xb406a1fc, 0x647c01bb, + 0xd4556186, 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, 0x05c23104, + 0xb5eb5139, 0x6591f17e, 0xd5b89143, 0x86b821a1, 0x3691419c, + 0xe6ebe1db, 0x56c281e6, 0x461ea154, 0xf637c169, 0x264d612e, + 0x96640113, 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, 0x4958f358, + 0xf9719365, 0x290b3322, 0x9922531f, 0x89fe73ad, 0x39d71390, + 0xe9adb3d7, 0x5984d3ea, 0x88138368, 0x383ae355, 0xe8404312, + 0x5869232f, 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, 0x0b6993cd, + 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, 0x0a846308, 0xbaad0335, + 0x6ad7a372, 0xdafec34f, 0xca22e3fd, 0x7a0b83c0, 0xaa712387, + 0x1a5843ba, 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, 0x8c3c42a9, + 0x3c152294, 0xec6f82d3, 0x5c46e2ee, 0x4c9ac25c, 0xfcb3a261, + 0x2cc90226, 0x9ce0621b, 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, + 0x1f9a72be, 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, 0xce0d223c, + 0x7e244201, 0xae5ee246, 0x1e77827b, 0x92b0e6b1, 0x2299868c, + 0xf2e326cb, 0x42ca46f6, 0x52166644, 0xe23f0679, 0x3245a63e, + 0x826cc603, 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, 0x102706d1, + 0xa00e66ec, 0x7074c6ab, 0xc05da696, 0xd0818624, 0x60a8e619, + 0xb0d2465e, 0x00fb2663, 0xd16c76e1, 0x614516dc, 0xb13fb69b, + 0x0116d6a6, 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, 0x5639a785, + 0xe610c7b8, 0x366a67ff, 0x864307c2, 0x57d45740, 0xe7fd377d, + 0x3787973a, 0x87aef707, 0x9772d7b5, 0x275bb788, 0xf72117cf, + 0x470877f2, 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, 0xd543b720, + 0x656ad71d, 0xb510775a, 0x05391767, 0x15e537d5, 0xa5cc57e8, + 0x75b6f7af, 0xc59f9792, 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, + 0x0b92b5ae, 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, 0xda05e52c, + 0x6a2c8511, 0xba562556, 0x0a7f456b, 0x597ff589, 0xe95695b4, + 0x392c35f3, 0x890555ce, 0x99d9757c, 0x29f01541, 0xf98ab506, + 0x49a3d53b, 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, 0xdfc7d428, + 0x6feeb415, 0xbf941452, 0x0fbd746f, 0x1f6154dd, 0xaf4834e0, + 0x7f3294a7, 0xcf1bf49a, 0x1e8ca418, 0xaea5c425, 0x7edf6462, + 0xcef6045f, 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, 0x9df6b4bd, + 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, 0x9c1b4478, 0x2c322445, + 0xfc488402, 0x4c61e43f, 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, + 0x8cc764ca}, + {0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, 0x1642919b, + 0xb391cd50, 0x1de359d6, 0xb830051d, 0x6d8253ec, 0xc8510f27, + 0x66239ba1, 0xc3f0c76a, 0x7bc0c277, 0xde139ebc, 0x70610a3a, + 0xd5b256f1, 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, 0xf68085ef, + 0x5353d924, 0xfd214da2, 0x58f21169, 0xe0c21474, 0x451148bf, + 0xeb63dc39, 0x4eb080f2, 0x3605ac07, 0x93d6f0cc, 0x3da4644a, + 0x98773881, 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, 0x4dc56e70, + 0xe81632bb, 0x4664a63d, 0xe3b7faf6, 0xad077a04, 0x08d426cf, + 0xa6a6b249, 0x0375ee82, 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, + 0x15377f19, 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, 0x6c0a580f, + 0xc9d904c4, 0x67ab9042, 0xc278cc89, 0x7a48c994, 0xdf9b955f, + 0x71e901d9, 0xd43a5d12, 0x01880be3, 0xa45b5728, 0x0a29c3ae, + 0xaffa9f65, 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, 0xe14a1f97, + 0x4499435c, 0xeaebd7da, 0x4f388b11, 0x9a8adde0, 0x3f59812b, + 0x912b15ad, 0x34f84966, 0x8cc84c7b, 0x291b10b0, 0x87698436, + 0x22bad8fd, 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, 0x378da7e4, + 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, 0x21cf367f, 0x841c6ab4, + 0x2a6efe32, 0x8fbda2f9, 0xc10d220b, 0x64de7ec0, 0xcaacea46, + 0x6f7fb68d, 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, 0xbacde07c, + 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, 0xd814b01e, 0x7dc7ecd5, + 0xd3b57853, 0x76662498, 0xce562185, 0x6b857d4e, 0xc5f7e9c8, + 0x6024b503, 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, 0x4316661d, + 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, 0x5554f786, 0xf087ab4d, + 0x5ef53fcb, 0xfb266300, 0x2e9435f1, 0x8b47693a, 0x2535fdbc, + 0x80e6a177, 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, 0xf8538d82, + 0x5d80d149, 0xf3f245cf, 0x56211904, 0x83934ff5, 0x2640133e, + 0x883287b8, 0x2de1db73, 0x95d1de6e, 0x300282a5, 0x9e701623, + 0x3ba34ae8, 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, 0x189199f6, + 0xbd42c53d, 0x133051bb, 0xb6e30d70, 0x0ed3086d, 0xab0054a6, + 0x0572c020, 0xa0a19ceb, 0xb41ee811, 0x11cdb4da, 0xbfbf205c, + 0x1a6c7c97, 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, 0xcfde2a66, + 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, 0x2f1c3e12, 0x8acf62d9, + 0x24bdf65f, 0x816eaa94, 0x395eaf89, 0x9c8df342, 0x32ff67c4, + 0x972c3b0f, 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, 0x821b4416, + 0x27c818dd, 0x89ba8c5b, 0x2c69d090, 0x9459d58d, 0x318a8946, + 0x9ff81dc0, 0x3a2b410b, 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, + 0x41eb837c, 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, 0x0f5b038e, + 0xaa885f45, 0x04facbc3, 0xa1299708, 0x749bc1f9, 0xd1489d32, + 0x7f3a09b4, 0xdae9557f, 0x62d95062, 0xc70a0ca9, 0x6978982f, + 0xccabc4e4}, + {0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, 0x13244ff4, + 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, 0x674eef33, 0xd3459895, + 0x4e5f70a4, 0xfa540702, 0x746aa0c7, 0xc061d761, 0x5d7b3f50, + 0xe97048f6, 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, 0xa9d23154, + 0x1dd946f2, 0x80c3aec3, 0x34c8d965, 0xbaf67ea0, 0x0efd0906, + 0x93e7e137, 0x27ec9691, 0x9c39bdcf, 0x2832ca69, 0xb5282258, + 0x012355fe, 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, 0xe8531d08, + 0x5c586aae, 0xc142829f, 0x7549f539, 0x52a563a8, 0xe6ae140e, + 0x7bb4fc3f, 0xcfbf8b99, 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, + 0xdc9bc46d, 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, 0x79750b44, + 0xcd7e7ce2, 0x506494d3, 0xe46fe375, 0x6a5144b0, 0xde5a3316, + 0x4340db27, 0xf74bac81, 0x1e3be477, 0xaa3093d1, 0x372a7be0, + 0x83210c46, 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, 0xa4cd9ad7, + 0x10c6ed71, 0x8ddc0540, 0x39d772e6, 0xd0a73a10, 0x64ac4db6, + 0xf9b6a587, 0x4dbdd221, 0xc38375e4, 0x77880242, 0xea92ea73, + 0x5e999dd5, 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, 0x820259b8, + 0x36092e1e, 0xab13c62f, 0x1f18b189, 0x9126164c, 0x252d61ea, + 0xb83789db, 0x0c3cfe7d, 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, + 0xb6ca80dd, 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, 0x5fbac82b, + 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, 0xf2ea1688, 0x46e1612e, + 0xdbfb891f, 0x6ff0feb9, 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, + 0x7cd4b14d, 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, 0x3c76c8ef, + 0x887dbf49, 0x15675778, 0xa16c20de, 0x2f52871b, 0x9b59f0bd, + 0x0643188c, 0xb2486f2a, 0x5b3827dc, 0xef33507a, 0x7229b84b, + 0xc622cfed, 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, 0x7df7e4b3, + 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, 0x099d4474, 0xbd9633d2, + 0x208cdbe3, 0x9487ac45, 0x1ab90b80, 0xaeb27c26, 0x33a89417, + 0x87a3e3b1, 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, 0xc7019a13, + 0x730aedb5, 0xee100584, 0x5a1b7222, 0xd425d5e7, 0x602ea241, + 0xfd344a70, 0x493f3dd6, 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, + 0x1685f5fd, 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, 0xfff5bd0b, + 0x4bfecaad, 0xd6e4229c, 0x62ef553a, 0x4503c3ab, 0xf108b40d, + 0x6c125c3c, 0xd8192b9a, 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, + 0xcb3d646e, 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, 0x17a6a003, + 0xa3add7a5, 0x3eb73f94, 0x8abc4832, 0x0482eff7, 0xb0899851, + 0x2d937060, 0x999807c6, 0x70e84f30, 0xc4e33896, 0x59f9d0a7, + 0xedf2a701, 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, 0xca1e3190, + 0x7e154636, 0xe30fae07, 0x5704d9a1, 0xbe749157, 0x0a7fe6f1, + 0x97650ec0, 0x236e7966, 0xad50dea3, 0x195ba905, 0x84414134, + 0x304a3692}, + {0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, 0xfa0e4a84, + 0x640ee048, 0x87096fc6, 0x1909c50a, 0xb51be5d3, 0x2b1b4f1f, + 0xc81cc091, 0x561c6a5d, 0x4f15af57, 0xd115059b, 0x32128a15, + 0xac1220d9, 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, 0x9e2a5eaf, + 0x002af463, 0xe32d7bed, 0x7d2dd121, 0x6424142b, 0xfa24bee7, + 0x19233169, 0x87239ba5, 0x566276f9, 0xc862dc35, 0x2b6553bb, + 0xb565f977, 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, 0x1977d9ae, + 0x87777362, 0x6470fcec, 0xfa705620, 0x7d53cd85, 0xe3536749, + 0x0054e8c7, 0x9e54420b, 0x875d8701, 0x195d2dcd, 0xfa5aa243, + 0x645a088f, 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, 0xedc29d29, + 0x73c237e5, 0x90c5b86b, 0x0ec512a7, 0x17ccd7ad, 0x89cc7d61, + 0x6acbf2ef, 0xf4cb5823, 0x58d978fa, 0xc6d9d236, 0x25de5db8, + 0xbbdef774, 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, 0x3cfd6cd1, + 0xa2fdc61d, 0x41fa4993, 0xdffae35f, 0x73e8c386, 0xede8694a, + 0x0eefe6c4, 0x90ef4c08, 0x89e68902, 0x17e623ce, 0xf4e1ac40, + 0x6ae1068c, 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, 0x0ebb0e03, + 0x90bba4cf, 0x73bc2b41, 0xedbc818d, 0xf4b54487, 0x6ab5ee4b, + 0x89b261c5, 0x17b2cb09, 0x909150ac, 0x0e91fa60, 0xed9675ee, + 0x7396df22, 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, 0xdf84fffb, + 0x41845537, 0xa283dab9, 0x3c837075, 0xda853b53, 0x4485919f, + 0xa7821e11, 0x3982b4dd, 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, + 0xc38cfe59, 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, 0xf1b4802f, + 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, 0x0bbacaab, 0x95ba6067, + 0x76bdefe9, 0xe8bd4525, 0x44af65fc, 0xdaafcf30, 0x39a840be, + 0xa7a8ea72, 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, 0x76e9072e, + 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, 0x39fca879, 0xa7fc02b5, + 0x44fb8d3b, 0xdafb27f7, 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, + 0x20f56d73, 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, 0x12cd1305, + 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, 0xe8c35981, 0x76c3f34d, + 0x95c47cc3, 0x0bc4d60f, 0x3747a67a, 0xa9470cb6, 0x4a408338, + 0xd44029f4, 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, 0x7852092d, + 0xe652a3e1, 0x05552c6f, 0x9b5586a3, 0x1c761d06, 0x8276b7ca, + 0x61713844, 0xff719288, 0xe6785782, 0x7878fd4e, 0x9b7f72c0, + 0x057fd80c, 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, 0x6125d083, + 0xff257a4f, 0x1c22f5c1, 0x82225f0d, 0x9b2b9a07, 0x052b30cb, + 0xe62cbf45, 0x782c1589, 0xd43e3550, 0x4a3e9f9c, 0xa9391012, + 0x3739bade, 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, 0xb01a217b, + 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, 0xff0f8e2c, 0x610f24e0, + 0x8208ab6e, 0x1c0801a2, 0x0501c4a8, 0x9b016e64, 0x7806e1ea, + 0xe6064b26}}; + +#endif /* W */ + +#endif /* N == 2 */ +#if N == 3 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}, + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x43cba68700000000, 0xc7903cd400000000, + 0x845b9a5300000000, 0xcf27087300000000, 0x8cecaef400000000, + 0x08b734a700000000, 0x4b7c922000000000, 0x9e4f10e600000000, + 0xdd84b66100000000, 0x59df2c3200000000, 0x1a148ab500000000, + 0x5168189500000000, 0x12a3be1200000000, 0x96f8244100000000, + 0xd53382c600000000, 0x7d99511700000000, 0x3e52f79000000000, + 0xba096dc300000000, 0xf9c2cb4400000000, 0xb2be596400000000, + 0xf175ffe300000000, 0x752e65b000000000, 0x36e5c33700000000, + 0xe3d641f100000000, 0xa01de77600000000, 0x24467d2500000000, + 0x678ddba200000000, 0x2cf1498200000000, 0x6f3aef0500000000, + 0xeb61755600000000, 0xa8aad3d100000000, 0xfa32a32e00000000, + 0xb9f905a900000000, 0x3da29ffa00000000, 0x7e69397d00000000, + 0x3515ab5d00000000, 0x76de0dda00000000, 0xf285978900000000, + 0xb14e310e00000000, 0x647db3c800000000, 0x27b6154f00000000, + 0xa3ed8f1c00000000, 0xe026299b00000000, 0xab5abbbb00000000, + 0xe8911d3c00000000, 0x6cca876f00000000, 0x2f0121e800000000, + 0x87abf23900000000, 0xc46054be00000000, 0x403bceed00000000, + 0x03f0686a00000000, 0x488cfa4a00000000, 0x0b475ccd00000000, + 0x8f1cc69e00000000, 0xccd7601900000000, 0x19e4e2df00000000, + 0x5a2f445800000000, 0xde74de0b00000000, 0x9dbf788c00000000, + 0xd6c3eaac00000000, 0x95084c2b00000000, 0x1153d67800000000, + 0x529870ff00000000, 0xf465465d00000000, 0xb7aee0da00000000, + 0x33f57a8900000000, 0x703edc0e00000000, 0x3b424e2e00000000, + 0x7889e8a900000000, 0xfcd272fa00000000, 0xbf19d47d00000000, + 0x6a2a56bb00000000, 0x29e1f03c00000000, 0xadba6a6f00000000, + 0xee71cce800000000, 0xa50d5ec800000000, 0xe6c6f84f00000000, + 0x629d621c00000000, 0x2156c49b00000000, 0x89fc174a00000000, + 0xca37b1cd00000000, 0x4e6c2b9e00000000, 0x0da78d1900000000, + 0x46db1f3900000000, 0x0510b9be00000000, 0x814b23ed00000000, + 0xc280856a00000000, 0x17b307ac00000000, 0x5478a12b00000000, + 0xd0233b7800000000, 0x93e89dff00000000, 0xd8940fdf00000000, + 0x9b5fa95800000000, 0x1f04330b00000000, 0x5ccf958c00000000, + 0x0e57e57300000000, 0x4d9c43f400000000, 0xc9c7d9a700000000, + 0x8a0c7f2000000000, 0xc170ed0000000000, 0x82bb4b8700000000, + 0x06e0d1d400000000, 0x452b775300000000, 0x9018f59500000000, + 0xd3d3531200000000, 0x5788c94100000000, 0x14436fc600000000, + 0x5f3ffde600000000, 0x1cf45b6100000000, 0x98afc13200000000, + 0xdb6467b500000000, 0x73ceb46400000000, 0x300512e300000000, + 0xb45e88b000000000, 0xf7952e3700000000, 0xbce9bc1700000000, + 0xff221a9000000000, 0x7b7980c300000000, 0x38b2264400000000, + 0xed81a48200000000, 0xae4a020500000000, 0x2a11985600000000, + 0x69da3ed100000000, 0x22a6acf100000000, 0x616d0a7600000000, + 0xe536902500000000, 0xa6fd36a200000000, 0xe8cb8cba00000000, + 0xab002a3d00000000, 0x2f5bb06e00000000, 0x6c9016e900000000, + 0x27ec84c900000000, 0x6427224e00000000, 0xe07cb81d00000000, + 0xa3b71e9a00000000, 0x76849c5c00000000, 0x354f3adb00000000, + 0xb114a08800000000, 0xf2df060f00000000, 0xb9a3942f00000000, + 0xfa6832a800000000, 0x7e33a8fb00000000, 0x3df80e7c00000000, + 0x9552ddad00000000, 0xd6997b2a00000000, 0x52c2e17900000000, + 0x110947fe00000000, 0x5a75d5de00000000, 0x19be735900000000, + 0x9de5e90a00000000, 0xde2e4f8d00000000, 0x0b1dcd4b00000000, + 0x48d66bcc00000000, 0xcc8df19f00000000, 0x8f46571800000000, + 0xc43ac53800000000, 0x87f163bf00000000, 0x03aaf9ec00000000, + 0x40615f6b00000000, 0x12f92f9400000000, 0x5132891300000000, + 0xd569134000000000, 0x96a2b5c700000000, 0xddde27e700000000, + 0x9e15816000000000, 0x1a4e1b3300000000, 0x5985bdb400000000, + 0x8cb63f7200000000, 0xcf7d99f500000000, 0x4b2603a600000000, + 0x08eda52100000000, 0x4391370100000000, 0x005a918600000000, + 0x84010bd500000000, 0xc7caad5200000000, 0x6f607e8300000000, + 0x2cabd80400000000, 0xa8f0425700000000, 0xeb3be4d000000000, + 0xa04776f000000000, 0xe38cd07700000000, 0x67d74a2400000000, + 0x241ceca300000000, 0xf12f6e6500000000, 0xb2e4c8e200000000, + 0x36bf52b100000000, 0x7574f43600000000, 0x3e08661600000000, + 0x7dc3c09100000000, 0xf9985ac200000000, 0xba53fc4500000000, + 0x1caecae700000000, 0x5f656c6000000000, 0xdb3ef63300000000, + 0x98f550b400000000, 0xd389c29400000000, 0x9042641300000000, + 0x1419fe4000000000, 0x57d258c700000000, 0x82e1da0100000000, + 0xc12a7c8600000000, 0x4571e6d500000000, 0x06ba405200000000, + 0x4dc6d27200000000, 0x0e0d74f500000000, 0x8a56eea600000000, + 0xc99d482100000000, 0x61379bf000000000, 0x22fc3d7700000000, + 0xa6a7a72400000000, 0xe56c01a300000000, 0xae10938300000000, + 0xeddb350400000000, 0x6980af5700000000, 0x2a4b09d000000000, + 0xff788b1600000000, 0xbcb32d9100000000, 0x38e8b7c200000000, + 0x7b23114500000000, 0x305f836500000000, 0x739425e200000000, + 0xf7cfbfb100000000, 0xb404193600000000, 0xe69c69c900000000, + 0xa557cf4e00000000, 0x210c551d00000000, 0x62c7f39a00000000, + 0x29bb61ba00000000, 0x6a70c73d00000000, 0xee2b5d6e00000000, + 0xade0fbe900000000, 0x78d3792f00000000, 0x3b18dfa800000000, + 0xbf4345fb00000000, 0xfc88e37c00000000, 0xb7f4715c00000000, + 0xf43fd7db00000000, 0x70644d8800000000, 0x33afeb0f00000000, + 0x9b0538de00000000, 0xd8ce9e5900000000, 0x5c95040a00000000, + 0x1f5ea28d00000000, 0x542230ad00000000, 0x17e9962a00000000, + 0x93b20c7900000000, 0xd079aafe00000000, 0x054a283800000000, + 0x46818ebf00000000, 0xc2da14ec00000000, 0x8111b26b00000000, + 0xca6d204b00000000, 0x89a686cc00000000, 0x0dfd1c9f00000000, + 0x4e36ba1800000000}, + {0x0000000000000000, 0xe1b652ef00000000, 0x836bd40500000000, + 0x62dd86ea00000000, 0x06d7a80b00000000, 0xe761fae400000000, + 0x85bc7c0e00000000, 0x640a2ee100000000, 0x0cae511700000000, + 0xed1803f800000000, 0x8fc5851200000000, 0x6e73d7fd00000000, + 0x0a79f91c00000000, 0xebcfabf300000000, 0x89122d1900000000, + 0x68a47ff600000000, 0x185ca32e00000000, 0xf9eaf1c100000000, + 0x9b37772b00000000, 0x7a8125c400000000, 0x1e8b0b2500000000, + 0xff3d59ca00000000, 0x9de0df2000000000, 0x7c568dcf00000000, + 0x14f2f23900000000, 0xf544a0d600000000, 0x9799263c00000000, + 0x762f74d300000000, 0x12255a3200000000, 0xf39308dd00000000, + 0x914e8e3700000000, 0x70f8dcd800000000, 0x30b8465d00000000, + 0xd10e14b200000000, 0xb3d3925800000000, 0x5265c0b700000000, + 0x366fee5600000000, 0xd7d9bcb900000000, 0xb5043a5300000000, + 0x54b268bc00000000, 0x3c16174a00000000, 0xdda045a500000000, + 0xbf7dc34f00000000, 0x5ecb91a000000000, 0x3ac1bf4100000000, + 0xdb77edae00000000, 0xb9aa6b4400000000, 0x581c39ab00000000, + 0x28e4e57300000000, 0xc952b79c00000000, 0xab8f317600000000, + 0x4a39639900000000, 0x2e334d7800000000, 0xcf851f9700000000, + 0xad58997d00000000, 0x4ceecb9200000000, 0x244ab46400000000, + 0xc5fce68b00000000, 0xa721606100000000, 0x4697328e00000000, + 0x229d1c6f00000000, 0xc32b4e8000000000, 0xa1f6c86a00000000, + 0x40409a8500000000, 0x60708dba00000000, 0x81c6df5500000000, + 0xe31b59bf00000000, 0x02ad0b5000000000, 0x66a725b100000000, + 0x8711775e00000000, 0xe5ccf1b400000000, 0x047aa35b00000000, + 0x6cdedcad00000000, 0x8d688e4200000000, 0xefb508a800000000, + 0x0e035a4700000000, 0x6a0974a600000000, 0x8bbf264900000000, + 0xe962a0a300000000, 0x08d4f24c00000000, 0x782c2e9400000000, + 0x999a7c7b00000000, 0xfb47fa9100000000, 0x1af1a87e00000000, + 0x7efb869f00000000, 0x9f4dd47000000000, 0xfd90529a00000000, + 0x1c26007500000000, 0x74827f8300000000, 0x95342d6c00000000, + 0xf7e9ab8600000000, 0x165ff96900000000, 0x7255d78800000000, + 0x93e3856700000000, 0xf13e038d00000000, 0x1088516200000000, + 0x50c8cbe700000000, 0xb17e990800000000, 0xd3a31fe200000000, + 0x32154d0d00000000, 0x561f63ec00000000, 0xb7a9310300000000, + 0xd574b7e900000000, 0x34c2e50600000000, 0x5c669af000000000, + 0xbdd0c81f00000000, 0xdf0d4ef500000000, 0x3ebb1c1a00000000, + 0x5ab132fb00000000, 0xbb07601400000000, 0xd9dae6fe00000000, + 0x386cb41100000000, 0x489468c900000000, 0xa9223a2600000000, + 0xcbffbccc00000000, 0x2a49ee2300000000, 0x4e43c0c200000000, + 0xaff5922d00000000, 0xcd2814c700000000, 0x2c9e462800000000, + 0x443a39de00000000, 0xa58c6b3100000000, 0xc751eddb00000000, + 0x26e7bf3400000000, 0x42ed91d500000000, 0xa35bc33a00000000, + 0xc18645d000000000, 0x2030173f00000000, 0x81e66bae00000000, + 0x6050394100000000, 0x028dbfab00000000, 0xe33bed4400000000, + 0x8731c3a500000000, 0x6687914a00000000, 0x045a17a000000000, + 0xe5ec454f00000000, 0x8d483ab900000000, 0x6cfe685600000000, + 0x0e23eebc00000000, 0xef95bc5300000000, 0x8b9f92b200000000, + 0x6a29c05d00000000, 0x08f446b700000000, 0xe942145800000000, + 0x99bac88000000000, 0x780c9a6f00000000, 0x1ad11c8500000000, + 0xfb674e6a00000000, 0x9f6d608b00000000, 0x7edb326400000000, + 0x1c06b48e00000000, 0xfdb0e66100000000, 0x9514999700000000, + 0x74a2cb7800000000, 0x167f4d9200000000, 0xf7c91f7d00000000, + 0x93c3319c00000000, 0x7275637300000000, 0x10a8e59900000000, + 0xf11eb77600000000, 0xb15e2df300000000, 0x50e87f1c00000000, + 0x3235f9f600000000, 0xd383ab1900000000, 0xb78985f800000000, + 0x563fd71700000000, 0x34e251fd00000000, 0xd554031200000000, + 0xbdf07ce400000000, 0x5c462e0b00000000, 0x3e9ba8e100000000, + 0xdf2dfa0e00000000, 0xbb27d4ef00000000, 0x5a91860000000000, + 0x384c00ea00000000, 0xd9fa520500000000, 0xa9028edd00000000, + 0x48b4dc3200000000, 0x2a695ad800000000, 0xcbdf083700000000, + 0xafd526d600000000, 0x4e63743900000000, 0x2cbef2d300000000, + 0xcd08a03c00000000, 0xa5acdfca00000000, 0x441a8d2500000000, + 0x26c70bcf00000000, 0xc771592000000000, 0xa37b77c100000000, + 0x42cd252e00000000, 0x2010a3c400000000, 0xc1a6f12b00000000, + 0xe196e61400000000, 0x0020b4fb00000000, 0x62fd321100000000, + 0x834b60fe00000000, 0xe7414e1f00000000, 0x06f71cf000000000, + 0x642a9a1a00000000, 0x859cc8f500000000, 0xed38b70300000000, + 0x0c8ee5ec00000000, 0x6e53630600000000, 0x8fe531e900000000, + 0xebef1f0800000000, 0x0a594de700000000, 0x6884cb0d00000000, + 0x893299e200000000, 0xf9ca453a00000000, 0x187c17d500000000, + 0x7aa1913f00000000, 0x9b17c3d000000000, 0xff1ded3100000000, + 0x1eabbfde00000000, 0x7c76393400000000, 0x9dc06bdb00000000, + 0xf564142d00000000, 0x14d246c200000000, 0x760fc02800000000, + 0x97b992c700000000, 0xf3b3bc2600000000, 0x1205eec900000000, + 0x70d8682300000000, 0x916e3acc00000000, 0xd12ea04900000000, + 0x3098f2a600000000, 0x5245744c00000000, 0xb3f326a300000000, + 0xd7f9084200000000, 0x364f5aad00000000, 0x5492dc4700000000, + 0xb5248ea800000000, 0xdd80f15e00000000, 0x3c36a3b100000000, + 0x5eeb255b00000000, 0xbf5d77b400000000, 0xdb57595500000000, + 0x3ae10bba00000000, 0x583c8d5000000000, 0xb98adfbf00000000, + 0xc972036700000000, 0x28c4518800000000, 0x4a19d76200000000, + 0xabaf858d00000000, 0xcfa5ab6c00000000, 0x2e13f98300000000, + 0x4cce7f6900000000, 0xad782d8600000000, 0xc5dc527000000000, + 0x246a009f00000000, 0x46b7867500000000, 0xa701d49a00000000, + 0xc30bfa7b00000000, 0x22bda89400000000, 0x40602e7e00000000, + 0xa1d67c9100000000}, + {0x0000000000000000, 0x5880e2d700000000, 0xf106b47400000000, + 0xa98656a300000000, 0xe20d68e900000000, 0xba8d8a3e00000000, + 0x130bdc9d00000000, 0x4b8b3e4a00000000, 0x851da10900000000, + 0xdd9d43de00000000, 0x741b157d00000000, 0x2c9bf7aa00000000, + 0x6710c9e000000000, 0x3f902b3700000000, 0x96167d9400000000, + 0xce969f4300000000, 0x0a3b421300000000, 0x52bba0c400000000, + 0xfb3df66700000000, 0xa3bd14b000000000, 0xe8362afa00000000, + 0xb0b6c82d00000000, 0x19309e8e00000000, 0x41b07c5900000000, + 0x8f26e31a00000000, 0xd7a601cd00000000, 0x7e20576e00000000, + 0x26a0b5b900000000, 0x6d2b8bf300000000, 0x35ab692400000000, + 0x9c2d3f8700000000, 0xc4addd5000000000, 0x1476842600000000, + 0x4cf666f100000000, 0xe570305200000000, 0xbdf0d28500000000, + 0xf67beccf00000000, 0xaefb0e1800000000, 0x077d58bb00000000, + 0x5ffdba6c00000000, 0x916b252f00000000, 0xc9ebc7f800000000, + 0x606d915b00000000, 0x38ed738c00000000, 0x73664dc600000000, + 0x2be6af1100000000, 0x8260f9b200000000, 0xdae01b6500000000, + 0x1e4dc63500000000, 0x46cd24e200000000, 0xef4b724100000000, + 0xb7cb909600000000, 0xfc40aedc00000000, 0xa4c04c0b00000000, + 0x0d461aa800000000, 0x55c6f87f00000000, 0x9b50673c00000000, + 0xc3d085eb00000000, 0x6a56d34800000000, 0x32d6319f00000000, + 0x795d0fd500000000, 0x21dded0200000000, 0x885bbba100000000, + 0xd0db597600000000, 0x28ec084d00000000, 0x706cea9a00000000, + 0xd9eabc3900000000, 0x816a5eee00000000, 0xcae160a400000000, + 0x9261827300000000, 0x3be7d4d000000000, 0x6367360700000000, + 0xadf1a94400000000, 0xf5714b9300000000, 0x5cf71d3000000000, + 0x0477ffe700000000, 0x4ffcc1ad00000000, 0x177c237a00000000, + 0xbefa75d900000000, 0xe67a970e00000000, 0x22d74a5e00000000, + 0x7a57a88900000000, 0xd3d1fe2a00000000, 0x8b511cfd00000000, + 0xc0da22b700000000, 0x985ac06000000000, 0x31dc96c300000000, + 0x695c741400000000, 0xa7caeb5700000000, 0xff4a098000000000, + 0x56cc5f2300000000, 0x0e4cbdf400000000, 0x45c783be00000000, + 0x1d47616900000000, 0xb4c137ca00000000, 0xec41d51d00000000, + 0x3c9a8c6b00000000, 0x641a6ebc00000000, 0xcd9c381f00000000, + 0x951cdac800000000, 0xde97e48200000000, 0x8617065500000000, + 0x2f9150f600000000, 0x7711b22100000000, 0xb9872d6200000000, + 0xe107cfb500000000, 0x4881991600000000, 0x10017bc100000000, + 0x5b8a458b00000000, 0x030aa75c00000000, 0xaa8cf1ff00000000, + 0xf20c132800000000, 0x36a1ce7800000000, 0x6e212caf00000000, + 0xc7a77a0c00000000, 0x9f2798db00000000, 0xd4aca69100000000, + 0x8c2c444600000000, 0x25aa12e500000000, 0x7d2af03200000000, + 0xb3bc6f7100000000, 0xeb3c8da600000000, 0x42badb0500000000, + 0x1a3a39d200000000, 0x51b1079800000000, 0x0931e54f00000000, + 0xa0b7b3ec00000000, 0xf837513b00000000, 0x50d8119a00000000, + 0x0858f34d00000000, 0xa1dea5ee00000000, 0xf95e473900000000, + 0xb2d5797300000000, 0xea559ba400000000, 0x43d3cd0700000000, + 0x1b532fd000000000, 0xd5c5b09300000000, 0x8d45524400000000, + 0x24c304e700000000, 0x7c43e63000000000, 0x37c8d87a00000000, + 0x6f483aad00000000, 0xc6ce6c0e00000000, 0x9e4e8ed900000000, + 0x5ae3538900000000, 0x0263b15e00000000, 0xabe5e7fd00000000, + 0xf365052a00000000, 0xb8ee3b6000000000, 0xe06ed9b700000000, + 0x49e88f1400000000, 0x11686dc300000000, 0xdffef28000000000, + 0x877e105700000000, 0x2ef846f400000000, 0x7678a42300000000, + 0x3df39a6900000000, 0x657378be00000000, 0xccf52e1d00000000, + 0x9475ccca00000000, 0x44ae95bc00000000, 0x1c2e776b00000000, + 0xb5a821c800000000, 0xed28c31f00000000, 0xa6a3fd5500000000, + 0xfe231f8200000000, 0x57a5492100000000, 0x0f25abf600000000, + 0xc1b334b500000000, 0x9933d66200000000, 0x30b580c100000000, + 0x6835621600000000, 0x23be5c5c00000000, 0x7b3ebe8b00000000, + 0xd2b8e82800000000, 0x8a380aff00000000, 0x4e95d7af00000000, + 0x1615357800000000, 0xbf9363db00000000, 0xe713810c00000000, + 0xac98bf4600000000, 0xf4185d9100000000, 0x5d9e0b3200000000, + 0x051ee9e500000000, 0xcb8876a600000000, 0x9308947100000000, + 0x3a8ec2d200000000, 0x620e200500000000, 0x29851e4f00000000, + 0x7105fc9800000000, 0xd883aa3b00000000, 0x800348ec00000000, + 0x783419d700000000, 0x20b4fb0000000000, 0x8932ada300000000, + 0xd1b24f7400000000, 0x9a39713e00000000, 0xc2b993e900000000, + 0x6b3fc54a00000000, 0x33bf279d00000000, 0xfd29b8de00000000, + 0xa5a95a0900000000, 0x0c2f0caa00000000, 0x54afee7d00000000, + 0x1f24d03700000000, 0x47a432e000000000, 0xee22644300000000, + 0xb6a2869400000000, 0x720f5bc400000000, 0x2a8fb91300000000, + 0x8309efb000000000, 0xdb890d6700000000, 0x9002332d00000000, + 0xc882d1fa00000000, 0x6104875900000000, 0x3984658e00000000, + 0xf712facd00000000, 0xaf92181a00000000, 0x06144eb900000000, + 0x5e94ac6e00000000, 0x151f922400000000, 0x4d9f70f300000000, + 0xe419265000000000, 0xbc99c48700000000, 0x6c429df100000000, + 0x34c27f2600000000, 0x9d44298500000000, 0xc5c4cb5200000000, + 0x8e4ff51800000000, 0xd6cf17cf00000000, 0x7f49416c00000000, + 0x27c9a3bb00000000, 0xe95f3cf800000000, 0xb1dfde2f00000000, + 0x1859888c00000000, 0x40d96a5b00000000, 0x0b52541100000000, + 0x53d2b6c600000000, 0xfa54e06500000000, 0xa2d402b200000000, + 0x6679dfe200000000, 0x3ef93d3500000000, 0x977f6b9600000000, + 0xcfff894100000000, 0x8474b70b00000000, 0xdcf455dc00000000, + 0x7572037f00000000, 0x2df2e1a800000000, 0xe3647eeb00000000, + 0xbbe49c3c00000000, 0x1262ca9f00000000, 0x4ae2284800000000, + 0x0169160200000000, 0x59e9f4d500000000, 0xf06fa27600000000, + 0xa8ef40a100000000}, + {0x0000000000000000, 0x463b676500000000, 0x8c76ceca00000000, + 0xca4da9af00000000, 0x59ebed4e00000000, 0x1fd08a2b00000000, + 0xd59d238400000000, 0x93a644e100000000, 0xb2d6db9d00000000, + 0xf4edbcf800000000, 0x3ea0155700000000, 0x789b723200000000, + 0xeb3d36d300000000, 0xad0651b600000000, 0x674bf81900000000, + 0x21709f7c00000000, 0x25abc6e000000000, 0x6390a18500000000, + 0xa9dd082a00000000, 0xefe66f4f00000000, 0x7c402bae00000000, + 0x3a7b4ccb00000000, 0xf036e56400000000, 0xb60d820100000000, + 0x977d1d7d00000000, 0xd1467a1800000000, 0x1b0bd3b700000000, + 0x5d30b4d200000000, 0xce96f03300000000, 0x88ad975600000000, + 0x42e03ef900000000, 0x04db599c00000000, 0x0b50fc1a00000000, + 0x4d6b9b7f00000000, 0x872632d000000000, 0xc11d55b500000000, + 0x52bb115400000000, 0x1480763100000000, 0xdecddf9e00000000, + 0x98f6b8fb00000000, 0xb986278700000000, 0xffbd40e200000000, + 0x35f0e94d00000000, 0x73cb8e2800000000, 0xe06dcac900000000, + 0xa656adac00000000, 0x6c1b040300000000, 0x2a20636600000000, + 0x2efb3afa00000000, 0x68c05d9f00000000, 0xa28df43000000000, + 0xe4b6935500000000, 0x7710d7b400000000, 0x312bb0d100000000, + 0xfb66197e00000000, 0xbd5d7e1b00000000, 0x9c2de16700000000, + 0xda16860200000000, 0x105b2fad00000000, 0x566048c800000000, + 0xc5c60c2900000000, 0x83fd6b4c00000000, 0x49b0c2e300000000, + 0x0f8ba58600000000, 0x16a0f83500000000, 0x509b9f5000000000, + 0x9ad636ff00000000, 0xdced519a00000000, 0x4f4b157b00000000, + 0x0970721e00000000, 0xc33ddbb100000000, 0x8506bcd400000000, + 0xa47623a800000000, 0xe24d44cd00000000, 0x2800ed6200000000, + 0x6e3b8a0700000000, 0xfd9dcee600000000, 0xbba6a98300000000, + 0x71eb002c00000000, 0x37d0674900000000, 0x330b3ed500000000, + 0x753059b000000000, 0xbf7df01f00000000, 0xf946977a00000000, + 0x6ae0d39b00000000, 0x2cdbb4fe00000000, 0xe6961d5100000000, + 0xa0ad7a3400000000, 0x81dde54800000000, 0xc7e6822d00000000, + 0x0dab2b8200000000, 0x4b904ce700000000, 0xd836080600000000, + 0x9e0d6f6300000000, 0x5440c6cc00000000, 0x127ba1a900000000, + 0x1df0042f00000000, 0x5bcb634a00000000, 0x9186cae500000000, + 0xd7bdad8000000000, 0x441be96100000000, 0x02208e0400000000, + 0xc86d27ab00000000, 0x8e5640ce00000000, 0xaf26dfb200000000, + 0xe91db8d700000000, 0x2350117800000000, 0x656b761d00000000, + 0xf6cd32fc00000000, 0xb0f6559900000000, 0x7abbfc3600000000, + 0x3c809b5300000000, 0x385bc2cf00000000, 0x7e60a5aa00000000, + 0xb42d0c0500000000, 0xf2166b6000000000, 0x61b02f8100000000, + 0x278b48e400000000, 0xedc6e14b00000000, 0xabfd862e00000000, + 0x8a8d195200000000, 0xccb67e3700000000, 0x06fbd79800000000, + 0x40c0b0fd00000000, 0xd366f41c00000000, 0x955d937900000000, + 0x5f103ad600000000, 0x192b5db300000000, 0x2c40f16b00000000, + 0x6a7b960e00000000, 0xa0363fa100000000, 0xe60d58c400000000, + 0x75ab1c2500000000, 0x33907b4000000000, 0xf9ddd2ef00000000, + 0xbfe6b58a00000000, 0x9e962af600000000, 0xd8ad4d9300000000, + 0x12e0e43c00000000, 0x54db835900000000, 0xc77dc7b800000000, + 0x8146a0dd00000000, 0x4b0b097200000000, 0x0d306e1700000000, + 0x09eb378b00000000, 0x4fd050ee00000000, 0x859df94100000000, + 0xc3a69e2400000000, 0x5000dac500000000, 0x163bbda000000000, + 0xdc76140f00000000, 0x9a4d736a00000000, 0xbb3dec1600000000, + 0xfd068b7300000000, 0x374b22dc00000000, 0x717045b900000000, + 0xe2d6015800000000, 0xa4ed663d00000000, 0x6ea0cf9200000000, + 0x289ba8f700000000, 0x27100d7100000000, 0x612b6a1400000000, + 0xab66c3bb00000000, 0xed5da4de00000000, 0x7efbe03f00000000, + 0x38c0875a00000000, 0xf28d2ef500000000, 0xb4b6499000000000, + 0x95c6d6ec00000000, 0xd3fdb18900000000, 0x19b0182600000000, + 0x5f8b7f4300000000, 0xcc2d3ba200000000, 0x8a165cc700000000, + 0x405bf56800000000, 0x0660920d00000000, 0x02bbcb9100000000, + 0x4480acf400000000, 0x8ecd055b00000000, 0xc8f6623e00000000, + 0x5b5026df00000000, 0x1d6b41ba00000000, 0xd726e81500000000, + 0x911d8f7000000000, 0xb06d100c00000000, 0xf656776900000000, + 0x3c1bdec600000000, 0x7a20b9a300000000, 0xe986fd4200000000, + 0xafbd9a2700000000, 0x65f0338800000000, 0x23cb54ed00000000, + 0x3ae0095e00000000, 0x7cdb6e3b00000000, 0xb696c79400000000, + 0xf0ada0f100000000, 0x630be41000000000, 0x2530837500000000, + 0xef7d2ada00000000, 0xa9464dbf00000000, 0x8836d2c300000000, + 0xce0db5a600000000, 0x04401c0900000000, 0x427b7b6c00000000, + 0xd1dd3f8d00000000, 0x97e658e800000000, 0x5dabf14700000000, + 0x1b90962200000000, 0x1f4bcfbe00000000, 0x5970a8db00000000, + 0x933d017400000000, 0xd506661100000000, 0x46a022f000000000, + 0x009b459500000000, 0xcad6ec3a00000000, 0x8ced8b5f00000000, + 0xad9d142300000000, 0xeba6734600000000, 0x21ebdae900000000, + 0x67d0bd8c00000000, 0xf476f96d00000000, 0xb24d9e0800000000, + 0x780037a700000000, 0x3e3b50c200000000, 0x31b0f54400000000, + 0x778b922100000000, 0xbdc63b8e00000000, 0xfbfd5ceb00000000, + 0x685b180a00000000, 0x2e607f6f00000000, 0xe42dd6c000000000, + 0xa216b1a500000000, 0x83662ed900000000, 0xc55d49bc00000000, + 0x0f10e01300000000, 0x492b877600000000, 0xda8dc39700000000, + 0x9cb6a4f200000000, 0x56fb0d5d00000000, 0x10c06a3800000000, + 0x141b33a400000000, 0x522054c100000000, 0x986dfd6e00000000, + 0xde569a0b00000000, 0x4df0deea00000000, 0x0bcbb98f00000000, + 0xc186102000000000, 0x87bd774500000000, 0xa6cde83900000000, + 0xe0f68f5c00000000, 0x2abb26f300000000, 0x6c80419600000000, + 0xff26057700000000, 0xb91d621200000000, 0x7350cbbd00000000, + 0x356bacd800000000}, + {0x0000000000000000, 0x9e83da9f00000000, 0x7d01c4e400000000, + 0xe3821e7b00000000, 0xbb04f91200000000, 0x2587238d00000000, + 0xc6053df600000000, 0x5886e76900000000, 0x7609f22500000000, + 0xe88a28ba00000000, 0x0b0836c100000000, 0x958bec5e00000000, + 0xcd0d0b3700000000, 0x538ed1a800000000, 0xb00ccfd300000000, + 0x2e8f154c00000000, 0xec12e44b00000000, 0x72913ed400000000, + 0x911320af00000000, 0x0f90fa3000000000, 0x57161d5900000000, + 0xc995c7c600000000, 0x2a17d9bd00000000, 0xb494032200000000, + 0x9a1b166e00000000, 0x0498ccf100000000, 0xe71ad28a00000000, + 0x7999081500000000, 0x211fef7c00000000, 0xbf9c35e300000000, + 0x5c1e2b9800000000, 0xc29df10700000000, 0xd825c89700000000, + 0x46a6120800000000, 0xa5240c7300000000, 0x3ba7d6ec00000000, + 0x6321318500000000, 0xfda2eb1a00000000, 0x1e20f56100000000, + 0x80a32ffe00000000, 0xae2c3ab200000000, 0x30afe02d00000000, + 0xd32dfe5600000000, 0x4dae24c900000000, 0x1528c3a000000000, + 0x8bab193f00000000, 0x6829074400000000, 0xf6aadddb00000000, + 0x34372cdc00000000, 0xaab4f64300000000, 0x4936e83800000000, + 0xd7b532a700000000, 0x8f33d5ce00000000, 0x11b00f5100000000, + 0xf232112a00000000, 0x6cb1cbb500000000, 0x423edef900000000, + 0xdcbd046600000000, 0x3f3f1a1d00000000, 0xa1bcc08200000000, + 0xf93a27eb00000000, 0x67b9fd7400000000, 0x843be30f00000000, + 0x1ab8399000000000, 0xf14de1f400000000, 0x6fce3b6b00000000, + 0x8c4c251000000000, 0x12cfff8f00000000, 0x4a4918e600000000, + 0xd4cac27900000000, 0x3748dc0200000000, 0xa9cb069d00000000, + 0x874413d100000000, 0x19c7c94e00000000, 0xfa45d73500000000, + 0x64c60daa00000000, 0x3c40eac300000000, 0xa2c3305c00000000, + 0x41412e2700000000, 0xdfc2f4b800000000, 0x1d5f05bf00000000, + 0x83dcdf2000000000, 0x605ec15b00000000, 0xfedd1bc400000000, + 0xa65bfcad00000000, 0x38d8263200000000, 0xdb5a384900000000, + 0x45d9e2d600000000, 0x6b56f79a00000000, 0xf5d52d0500000000, + 0x1657337e00000000, 0x88d4e9e100000000, 0xd0520e8800000000, + 0x4ed1d41700000000, 0xad53ca6c00000000, 0x33d010f300000000, + 0x2968296300000000, 0xb7ebf3fc00000000, 0x5469ed8700000000, + 0xcaea371800000000, 0x926cd07100000000, 0x0cef0aee00000000, + 0xef6d149500000000, 0x71eece0a00000000, 0x5f61db4600000000, + 0xc1e201d900000000, 0x22601fa200000000, 0xbce3c53d00000000, + 0xe465225400000000, 0x7ae6f8cb00000000, 0x9964e6b000000000, + 0x07e73c2f00000000, 0xc57acd2800000000, 0x5bf917b700000000, + 0xb87b09cc00000000, 0x26f8d35300000000, 0x7e7e343a00000000, + 0xe0fdeea500000000, 0x037ff0de00000000, 0x9dfc2a4100000000, + 0xb3733f0d00000000, 0x2df0e59200000000, 0xce72fbe900000000, + 0x50f1217600000000, 0x0877c61f00000000, 0x96f41c8000000000, + 0x757602fb00000000, 0xebf5d86400000000, 0xa39db33200000000, + 0x3d1e69ad00000000, 0xde9c77d600000000, 0x401fad4900000000, + 0x18994a2000000000, 0x861a90bf00000000, 0x65988ec400000000, + 0xfb1b545b00000000, 0xd594411700000000, 0x4b179b8800000000, + 0xa89585f300000000, 0x36165f6c00000000, 0x6e90b80500000000, + 0xf013629a00000000, 0x13917ce100000000, 0x8d12a67e00000000, + 0x4f8f577900000000, 0xd10c8de600000000, 0x328e939d00000000, + 0xac0d490200000000, 0xf48bae6b00000000, 0x6a0874f400000000, + 0x898a6a8f00000000, 0x1709b01000000000, 0x3986a55c00000000, + 0xa7057fc300000000, 0x448761b800000000, 0xda04bb2700000000, + 0x82825c4e00000000, 0x1c0186d100000000, 0xff8398aa00000000, + 0x6100423500000000, 0x7bb87ba500000000, 0xe53ba13a00000000, + 0x06b9bf4100000000, 0x983a65de00000000, 0xc0bc82b700000000, + 0x5e3f582800000000, 0xbdbd465300000000, 0x233e9ccc00000000, + 0x0db1898000000000, 0x9332531f00000000, 0x70b04d6400000000, + 0xee3397fb00000000, 0xb6b5709200000000, 0x2836aa0d00000000, + 0xcbb4b47600000000, 0x55376ee900000000, 0x97aa9fee00000000, + 0x0929457100000000, 0xeaab5b0a00000000, 0x7428819500000000, + 0x2cae66fc00000000, 0xb22dbc6300000000, 0x51afa21800000000, + 0xcf2c788700000000, 0xe1a36dcb00000000, 0x7f20b75400000000, + 0x9ca2a92f00000000, 0x022173b000000000, 0x5aa794d900000000, + 0xc4244e4600000000, 0x27a6503d00000000, 0xb9258aa200000000, + 0x52d052c600000000, 0xcc53885900000000, 0x2fd1962200000000, + 0xb1524cbd00000000, 0xe9d4abd400000000, 0x7757714b00000000, + 0x94d56f3000000000, 0x0a56b5af00000000, 0x24d9a0e300000000, + 0xba5a7a7c00000000, 0x59d8640700000000, 0xc75bbe9800000000, + 0x9fdd59f100000000, 0x015e836e00000000, 0xe2dc9d1500000000, + 0x7c5f478a00000000, 0xbec2b68d00000000, 0x20416c1200000000, + 0xc3c3726900000000, 0x5d40a8f600000000, 0x05c64f9f00000000, + 0x9b45950000000000, 0x78c78b7b00000000, 0xe64451e400000000, + 0xc8cb44a800000000, 0x56489e3700000000, 0xb5ca804c00000000, + 0x2b495ad300000000, 0x73cfbdba00000000, 0xed4c672500000000, + 0x0ece795e00000000, 0x904da3c100000000, 0x8af59a5100000000, + 0x147640ce00000000, 0xf7f45eb500000000, 0x6977842a00000000, + 0x31f1634300000000, 0xaf72b9dc00000000, 0x4cf0a7a700000000, + 0xd2737d3800000000, 0xfcfc687400000000, 0x627fb2eb00000000, + 0x81fdac9000000000, 0x1f7e760f00000000, 0x47f8916600000000, + 0xd97b4bf900000000, 0x3af9558200000000, 0xa47a8f1d00000000, + 0x66e77e1a00000000, 0xf864a48500000000, 0x1be6bafe00000000, + 0x8565606100000000, 0xdde3870800000000, 0x43605d9700000000, + 0xa0e243ec00000000, 0x3e61997300000000, 0x10ee8c3f00000000, + 0x8e6d56a000000000, 0x6def48db00000000, 0xf36c924400000000, + 0xabea752d00000000, 0x3569afb200000000, 0xd6ebb1c900000000, + 0x48686b5600000000}, + {0x0000000000000000, 0xc064281700000000, 0x80c9502e00000000, + 0x40ad783900000000, 0x0093a15c00000000, 0xc0f7894b00000000, + 0x805af17200000000, 0x403ed96500000000, 0x002643b900000000, + 0xc0426bae00000000, 0x80ef139700000000, 0x408b3b8000000000, + 0x00b5e2e500000000, 0xc0d1caf200000000, 0x807cb2cb00000000, + 0x40189adc00000000, 0x414af7a900000000, 0x812edfbe00000000, + 0xc183a78700000000, 0x01e78f9000000000, 0x41d956f500000000, + 0x81bd7ee200000000, 0xc11006db00000000, 0x01742ecc00000000, + 0x416cb41000000000, 0x81089c0700000000, 0xc1a5e43e00000000, + 0x01c1cc2900000000, 0x41ff154c00000000, 0x819b3d5b00000000, + 0xc136456200000000, 0x01526d7500000000, 0xc3929f8800000000, + 0x03f6b79f00000000, 0x435bcfa600000000, 0x833fe7b100000000, + 0xc3013ed400000000, 0x036516c300000000, 0x43c86efa00000000, + 0x83ac46ed00000000, 0xc3b4dc3100000000, 0x03d0f42600000000, + 0x437d8c1f00000000, 0x8319a40800000000, 0xc3277d6d00000000, + 0x0343557a00000000, 0x43ee2d4300000000, 0x838a055400000000, + 0x82d8682100000000, 0x42bc403600000000, 0x0211380f00000000, + 0xc275101800000000, 0x824bc97d00000000, 0x422fe16a00000000, + 0x0282995300000000, 0xc2e6b14400000000, 0x82fe2b9800000000, + 0x429a038f00000000, 0x02377bb600000000, 0xc25353a100000000, + 0x826d8ac400000000, 0x4209a2d300000000, 0x02a4daea00000000, + 0xc2c0f2fd00000000, 0xc7234eca00000000, 0x074766dd00000000, + 0x47ea1ee400000000, 0x878e36f300000000, 0xc7b0ef9600000000, + 0x07d4c78100000000, 0x4779bfb800000000, 0x871d97af00000000, + 0xc7050d7300000000, 0x0761256400000000, 0x47cc5d5d00000000, + 0x87a8754a00000000, 0xc796ac2f00000000, 0x07f2843800000000, + 0x475ffc0100000000, 0x873bd41600000000, 0x8669b96300000000, + 0x460d917400000000, 0x06a0e94d00000000, 0xc6c4c15a00000000, + 0x86fa183f00000000, 0x469e302800000000, 0x0633481100000000, + 0xc657600600000000, 0x864ffada00000000, 0x462bd2cd00000000, + 0x0686aaf400000000, 0xc6e282e300000000, 0x86dc5b8600000000, + 0x46b8739100000000, 0x06150ba800000000, 0xc67123bf00000000, + 0x04b1d14200000000, 0xc4d5f95500000000, 0x8478816c00000000, + 0x441ca97b00000000, 0x0422701e00000000, 0xc446580900000000, + 0x84eb203000000000, 0x448f082700000000, 0x049792fb00000000, + 0xc4f3baec00000000, 0x845ec2d500000000, 0x443aeac200000000, + 0x040433a700000000, 0xc4601bb000000000, 0x84cd638900000000, + 0x44a94b9e00000000, 0x45fb26eb00000000, 0x859f0efc00000000, + 0xc53276c500000000, 0x05565ed200000000, 0x456887b700000000, + 0x850cafa000000000, 0xc5a1d79900000000, 0x05c5ff8e00000000, + 0x45dd655200000000, 0x85b94d4500000000, 0xc514357c00000000, + 0x05701d6b00000000, 0x454ec40e00000000, 0x852aec1900000000, + 0xc587942000000000, 0x05e3bc3700000000, 0xcf41ed4f00000000, + 0x0f25c55800000000, 0x4f88bd6100000000, 0x8fec957600000000, + 0xcfd24c1300000000, 0x0fb6640400000000, 0x4f1b1c3d00000000, + 0x8f7f342a00000000, 0xcf67aef600000000, 0x0f0386e100000000, + 0x4faefed800000000, 0x8fcad6cf00000000, 0xcff40faa00000000, + 0x0f9027bd00000000, 0x4f3d5f8400000000, 0x8f59779300000000, + 0x8e0b1ae600000000, 0x4e6f32f100000000, 0x0ec24ac800000000, + 0xcea662df00000000, 0x8e98bbba00000000, 0x4efc93ad00000000, + 0x0e51eb9400000000, 0xce35c38300000000, 0x8e2d595f00000000, + 0x4e49714800000000, 0x0ee4097100000000, 0xce80216600000000, + 0x8ebef80300000000, 0x4edad01400000000, 0x0e77a82d00000000, + 0xce13803a00000000, 0x0cd372c700000000, 0xccb75ad000000000, + 0x8c1a22e900000000, 0x4c7e0afe00000000, 0x0c40d39b00000000, + 0xcc24fb8c00000000, 0x8c8983b500000000, 0x4cedaba200000000, + 0x0cf5317e00000000, 0xcc91196900000000, 0x8c3c615000000000, + 0x4c58494700000000, 0x0c66902200000000, 0xcc02b83500000000, + 0x8cafc00c00000000, 0x4ccbe81b00000000, 0x4d99856e00000000, + 0x8dfdad7900000000, 0xcd50d54000000000, 0x0d34fd5700000000, + 0x4d0a243200000000, 0x8d6e0c2500000000, 0xcdc3741c00000000, + 0x0da75c0b00000000, 0x4dbfc6d700000000, 0x8ddbeec000000000, + 0xcd7696f900000000, 0x0d12beee00000000, 0x4d2c678b00000000, + 0x8d484f9c00000000, 0xcde537a500000000, 0x0d811fb200000000, + 0x0862a38500000000, 0xc8068b9200000000, 0x88abf3ab00000000, + 0x48cfdbbc00000000, 0x08f102d900000000, 0xc8952ace00000000, + 0x883852f700000000, 0x485c7ae000000000, 0x0844e03c00000000, + 0xc820c82b00000000, 0x888db01200000000, 0x48e9980500000000, + 0x08d7416000000000, 0xc8b3697700000000, 0x881e114e00000000, + 0x487a395900000000, 0x4928542c00000000, 0x894c7c3b00000000, + 0xc9e1040200000000, 0x09852c1500000000, 0x49bbf57000000000, + 0x89dfdd6700000000, 0xc972a55e00000000, 0x09168d4900000000, + 0x490e179500000000, 0x896a3f8200000000, 0xc9c747bb00000000, + 0x09a36fac00000000, 0x499db6c900000000, 0x89f99ede00000000, + 0xc954e6e700000000, 0x0930cef000000000, 0xcbf03c0d00000000, + 0x0b94141a00000000, 0x4b396c2300000000, 0x8b5d443400000000, + 0xcb639d5100000000, 0x0b07b54600000000, 0x4baacd7f00000000, + 0x8bcee56800000000, 0xcbd67fb400000000, 0x0bb257a300000000, + 0x4b1f2f9a00000000, 0x8b7b078d00000000, 0xcb45dee800000000, + 0x0b21f6ff00000000, 0x4b8c8ec600000000, 0x8be8a6d100000000, + 0x8abacba400000000, 0x4adee3b300000000, 0x0a739b8a00000000, + 0xca17b39d00000000, 0x8a296af800000000, 0x4a4d42ef00000000, + 0x0ae03ad600000000, 0xca8412c100000000, 0x8a9c881d00000000, + 0x4af8a00a00000000, 0x0a55d83300000000, 0xca31f02400000000, + 0x8a0f294100000000, 0x4a6b015600000000, 0x0ac6796f00000000, + 0xcaa2517800000000}, + {0x0000000000000000, 0xd4ea739b00000000, 0xe9d396ed00000000, + 0x3d39e57600000000, 0x93a15c0000000000, 0x474b2f9b00000000, + 0x7a72caed00000000, 0xae98b97600000000, 0x2643b90000000000, + 0xf2a9ca9b00000000, 0xcf902fed00000000, 0x1b7a5c7600000000, + 0xb5e2e50000000000, 0x6108969b00000000, 0x5c3173ed00000000, + 0x88db007600000000, 0x4c86720100000000, 0x986c019a00000000, + 0xa555e4ec00000000, 0x71bf977700000000, 0xdf272e0100000000, + 0x0bcd5d9a00000000, 0x36f4b8ec00000000, 0xe21ecb7700000000, + 0x6ac5cb0100000000, 0xbe2fb89a00000000, 0x83165dec00000000, + 0x57fc2e7700000000, 0xf964970100000000, 0x2d8ee49a00000000, + 0x10b701ec00000000, 0xc45d727700000000, 0x980ce50200000000, + 0x4ce6969900000000, 0x71df73ef00000000, 0xa535007400000000, + 0x0badb90200000000, 0xdf47ca9900000000, 0xe27e2fef00000000, + 0x36945c7400000000, 0xbe4f5c0200000000, 0x6aa52f9900000000, + 0x579ccaef00000000, 0x8376b97400000000, 0x2dee000200000000, + 0xf904739900000000, 0xc43d96ef00000000, 0x10d7e57400000000, + 0xd48a970300000000, 0x0060e49800000000, 0x3d5901ee00000000, + 0xe9b3727500000000, 0x472bcb0300000000, 0x93c1b89800000000, + 0xaef85dee00000000, 0x7a122e7500000000, 0xf2c92e0300000000, + 0x26235d9800000000, 0x1b1ab8ee00000000, 0xcff0cb7500000000, + 0x6168720300000000, 0xb582019800000000, 0x88bbe4ee00000000, + 0x5c51977500000000, 0x3019ca0500000000, 0xe4f3b99e00000000, + 0xd9ca5ce800000000, 0x0d202f7300000000, 0xa3b8960500000000, + 0x7752e59e00000000, 0x4a6b00e800000000, 0x9e81737300000000, + 0x165a730500000000, 0xc2b0009e00000000, 0xff89e5e800000000, + 0x2b63967300000000, 0x85fb2f0500000000, 0x51115c9e00000000, + 0x6c28b9e800000000, 0xb8c2ca7300000000, 0x7c9fb80400000000, + 0xa875cb9f00000000, 0x954c2ee900000000, 0x41a65d7200000000, + 0xef3ee40400000000, 0x3bd4979f00000000, 0x06ed72e900000000, + 0xd207017200000000, 0x5adc010400000000, 0x8e36729f00000000, + 0xb30f97e900000000, 0x67e5e47200000000, 0xc97d5d0400000000, + 0x1d972e9f00000000, 0x20aecbe900000000, 0xf444b87200000000, + 0xa8152f0700000000, 0x7cff5c9c00000000, 0x41c6b9ea00000000, + 0x952cca7100000000, 0x3bb4730700000000, 0xef5e009c00000000, + 0xd267e5ea00000000, 0x068d967100000000, 0x8e56960700000000, + 0x5abce59c00000000, 0x678500ea00000000, 0xb36f737100000000, + 0x1df7ca0700000000, 0xc91db99c00000000, 0xf4245cea00000000, + 0x20ce2f7100000000, 0xe4935d0600000000, 0x30792e9d00000000, + 0x0d40cbeb00000000, 0xd9aab87000000000, 0x7732010600000000, + 0xa3d8729d00000000, 0x9ee197eb00000000, 0x4a0be47000000000, + 0xc2d0e40600000000, 0x163a979d00000000, 0x2b0372eb00000000, + 0xffe9017000000000, 0x5171b80600000000, 0x859bcb9d00000000, + 0xb8a22eeb00000000, 0x6c485d7000000000, 0x6032940b00000000, + 0xb4d8e79000000000, 0x89e102e600000000, 0x5d0b717d00000000, + 0xf393c80b00000000, 0x2779bb9000000000, 0x1a405ee600000000, + 0xceaa2d7d00000000, 0x46712d0b00000000, 0x929b5e9000000000, + 0xafa2bbe600000000, 0x7b48c87d00000000, 0xd5d0710b00000000, + 0x013a029000000000, 0x3c03e7e600000000, 0xe8e9947d00000000, + 0x2cb4e60a00000000, 0xf85e959100000000, 0xc56770e700000000, + 0x118d037c00000000, 0xbf15ba0a00000000, 0x6bffc99100000000, + 0x56c62ce700000000, 0x822c5f7c00000000, 0x0af75f0a00000000, + 0xde1d2c9100000000, 0xe324c9e700000000, 0x37ceba7c00000000, + 0x9956030a00000000, 0x4dbc709100000000, 0x708595e700000000, + 0xa46fe67c00000000, 0xf83e710900000000, 0x2cd4029200000000, + 0x11ede7e400000000, 0xc507947f00000000, 0x6b9f2d0900000000, + 0xbf755e9200000000, 0x824cbbe400000000, 0x56a6c87f00000000, + 0xde7dc80900000000, 0x0a97bb9200000000, 0x37ae5ee400000000, + 0xe3442d7f00000000, 0x4ddc940900000000, 0x9936e79200000000, + 0xa40f02e400000000, 0x70e5717f00000000, 0xb4b8030800000000, + 0x6052709300000000, 0x5d6b95e500000000, 0x8981e67e00000000, + 0x27195f0800000000, 0xf3f32c9300000000, 0xcecac9e500000000, + 0x1a20ba7e00000000, 0x92fbba0800000000, 0x4611c99300000000, + 0x7b282ce500000000, 0xafc25f7e00000000, 0x015ae60800000000, + 0xd5b0959300000000, 0xe88970e500000000, 0x3c63037e00000000, + 0x502b5e0e00000000, 0x84c12d9500000000, 0xb9f8c8e300000000, + 0x6d12bb7800000000, 0xc38a020e00000000, 0x1760719500000000, + 0x2a5994e300000000, 0xfeb3e77800000000, 0x7668e70e00000000, + 0xa282949500000000, 0x9fbb71e300000000, 0x4b51027800000000, + 0xe5c9bb0e00000000, 0x3123c89500000000, 0x0c1a2de300000000, + 0xd8f05e7800000000, 0x1cad2c0f00000000, 0xc8475f9400000000, + 0xf57ebae200000000, 0x2194c97900000000, 0x8f0c700f00000000, + 0x5be6039400000000, 0x66dfe6e200000000, 0xb235957900000000, + 0x3aee950f00000000, 0xee04e69400000000, 0xd33d03e200000000, + 0x07d7707900000000, 0xa94fc90f00000000, 0x7da5ba9400000000, + 0x409c5fe200000000, 0x94762c7900000000, 0xc827bb0c00000000, + 0x1ccdc89700000000, 0x21f42de100000000, 0xf51e5e7a00000000, + 0x5b86e70c00000000, 0x8f6c949700000000, 0xb25571e100000000, + 0x66bf027a00000000, 0xee64020c00000000, 0x3a8e719700000000, + 0x07b794e100000000, 0xd35de77a00000000, 0x7dc55e0c00000000, + 0xa92f2d9700000000, 0x9416c8e100000000, 0x40fcbb7a00000000, + 0x84a1c90d00000000, 0x504bba9600000000, 0x6d725fe000000000, + 0xb9982c7b00000000, 0x1700950d00000000, 0xc3eae69600000000, + 0xfed303e000000000, 0x2a39707b00000000, 0xa2e2700d00000000, + 0x7608039600000000, 0x4b31e6e000000000, 0x9fdb957b00000000, + 0x31432c0d00000000, 0xe5a95f9600000000, 0xd890bae000000000, + 0x0c7ac97b00000000}, + {0x0000000000000000, 0x2765258100000000, 0x0fcc3bd900000000, + 0x28a91e5800000000, 0x5f9e066900000000, 0x78fb23e800000000, + 0x50523db000000000, 0x7737183100000000, 0xbe3c0dd200000000, + 0x9959285300000000, 0xb1f0360b00000000, 0x9695138a00000000, + 0xe1a20bbb00000000, 0xc6c72e3a00000000, 0xee6e306200000000, + 0xc90b15e300000000, 0x3d7f6b7f00000000, 0x1a1a4efe00000000, + 0x32b350a600000000, 0x15d6752700000000, 0x62e16d1600000000, + 0x4584489700000000, 0x6d2d56cf00000000, 0x4a48734e00000000, + 0x834366ad00000000, 0xa426432c00000000, 0x8c8f5d7400000000, + 0xabea78f500000000, 0xdcdd60c400000000, 0xfbb8454500000000, + 0xd3115b1d00000000, 0xf4747e9c00000000, 0x7afed6fe00000000, + 0x5d9bf37f00000000, 0x7532ed2700000000, 0x5257c8a600000000, + 0x2560d09700000000, 0x0205f51600000000, 0x2aaceb4e00000000, + 0x0dc9cecf00000000, 0xc4c2db2c00000000, 0xe3a7fead00000000, + 0xcb0ee0f500000000, 0xec6bc57400000000, 0x9b5cdd4500000000, + 0xbc39f8c400000000, 0x9490e69c00000000, 0xb3f5c31d00000000, + 0x4781bd8100000000, 0x60e4980000000000, 0x484d865800000000, + 0x6f28a3d900000000, 0x181fbbe800000000, 0x3f7a9e6900000000, + 0x17d3803100000000, 0x30b6a5b000000000, 0xf9bdb05300000000, + 0xded895d200000000, 0xf6718b8a00000000, 0xd114ae0b00000000, + 0xa623b63a00000000, 0x814693bb00000000, 0xa9ef8de300000000, + 0x8e8aa86200000000, 0xb5fadc2600000000, 0x929ff9a700000000, + 0xba36e7ff00000000, 0x9d53c27e00000000, 0xea64da4f00000000, + 0xcd01ffce00000000, 0xe5a8e19600000000, 0xc2cdc41700000000, + 0x0bc6d1f400000000, 0x2ca3f47500000000, 0x040aea2d00000000, + 0x236fcfac00000000, 0x5458d79d00000000, 0x733df21c00000000, + 0x5b94ec4400000000, 0x7cf1c9c500000000, 0x8885b75900000000, + 0xafe092d800000000, 0x87498c8000000000, 0xa02ca90100000000, + 0xd71bb13000000000, 0xf07e94b100000000, 0xd8d78ae900000000, + 0xffb2af6800000000, 0x36b9ba8b00000000, 0x11dc9f0a00000000, + 0x3975815200000000, 0x1e10a4d300000000, 0x6927bce200000000, + 0x4e42996300000000, 0x66eb873b00000000, 0x418ea2ba00000000, + 0xcf040ad800000000, 0xe8612f5900000000, 0xc0c8310100000000, + 0xe7ad148000000000, 0x909a0cb100000000, 0xb7ff293000000000, + 0x9f56376800000000, 0xb83312e900000000, 0x7138070a00000000, + 0x565d228b00000000, 0x7ef43cd300000000, 0x5991195200000000, + 0x2ea6016300000000, 0x09c324e200000000, 0x216a3aba00000000, + 0x060f1f3b00000000, 0xf27b61a700000000, 0xd51e442600000000, + 0xfdb75a7e00000000, 0xdad27fff00000000, 0xade567ce00000000, + 0x8a80424f00000000, 0xa2295c1700000000, 0x854c799600000000, + 0x4c476c7500000000, 0x6b2249f400000000, 0x438b57ac00000000, + 0x64ee722d00000000, 0x13d96a1c00000000, 0x34bc4f9d00000000, + 0x1c1551c500000000, 0x3b70744400000000, 0x6af5b94d00000000, + 0x4d909ccc00000000, 0x6539829400000000, 0x425ca71500000000, + 0x356bbf2400000000, 0x120e9aa500000000, 0x3aa784fd00000000, + 0x1dc2a17c00000000, 0xd4c9b49f00000000, 0xf3ac911e00000000, + 0xdb058f4600000000, 0xfc60aac700000000, 0x8b57b2f600000000, + 0xac32977700000000, 0x849b892f00000000, 0xa3feacae00000000, + 0x578ad23200000000, 0x70eff7b300000000, 0x5846e9eb00000000, + 0x7f23cc6a00000000, 0x0814d45b00000000, 0x2f71f1da00000000, + 0x07d8ef8200000000, 0x20bdca0300000000, 0xe9b6dfe000000000, + 0xced3fa6100000000, 0xe67ae43900000000, 0xc11fc1b800000000, + 0xb628d98900000000, 0x914dfc0800000000, 0xb9e4e25000000000, + 0x9e81c7d100000000, 0x100b6fb300000000, 0x376e4a3200000000, + 0x1fc7546a00000000, 0x38a271eb00000000, 0x4f9569da00000000, + 0x68f04c5b00000000, 0x4059520300000000, 0x673c778200000000, + 0xae37626100000000, 0x895247e000000000, 0xa1fb59b800000000, + 0x869e7c3900000000, 0xf1a9640800000000, 0xd6cc418900000000, + 0xfe655fd100000000, 0xd9007a5000000000, 0x2d7404cc00000000, + 0x0a11214d00000000, 0x22b83f1500000000, 0x05dd1a9400000000, + 0x72ea02a500000000, 0x558f272400000000, 0x7d26397c00000000, + 0x5a431cfd00000000, 0x9348091e00000000, 0xb42d2c9f00000000, + 0x9c8432c700000000, 0xbbe1174600000000, 0xccd60f7700000000, + 0xebb32af600000000, 0xc31a34ae00000000, 0xe47f112f00000000, + 0xdf0f656b00000000, 0xf86a40ea00000000, 0xd0c35eb200000000, + 0xf7a67b3300000000, 0x8091630200000000, 0xa7f4468300000000, + 0x8f5d58db00000000, 0xa8387d5a00000000, 0x613368b900000000, + 0x46564d3800000000, 0x6eff536000000000, 0x499a76e100000000, + 0x3ead6ed000000000, 0x19c84b5100000000, 0x3161550900000000, + 0x1604708800000000, 0xe2700e1400000000, 0xc5152b9500000000, + 0xedbc35cd00000000, 0xcad9104c00000000, 0xbdee087d00000000, + 0x9a8b2dfc00000000, 0xb22233a400000000, 0x9547162500000000, + 0x5c4c03c600000000, 0x7b29264700000000, 0x5380381f00000000, + 0x74e51d9e00000000, 0x03d205af00000000, 0x24b7202e00000000, + 0x0c1e3e7600000000, 0x2b7b1bf700000000, 0xa5f1b39500000000, + 0x8294961400000000, 0xaa3d884c00000000, 0x8d58adcd00000000, + 0xfa6fb5fc00000000, 0xdd0a907d00000000, 0xf5a38e2500000000, + 0xd2c6aba400000000, 0x1bcdbe4700000000, 0x3ca89bc600000000, + 0x1401859e00000000, 0x3364a01f00000000, 0x4453b82e00000000, + 0x63369daf00000000, 0x4b9f83f700000000, 0x6cfaa67600000000, + 0x988ed8ea00000000, 0xbfebfd6b00000000, 0x9742e33300000000, + 0xb027c6b200000000, 0xc710de8300000000, 0xe075fb0200000000, + 0xc8dce55a00000000, 0xefb9c0db00000000, 0x26b2d53800000000, + 0x01d7f0b900000000, 0x297eeee100000000, 0x0e1bcb6000000000, + 0x792cd35100000000, 0x5e49f6d000000000, 0x76e0e88800000000, + 0x5185cd0900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x9ba54c6f, 0xec3b9e9f, 0x779ed2f0, 0x03063b7f, + 0x98a37710, 0xef3da5e0, 0x7498e98f, 0x060c76fe, 0x9da93a91, + 0xea37e861, 0x7192a40e, 0x050a4d81, 0x9eaf01ee, 0xe931d31e, + 0x72949f71, 0x0c18edfc, 0x97bda193, 0xe0237363, 0x7b863f0c, + 0x0f1ed683, 0x94bb9aec, 0xe325481c, 0x78800473, 0x0a149b02, + 0x91b1d76d, 0xe62f059d, 0x7d8a49f2, 0x0912a07d, 0x92b7ec12, + 0xe5293ee2, 0x7e8c728d, 0x1831dbf8, 0x83949797, 0xf40a4567, + 0x6faf0908, 0x1b37e087, 0x8092ace8, 0xf70c7e18, 0x6ca93277, + 0x1e3dad06, 0x8598e169, 0xf2063399, 0x69a37ff6, 0x1d3b9679, + 0x869eda16, 0xf10008e6, 0x6aa54489, 0x14293604, 0x8f8c7a6b, + 0xf812a89b, 0x63b7e4f4, 0x172f0d7b, 0x8c8a4114, 0xfb1493e4, + 0x60b1df8b, 0x122540fa, 0x89800c95, 0xfe1ede65, 0x65bb920a, + 0x11237b85, 0x8a8637ea, 0xfd18e51a, 0x66bda975, 0x3063b7f0, + 0xabc6fb9f, 0xdc58296f, 0x47fd6500, 0x33658c8f, 0xa8c0c0e0, + 0xdf5e1210, 0x44fb5e7f, 0x366fc10e, 0xadca8d61, 0xda545f91, + 0x41f113fe, 0x3569fa71, 0xaeccb61e, 0xd95264ee, 0x42f72881, + 0x3c7b5a0c, 0xa7de1663, 0xd040c493, 0x4be588fc, 0x3f7d6173, + 0xa4d82d1c, 0xd346ffec, 0x48e3b383, 0x3a772cf2, 0xa1d2609d, + 0xd64cb26d, 0x4de9fe02, 0x3971178d, 0xa2d45be2, 0xd54a8912, + 0x4eefc57d, 0x28526c08, 0xb3f72067, 0xc469f297, 0x5fccbef8, + 0x2b545777, 0xb0f11b18, 0xc76fc9e8, 0x5cca8587, 0x2e5e1af6, + 0xb5fb5699, 0xc2658469, 0x59c0c806, 0x2d582189, 0xb6fd6de6, + 0xc163bf16, 0x5ac6f379, 0x244a81f4, 0xbfefcd9b, 0xc8711f6b, + 0x53d45304, 0x274cba8b, 0xbce9f6e4, 0xcb772414, 0x50d2687b, + 0x2246f70a, 0xb9e3bb65, 0xce7d6995, 0x55d825fa, 0x2140cc75, + 0xbae5801a, 0xcd7b52ea, 0x56de1e85, 0x60c76fe0, 0xfb62238f, + 0x8cfcf17f, 0x1759bd10, 0x63c1549f, 0xf86418f0, 0x8ffaca00, + 0x145f866f, 0x66cb191e, 0xfd6e5571, 0x8af08781, 0x1155cbee, + 0x65cd2261, 0xfe686e0e, 0x89f6bcfe, 0x1253f091, 0x6cdf821c, + 0xf77ace73, 0x80e41c83, 0x1b4150ec, 0x6fd9b963, 0xf47cf50c, + 0x83e227fc, 0x18476b93, 0x6ad3f4e2, 0xf176b88d, 0x86e86a7d, + 0x1d4d2612, 0x69d5cf9d, 0xf27083f2, 0x85ee5102, 0x1e4b1d6d, + 0x78f6b418, 0xe353f877, 0x94cd2a87, 0x0f6866e8, 0x7bf08f67, + 0xe055c308, 0x97cb11f8, 0x0c6e5d97, 0x7efac2e6, 0xe55f8e89, + 0x92c15c79, 0x09641016, 0x7dfcf999, 0xe659b5f6, 0x91c76706, + 0x0a622b69, 0x74ee59e4, 0xef4b158b, 0x98d5c77b, 0x03708b14, + 0x77e8629b, 0xec4d2ef4, 0x9bd3fc04, 0x0076b06b, 0x72e22f1a, + 0xe9476375, 0x9ed9b185, 0x057cfdea, 0x71e41465, 0xea41580a, + 0x9ddf8afa, 0x067ac695, 0x50a4d810, 0xcb01947f, 0xbc9f468f, + 0x273a0ae0, 0x53a2e36f, 0xc807af00, 0xbf997df0, 0x243c319f, + 0x56a8aeee, 0xcd0de281, 0xba933071, 0x21367c1e, 0x55ae9591, + 0xce0bd9fe, 0xb9950b0e, 0x22304761, 0x5cbc35ec, 0xc7197983, + 0xb087ab73, 0x2b22e71c, 0x5fba0e93, 0xc41f42fc, 0xb381900c, + 0x2824dc63, 0x5ab04312, 0xc1150f7d, 0xb68bdd8d, 0x2d2e91e2, + 0x59b6786d, 0xc2133402, 0xb58de6f2, 0x2e28aa9d, 0x489503e8, + 0xd3304f87, 0xa4ae9d77, 0x3f0bd118, 0x4b933897, 0xd03674f8, + 0xa7a8a608, 0x3c0dea67, 0x4e997516, 0xd53c3979, 0xa2a2eb89, + 0x3907a7e6, 0x4d9f4e69, 0xd63a0206, 0xa1a4d0f6, 0x3a019c99, + 0x448dee14, 0xdf28a27b, 0xa8b6708b, 0x33133ce4, 0x478bd56b, + 0xdc2e9904, 0xabb04bf4, 0x3015079b, 0x428198ea, 0xd924d485, + 0xaeba0675, 0x351f4a1a, 0x4187a395, 0xda22effa, 0xadbc3d0a, + 0x36197165}, + {0x00000000, 0xc18edfc0, 0x586cb9c1, 0x99e26601, 0xb0d97382, + 0x7157ac42, 0xe8b5ca43, 0x293b1583, 0xbac3e145, 0x7b4d3e85, + 0xe2af5884, 0x23218744, 0x0a1a92c7, 0xcb944d07, 0x52762b06, + 0x93f8f4c6, 0xaef6c4cb, 0x6f781b0b, 0xf69a7d0a, 0x3714a2ca, + 0x1e2fb749, 0xdfa16889, 0x46430e88, 0x87cdd148, 0x1435258e, + 0xd5bbfa4e, 0x4c599c4f, 0x8dd7438f, 0xa4ec560c, 0x656289cc, + 0xfc80efcd, 0x3d0e300d, 0x869c8fd7, 0x47125017, 0xdef03616, + 0x1f7ee9d6, 0x3645fc55, 0xf7cb2395, 0x6e294594, 0xafa79a54, + 0x3c5f6e92, 0xfdd1b152, 0x6433d753, 0xa5bd0893, 0x8c861d10, + 0x4d08c2d0, 0xd4eaa4d1, 0x15647b11, 0x286a4b1c, 0xe9e494dc, + 0x7006f2dd, 0xb1882d1d, 0x98b3389e, 0x593de75e, 0xc0df815f, + 0x01515e9f, 0x92a9aa59, 0x53277599, 0xcac51398, 0x0b4bcc58, + 0x2270d9db, 0xe3fe061b, 0x7a1c601a, 0xbb92bfda, 0xd64819ef, + 0x17c6c62f, 0x8e24a02e, 0x4faa7fee, 0x66916a6d, 0xa71fb5ad, + 0x3efdd3ac, 0xff730c6c, 0x6c8bf8aa, 0xad05276a, 0x34e7416b, + 0xf5699eab, 0xdc528b28, 0x1ddc54e8, 0x843e32e9, 0x45b0ed29, + 0x78bedd24, 0xb93002e4, 0x20d264e5, 0xe15cbb25, 0xc867aea6, + 0x09e97166, 0x900b1767, 0x5185c8a7, 0xc27d3c61, 0x03f3e3a1, + 0x9a1185a0, 0x5b9f5a60, 0x72a44fe3, 0xb32a9023, 0x2ac8f622, + 0xeb4629e2, 0x50d49638, 0x915a49f8, 0x08b82ff9, 0xc936f039, + 0xe00de5ba, 0x21833a7a, 0xb8615c7b, 0x79ef83bb, 0xea17777d, + 0x2b99a8bd, 0xb27bcebc, 0x73f5117c, 0x5ace04ff, 0x9b40db3f, + 0x02a2bd3e, 0xc32c62fe, 0xfe2252f3, 0x3fac8d33, 0xa64eeb32, + 0x67c034f2, 0x4efb2171, 0x8f75feb1, 0x169798b0, 0xd7194770, + 0x44e1b3b6, 0x856f6c76, 0x1c8d0a77, 0xdd03d5b7, 0xf438c034, + 0x35b61ff4, 0xac5479f5, 0x6ddaa635, 0x77e1359f, 0xb66fea5f, + 0x2f8d8c5e, 0xee03539e, 0xc738461d, 0x06b699dd, 0x9f54ffdc, + 0x5eda201c, 0xcd22d4da, 0x0cac0b1a, 0x954e6d1b, 0x54c0b2db, + 0x7dfba758, 0xbc757898, 0x25971e99, 0xe419c159, 0xd917f154, + 0x18992e94, 0x817b4895, 0x40f59755, 0x69ce82d6, 0xa8405d16, + 0x31a23b17, 0xf02ce4d7, 0x63d41011, 0xa25acfd1, 0x3bb8a9d0, + 0xfa367610, 0xd30d6393, 0x1283bc53, 0x8b61da52, 0x4aef0592, + 0xf17dba48, 0x30f36588, 0xa9110389, 0x689fdc49, 0x41a4c9ca, + 0x802a160a, 0x19c8700b, 0xd846afcb, 0x4bbe5b0d, 0x8a3084cd, + 0x13d2e2cc, 0xd25c3d0c, 0xfb67288f, 0x3ae9f74f, 0xa30b914e, + 0x62854e8e, 0x5f8b7e83, 0x9e05a143, 0x07e7c742, 0xc6691882, + 0xef520d01, 0x2edcd2c1, 0xb73eb4c0, 0x76b06b00, 0xe5489fc6, + 0x24c64006, 0xbd242607, 0x7caaf9c7, 0x5591ec44, 0x941f3384, + 0x0dfd5585, 0xcc738a45, 0xa1a92c70, 0x6027f3b0, 0xf9c595b1, + 0x384b4a71, 0x11705ff2, 0xd0fe8032, 0x491ce633, 0x889239f3, + 0x1b6acd35, 0xdae412f5, 0x430674f4, 0x8288ab34, 0xabb3beb7, + 0x6a3d6177, 0xf3df0776, 0x3251d8b6, 0x0f5fe8bb, 0xced1377b, + 0x5733517a, 0x96bd8eba, 0xbf869b39, 0x7e0844f9, 0xe7ea22f8, + 0x2664fd38, 0xb59c09fe, 0x7412d63e, 0xedf0b03f, 0x2c7e6fff, + 0x05457a7c, 0xc4cba5bc, 0x5d29c3bd, 0x9ca71c7d, 0x2735a3a7, + 0xe6bb7c67, 0x7f591a66, 0xbed7c5a6, 0x97ecd025, 0x56620fe5, + 0xcf8069e4, 0x0e0eb624, 0x9df642e2, 0x5c789d22, 0xc59afb23, + 0x041424e3, 0x2d2f3160, 0xeca1eea0, 0x754388a1, 0xb4cd5761, + 0x89c3676c, 0x484db8ac, 0xd1afdead, 0x1021016d, 0x391a14ee, + 0xf894cb2e, 0x6176ad2f, 0xa0f872ef, 0x33008629, 0xf28e59e9, + 0x6b6c3fe8, 0xaae2e028, 0x83d9f5ab, 0x42572a6b, 0xdbb54c6a, + 0x1a3b93aa}, + {0x00000000, 0xefc26b3e, 0x04f5d03d, 0xeb37bb03, 0x09eba07a, + 0xe629cb44, 0x0d1e7047, 0xe2dc1b79, 0x13d740f4, 0xfc152bca, + 0x172290c9, 0xf8e0fbf7, 0x1a3ce08e, 0xf5fe8bb0, 0x1ec930b3, + 0xf10b5b8d, 0x27ae81e8, 0xc86cead6, 0x235b51d5, 0xcc993aeb, + 0x2e452192, 0xc1874aac, 0x2ab0f1af, 0xc5729a91, 0x3479c11c, + 0xdbbbaa22, 0x308c1121, 0xdf4e7a1f, 0x3d926166, 0xd2500a58, + 0x3967b15b, 0xd6a5da65, 0x4f5d03d0, 0xa09f68ee, 0x4ba8d3ed, + 0xa46ab8d3, 0x46b6a3aa, 0xa974c894, 0x42437397, 0xad8118a9, + 0x5c8a4324, 0xb348281a, 0x587f9319, 0xb7bdf827, 0x5561e35e, + 0xbaa38860, 0x51943363, 0xbe56585d, 0x68f38238, 0x8731e906, + 0x6c065205, 0x83c4393b, 0x61182242, 0x8eda497c, 0x65edf27f, + 0x8a2f9941, 0x7b24c2cc, 0x94e6a9f2, 0x7fd112f1, 0x901379cf, + 0x72cf62b6, 0x9d0d0988, 0x763ab28b, 0x99f8d9b5, 0x9eba07a0, + 0x71786c9e, 0x9a4fd79d, 0x758dbca3, 0x9751a7da, 0x7893cce4, + 0x93a477e7, 0x7c661cd9, 0x8d6d4754, 0x62af2c6a, 0x89989769, + 0x665afc57, 0x8486e72e, 0x6b448c10, 0x80733713, 0x6fb15c2d, + 0xb9148648, 0x56d6ed76, 0xbde15675, 0x52233d4b, 0xb0ff2632, + 0x5f3d4d0c, 0xb40af60f, 0x5bc89d31, 0xaac3c6bc, 0x4501ad82, + 0xae361681, 0x41f47dbf, 0xa32866c6, 0x4cea0df8, 0xa7ddb6fb, + 0x481fddc5, 0xd1e70470, 0x3e256f4e, 0xd512d44d, 0x3ad0bf73, + 0xd80ca40a, 0x37cecf34, 0xdcf97437, 0x333b1f09, 0xc2304484, + 0x2df22fba, 0xc6c594b9, 0x2907ff87, 0xcbdbe4fe, 0x24198fc0, + 0xcf2e34c3, 0x20ec5ffd, 0xf6498598, 0x198beea6, 0xf2bc55a5, + 0x1d7e3e9b, 0xffa225e2, 0x10604edc, 0xfb57f5df, 0x14959ee1, + 0xe59ec56c, 0x0a5cae52, 0xe16b1551, 0x0ea97e6f, 0xec756516, + 0x03b70e28, 0xe880b52b, 0x0742de15, 0xe6050901, 0x09c7623f, + 0xe2f0d93c, 0x0d32b202, 0xefeea97b, 0x002cc245, 0xeb1b7946, + 0x04d91278, 0xf5d249f5, 0x1a1022cb, 0xf12799c8, 0x1ee5f2f6, + 0xfc39e98f, 0x13fb82b1, 0xf8cc39b2, 0x170e528c, 0xc1ab88e9, + 0x2e69e3d7, 0xc55e58d4, 0x2a9c33ea, 0xc8402893, 0x278243ad, + 0xccb5f8ae, 0x23779390, 0xd27cc81d, 0x3dbea323, 0xd6891820, + 0x394b731e, 0xdb976867, 0x34550359, 0xdf62b85a, 0x30a0d364, + 0xa9580ad1, 0x469a61ef, 0xadaddaec, 0x426fb1d2, 0xa0b3aaab, + 0x4f71c195, 0xa4467a96, 0x4b8411a8, 0xba8f4a25, 0x554d211b, + 0xbe7a9a18, 0x51b8f126, 0xb364ea5f, 0x5ca68161, 0xb7913a62, + 0x5853515c, 0x8ef68b39, 0x6134e007, 0x8a035b04, 0x65c1303a, + 0x871d2b43, 0x68df407d, 0x83e8fb7e, 0x6c2a9040, 0x9d21cbcd, + 0x72e3a0f3, 0x99d41bf0, 0x761670ce, 0x94ca6bb7, 0x7b080089, + 0x903fbb8a, 0x7ffdd0b4, 0x78bf0ea1, 0x977d659f, 0x7c4ade9c, + 0x9388b5a2, 0x7154aedb, 0x9e96c5e5, 0x75a17ee6, 0x9a6315d8, + 0x6b684e55, 0x84aa256b, 0x6f9d9e68, 0x805ff556, 0x6283ee2f, + 0x8d418511, 0x66763e12, 0x89b4552c, 0x5f118f49, 0xb0d3e477, + 0x5be45f74, 0xb426344a, 0x56fa2f33, 0xb938440d, 0x520fff0e, + 0xbdcd9430, 0x4cc6cfbd, 0xa304a483, 0x48331f80, 0xa7f174be, + 0x452d6fc7, 0xaaef04f9, 0x41d8bffa, 0xae1ad4c4, 0x37e20d71, + 0xd820664f, 0x3317dd4c, 0xdcd5b672, 0x3e09ad0b, 0xd1cbc635, + 0x3afc7d36, 0xd53e1608, 0x24354d85, 0xcbf726bb, 0x20c09db8, + 0xcf02f686, 0x2ddeedff, 0xc21c86c1, 0x292b3dc2, 0xc6e956fc, + 0x104c8c99, 0xff8ee7a7, 0x14b95ca4, 0xfb7b379a, 0x19a72ce3, + 0xf66547dd, 0x1d52fcde, 0xf29097e0, 0x039bcc6d, 0xec59a753, + 0x076e1c50, 0xe8ac776e, 0x0a706c17, 0xe5b20729, 0x0e85bc2a, + 0xe147d714}, + {0x00000000, 0x177b1443, 0x2ef62886, 0x398d3cc5, 0x5dec510c, + 0x4a97454f, 0x731a798a, 0x64616dc9, 0xbbd8a218, 0xaca3b65b, + 0x952e8a9e, 0x82559edd, 0xe634f314, 0xf14fe757, 0xc8c2db92, + 0xdfb9cfd1, 0xacc04271, 0xbbbb5632, 0x82366af7, 0x954d7eb4, + 0xf12c137d, 0xe657073e, 0xdfda3bfb, 0xc8a12fb8, 0x1718e069, + 0x0063f42a, 0x39eec8ef, 0x2e95dcac, 0x4af4b165, 0x5d8fa526, + 0x640299e3, 0x73798da0, 0x82f182a3, 0x958a96e0, 0xac07aa25, + 0xbb7cbe66, 0xdf1dd3af, 0xc866c7ec, 0xf1ebfb29, 0xe690ef6a, + 0x392920bb, 0x2e5234f8, 0x17df083d, 0x00a41c7e, 0x64c571b7, + 0x73be65f4, 0x4a335931, 0x5d484d72, 0x2e31c0d2, 0x394ad491, + 0x00c7e854, 0x17bcfc17, 0x73dd91de, 0x64a6859d, 0x5d2bb958, + 0x4a50ad1b, 0x95e962ca, 0x82927689, 0xbb1f4a4c, 0xac645e0f, + 0xc80533c6, 0xdf7e2785, 0xe6f31b40, 0xf1880f03, 0xde920307, + 0xc9e91744, 0xf0642b81, 0xe71f3fc2, 0x837e520b, 0x94054648, + 0xad887a8d, 0xbaf36ece, 0x654aa11f, 0x7231b55c, 0x4bbc8999, + 0x5cc79dda, 0x38a6f013, 0x2fdde450, 0x1650d895, 0x012bccd6, + 0x72524176, 0x65295535, 0x5ca469f0, 0x4bdf7db3, 0x2fbe107a, + 0x38c50439, 0x014838fc, 0x16332cbf, 0xc98ae36e, 0xdef1f72d, + 0xe77ccbe8, 0xf007dfab, 0x9466b262, 0x831da621, 0xba909ae4, + 0xadeb8ea7, 0x5c6381a4, 0x4b1895e7, 0x7295a922, 0x65eebd61, + 0x018fd0a8, 0x16f4c4eb, 0x2f79f82e, 0x3802ec6d, 0xe7bb23bc, + 0xf0c037ff, 0xc94d0b3a, 0xde361f79, 0xba5772b0, 0xad2c66f3, + 0x94a15a36, 0x83da4e75, 0xf0a3c3d5, 0xe7d8d796, 0xde55eb53, + 0xc92eff10, 0xad4f92d9, 0xba34869a, 0x83b9ba5f, 0x94c2ae1c, + 0x4b7b61cd, 0x5c00758e, 0x658d494b, 0x72f65d08, 0x169730c1, + 0x01ec2482, 0x38611847, 0x2f1a0c04, 0x6655004f, 0x712e140c, + 0x48a328c9, 0x5fd83c8a, 0x3bb95143, 0x2cc24500, 0x154f79c5, + 0x02346d86, 0xdd8da257, 0xcaf6b614, 0xf37b8ad1, 0xe4009e92, + 0x8061f35b, 0x971ae718, 0xae97dbdd, 0xb9eccf9e, 0xca95423e, + 0xddee567d, 0xe4636ab8, 0xf3187efb, 0x97791332, 0x80020771, + 0xb98f3bb4, 0xaef42ff7, 0x714de026, 0x6636f465, 0x5fbbc8a0, + 0x48c0dce3, 0x2ca1b12a, 0x3bdaa569, 0x025799ac, 0x152c8def, + 0xe4a482ec, 0xf3df96af, 0xca52aa6a, 0xdd29be29, 0xb948d3e0, + 0xae33c7a3, 0x97befb66, 0x80c5ef25, 0x5f7c20f4, 0x480734b7, + 0x718a0872, 0x66f11c31, 0x029071f8, 0x15eb65bb, 0x2c66597e, + 0x3b1d4d3d, 0x4864c09d, 0x5f1fd4de, 0x6692e81b, 0x71e9fc58, + 0x15889191, 0x02f385d2, 0x3b7eb917, 0x2c05ad54, 0xf3bc6285, + 0xe4c776c6, 0xdd4a4a03, 0xca315e40, 0xae503389, 0xb92b27ca, + 0x80a61b0f, 0x97dd0f4c, 0xb8c70348, 0xafbc170b, 0x96312bce, + 0x814a3f8d, 0xe52b5244, 0xf2504607, 0xcbdd7ac2, 0xdca66e81, + 0x031fa150, 0x1464b513, 0x2de989d6, 0x3a929d95, 0x5ef3f05c, + 0x4988e41f, 0x7005d8da, 0x677ecc99, 0x14074139, 0x037c557a, + 0x3af169bf, 0x2d8a7dfc, 0x49eb1035, 0x5e900476, 0x671d38b3, + 0x70662cf0, 0xafdfe321, 0xb8a4f762, 0x8129cba7, 0x9652dfe4, + 0xf233b22d, 0xe548a66e, 0xdcc59aab, 0xcbbe8ee8, 0x3a3681eb, + 0x2d4d95a8, 0x14c0a96d, 0x03bbbd2e, 0x67dad0e7, 0x70a1c4a4, + 0x492cf861, 0x5e57ec22, 0x81ee23f3, 0x969537b0, 0xaf180b75, + 0xb8631f36, 0xdc0272ff, 0xcb7966bc, 0xf2f45a79, 0xe58f4e3a, + 0x96f6c39a, 0x818dd7d9, 0xb800eb1c, 0xaf7bff5f, 0xcb1a9296, + 0xdc6186d5, 0xe5ecba10, 0xf297ae53, 0x2d2e6182, 0x3a5575c1, + 0x03d84904, 0x14a35d47, 0x70c2308e, 0x67b924cd, 0x5e341808, + 0x494f0c4b}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43147b17, 0x8628f62e, 0xc53c8d39, 0x0c51ec5d, + 0x4f45974a, 0x8a791a73, 0xc96d6164, 0x18a2d8bb, 0x5bb6a3ac, + 0x9e8a2e95, 0xdd9e5582, 0x14f334e6, 0x57e74ff1, 0x92dbc2c8, + 0xd1cfb9df, 0x7142c0ac, 0x3256bbbb, 0xf76a3682, 0xb47e4d95, + 0x7d132cf1, 0x3e0757e6, 0xfb3bdadf, 0xb82fa1c8, 0x69e01817, + 0x2af46300, 0xefc8ee39, 0xacdc952e, 0x65b1f44a, 0x26a58f5d, + 0xe3990264, 0xa08d7973, 0xa382f182, 0xe0968a95, 0x25aa07ac, + 0x66be7cbb, 0xafd31ddf, 0xecc766c8, 0x29fbebf1, 0x6aef90e6, + 0xbb202939, 0xf834522e, 0x3d08df17, 0x7e1ca400, 0xb771c564, + 0xf465be73, 0x3159334a, 0x724d485d, 0xd2c0312e, 0x91d44a39, + 0x54e8c700, 0x17fcbc17, 0xde91dd73, 0x9d85a664, 0x58b92b5d, + 0x1bad504a, 0xca62e995, 0x89769282, 0x4c4a1fbb, 0x0f5e64ac, + 0xc63305c8, 0x85277edf, 0x401bf3e6, 0x030f88f1, 0x070392de, + 0x4417e9c9, 0x812b64f0, 0xc23f1fe7, 0x0b527e83, 0x48460594, + 0x8d7a88ad, 0xce6ef3ba, 0x1fa14a65, 0x5cb53172, 0x9989bc4b, + 0xda9dc75c, 0x13f0a638, 0x50e4dd2f, 0x95d85016, 0xd6cc2b01, + 0x76415272, 0x35552965, 0xf069a45c, 0xb37ddf4b, 0x7a10be2f, + 0x3904c538, 0xfc384801, 0xbf2c3316, 0x6ee38ac9, 0x2df7f1de, + 0xe8cb7ce7, 0xabdf07f0, 0x62b26694, 0x21a61d83, 0xe49a90ba, + 0xa78eebad, 0xa481635c, 0xe795184b, 0x22a99572, 0x61bdee65, + 0xa8d08f01, 0xebc4f416, 0x2ef8792f, 0x6dec0238, 0xbc23bbe7, + 0xff37c0f0, 0x3a0b4dc9, 0x791f36de, 0xb07257ba, 0xf3662cad, + 0x365aa194, 0x754eda83, 0xd5c3a3f0, 0x96d7d8e7, 0x53eb55de, + 0x10ff2ec9, 0xd9924fad, 0x9a8634ba, 0x5fbab983, 0x1caec294, + 0xcd617b4b, 0x8e75005c, 0x4b498d65, 0x085df672, 0xc1309716, + 0x8224ec01, 0x47186138, 0x040c1a2f, 0x4f005566, 0x0c142e71, + 0xc928a348, 0x8a3cd85f, 0x4351b93b, 0x0045c22c, 0xc5794f15, + 0x866d3402, 0x57a28ddd, 0x14b6f6ca, 0xd18a7bf3, 0x929e00e4, + 0x5bf36180, 0x18e71a97, 0xdddb97ae, 0x9ecfecb9, 0x3e4295ca, + 0x7d56eedd, 0xb86a63e4, 0xfb7e18f3, 0x32137997, 0x71070280, + 0xb43b8fb9, 0xf72ff4ae, 0x26e04d71, 0x65f43666, 0xa0c8bb5f, + 0xe3dcc048, 0x2ab1a12c, 0x69a5da3b, 0xac995702, 0xef8d2c15, + 0xec82a4e4, 0xaf96dff3, 0x6aaa52ca, 0x29be29dd, 0xe0d348b9, + 0xa3c733ae, 0x66fbbe97, 0x25efc580, 0xf4207c5f, 0xb7340748, + 0x72088a71, 0x311cf166, 0xf8719002, 0xbb65eb15, 0x7e59662c, + 0x3d4d1d3b, 0x9dc06448, 0xded41f5f, 0x1be89266, 0x58fce971, + 0x91918815, 0xd285f302, 0x17b97e3b, 0x54ad052c, 0x8562bcf3, + 0xc676c7e4, 0x034a4add, 0x405e31ca, 0x893350ae, 0xca272bb9, + 0x0f1ba680, 0x4c0fdd97, 0x4803c7b8, 0x0b17bcaf, 0xce2b3196, + 0x8d3f4a81, 0x44522be5, 0x074650f2, 0xc27addcb, 0x816ea6dc, + 0x50a11f03, 0x13b56414, 0xd689e92d, 0x959d923a, 0x5cf0f35e, + 0x1fe48849, 0xdad80570, 0x99cc7e67, 0x39410714, 0x7a557c03, + 0xbf69f13a, 0xfc7d8a2d, 0x3510eb49, 0x7604905e, 0xb3381d67, + 0xf02c6670, 0x21e3dfaf, 0x62f7a4b8, 0xa7cb2981, 0xe4df5296, + 0x2db233f2, 0x6ea648e5, 0xab9ac5dc, 0xe88ebecb, 0xeb81363a, + 0xa8954d2d, 0x6da9c014, 0x2ebdbb03, 0xe7d0da67, 0xa4c4a170, + 0x61f82c49, 0x22ec575e, 0xf323ee81, 0xb0379596, 0x750b18af, + 0x361f63b8, 0xff7202dc, 0xbc6679cb, 0x795af4f2, 0x3a4e8fe5, + 0x9ac3f696, 0xd9d78d81, 0x1ceb00b8, 0x5fff7baf, 0x96921acb, + 0xd58661dc, 0x10baece5, 0x53ae97f2, 0x82612e2d, 0xc175553a, + 0x0449d803, 0x475da314, 0x8e30c270, 0xcd24b967, 0x0818345e, + 0x4b0c4f49}, + {0x00000000, 0x3e6bc2ef, 0x3dd0f504, 0x03bb37eb, 0x7aa0eb09, + 0x44cb29e6, 0x47701e0d, 0x791bdce2, 0xf440d713, 0xca2b15fc, + 0xc9902217, 0xf7fbe0f8, 0x8ee03c1a, 0xb08bfef5, 0xb330c91e, + 0x8d5b0bf1, 0xe881ae27, 0xd6ea6cc8, 0xd5515b23, 0xeb3a99cc, + 0x9221452e, 0xac4a87c1, 0xaff1b02a, 0x919a72c5, 0x1cc17934, + 0x22aabbdb, 0x21118c30, 0x1f7a4edf, 0x6661923d, 0x580a50d2, + 0x5bb16739, 0x65daa5d6, 0xd0035d4f, 0xee689fa0, 0xedd3a84b, + 0xd3b86aa4, 0xaaa3b646, 0x94c874a9, 0x97734342, 0xa91881ad, + 0x24438a5c, 0x1a2848b3, 0x19937f58, 0x27f8bdb7, 0x5ee36155, + 0x6088a3ba, 0x63339451, 0x5d5856be, 0x3882f368, 0x06e93187, + 0x0552066c, 0x3b39c483, 0x42221861, 0x7c49da8e, 0x7ff2ed65, + 0x41992f8a, 0xccc2247b, 0xf2a9e694, 0xf112d17f, 0xcf791390, + 0xb662cf72, 0x88090d9d, 0x8bb23a76, 0xb5d9f899, 0xa007ba9e, + 0x9e6c7871, 0x9dd74f9a, 0xa3bc8d75, 0xdaa75197, 0xe4cc9378, + 0xe777a493, 0xd91c667c, 0x54476d8d, 0x6a2caf62, 0x69979889, + 0x57fc5a66, 0x2ee78684, 0x108c446b, 0x13377380, 0x2d5cb16f, + 0x488614b9, 0x76edd656, 0x7556e1bd, 0x4b3d2352, 0x3226ffb0, + 0x0c4d3d5f, 0x0ff60ab4, 0x319dc85b, 0xbcc6c3aa, 0x82ad0145, + 0x811636ae, 0xbf7df441, 0xc66628a3, 0xf80dea4c, 0xfbb6dda7, + 0xc5dd1f48, 0x7004e7d1, 0x4e6f253e, 0x4dd412d5, 0x73bfd03a, + 0x0aa40cd8, 0x34cfce37, 0x3774f9dc, 0x091f3b33, 0x844430c2, + 0xba2ff22d, 0xb994c5c6, 0x87ff0729, 0xfee4dbcb, 0xc08f1924, + 0xc3342ecf, 0xfd5fec20, 0x988549f6, 0xa6ee8b19, 0xa555bcf2, + 0x9b3e7e1d, 0xe225a2ff, 0xdc4e6010, 0xdff557fb, 0xe19e9514, + 0x6cc59ee5, 0x52ae5c0a, 0x51156be1, 0x6f7ea90e, 0x166575ec, + 0x280eb703, 0x2bb580e8, 0x15de4207, 0x010905e6, 0x3f62c709, + 0x3cd9f0e2, 0x02b2320d, 0x7ba9eeef, 0x45c22c00, 0x46791beb, + 0x7812d904, 0xf549d2f5, 0xcb22101a, 0xc89927f1, 0xf6f2e51e, + 0x8fe939fc, 0xb182fb13, 0xb239ccf8, 0x8c520e17, 0xe988abc1, + 0xd7e3692e, 0xd4585ec5, 0xea339c2a, 0x932840c8, 0xad438227, + 0xaef8b5cc, 0x90937723, 0x1dc87cd2, 0x23a3be3d, 0x201889d6, + 0x1e734b39, 0x676897db, 0x59035534, 0x5ab862df, 0x64d3a030, + 0xd10a58a9, 0xef619a46, 0xecdaadad, 0xd2b16f42, 0xabaab3a0, + 0x95c1714f, 0x967a46a4, 0xa811844b, 0x254a8fba, 0x1b214d55, + 0x189a7abe, 0x26f1b851, 0x5fea64b3, 0x6181a65c, 0x623a91b7, + 0x5c515358, 0x398bf68e, 0x07e03461, 0x045b038a, 0x3a30c165, + 0x432b1d87, 0x7d40df68, 0x7efbe883, 0x40902a6c, 0xcdcb219d, + 0xf3a0e372, 0xf01bd499, 0xce701676, 0xb76bca94, 0x8900087b, + 0x8abb3f90, 0xb4d0fd7f, 0xa10ebf78, 0x9f657d97, 0x9cde4a7c, + 0xa2b58893, 0xdbae5471, 0xe5c5969e, 0xe67ea175, 0xd815639a, + 0x554e686b, 0x6b25aa84, 0x689e9d6f, 0x56f55f80, 0x2fee8362, + 0x1185418d, 0x123e7666, 0x2c55b489, 0x498f115f, 0x77e4d3b0, + 0x745fe45b, 0x4a3426b4, 0x332ffa56, 0x0d4438b9, 0x0eff0f52, + 0x3094cdbd, 0xbdcfc64c, 0x83a404a3, 0x801f3348, 0xbe74f1a7, + 0xc76f2d45, 0xf904efaa, 0xfabfd841, 0xc4d41aae, 0x710de237, + 0x4f6620d8, 0x4cdd1733, 0x72b6d5dc, 0x0bad093e, 0x35c6cbd1, + 0x367dfc3a, 0x08163ed5, 0x854d3524, 0xbb26f7cb, 0xb89dc020, + 0x86f602cf, 0xffedde2d, 0xc1861cc2, 0xc23d2b29, 0xfc56e9c6, + 0x998c4c10, 0xa7e78eff, 0xa45cb914, 0x9a377bfb, 0xe32ca719, + 0xdd4765f6, 0xdefc521d, 0xe09790f2, 0x6dcc9b03, 0x53a759ec, + 0x501c6e07, 0x6e77ace8, 0x176c700a, 0x2907b2e5, 0x2abc850e, + 0x14d747e1}, + {0x00000000, 0xc0df8ec1, 0xc1b96c58, 0x0166e299, 0x8273d9b0, + 0x42ac5771, 0x43cab5e8, 0x83153b29, 0x45e1c3ba, 0x853e4d7b, + 0x8458afe2, 0x44872123, 0xc7921a0a, 0x074d94cb, 0x062b7652, + 0xc6f4f893, 0xcbc4f6ae, 0x0b1b786f, 0x0a7d9af6, 0xcaa21437, + 0x49b72f1e, 0x8968a1df, 0x880e4346, 0x48d1cd87, 0x8e253514, + 0x4efabbd5, 0x4f9c594c, 0x8f43d78d, 0x0c56eca4, 0xcc896265, + 0xcdef80fc, 0x0d300e3d, 0xd78f9c86, 0x17501247, 0x1636f0de, + 0xd6e97e1f, 0x55fc4536, 0x9523cbf7, 0x9445296e, 0x549aa7af, + 0x926e5f3c, 0x52b1d1fd, 0x53d73364, 0x9308bda5, 0x101d868c, + 0xd0c2084d, 0xd1a4ead4, 0x117b6415, 0x1c4b6a28, 0xdc94e4e9, + 0xddf20670, 0x1d2d88b1, 0x9e38b398, 0x5ee73d59, 0x5f81dfc0, + 0x9f5e5101, 0x59aaa992, 0x99752753, 0x9813c5ca, 0x58cc4b0b, + 0xdbd97022, 0x1b06fee3, 0x1a601c7a, 0xdabf92bb, 0xef1948d6, + 0x2fc6c617, 0x2ea0248e, 0xee7faa4f, 0x6d6a9166, 0xadb51fa7, + 0xacd3fd3e, 0x6c0c73ff, 0xaaf88b6c, 0x6a2705ad, 0x6b41e734, + 0xab9e69f5, 0x288b52dc, 0xe854dc1d, 0xe9323e84, 0x29edb045, + 0x24ddbe78, 0xe40230b9, 0xe564d220, 0x25bb5ce1, 0xa6ae67c8, + 0x6671e909, 0x67170b90, 0xa7c88551, 0x613c7dc2, 0xa1e3f303, + 0xa085119a, 0x605a9f5b, 0xe34fa472, 0x23902ab3, 0x22f6c82a, + 0xe22946eb, 0x3896d450, 0xf8495a91, 0xf92fb808, 0x39f036c9, + 0xbae50de0, 0x7a3a8321, 0x7b5c61b8, 0xbb83ef79, 0x7d7717ea, + 0xbda8992b, 0xbcce7bb2, 0x7c11f573, 0xff04ce5a, 0x3fdb409b, + 0x3ebda202, 0xfe622cc3, 0xf35222fe, 0x338dac3f, 0x32eb4ea6, + 0xf234c067, 0x7121fb4e, 0xb1fe758f, 0xb0989716, 0x704719d7, + 0xb6b3e144, 0x766c6f85, 0x770a8d1c, 0xb7d503dd, 0x34c038f4, + 0xf41fb635, 0xf57954ac, 0x35a6da6d, 0x9f35e177, 0x5fea6fb6, + 0x5e8c8d2f, 0x9e5303ee, 0x1d4638c7, 0xdd99b606, 0xdcff549f, + 0x1c20da5e, 0xdad422cd, 0x1a0bac0c, 0x1b6d4e95, 0xdbb2c054, + 0x58a7fb7d, 0x987875bc, 0x991e9725, 0x59c119e4, 0x54f117d9, + 0x942e9918, 0x95487b81, 0x5597f540, 0xd682ce69, 0x165d40a8, + 0x173ba231, 0xd7e42cf0, 0x1110d463, 0xd1cf5aa2, 0xd0a9b83b, + 0x107636fa, 0x93630dd3, 0x53bc8312, 0x52da618b, 0x9205ef4a, + 0x48ba7df1, 0x8865f330, 0x890311a9, 0x49dc9f68, 0xcac9a441, + 0x0a162a80, 0x0b70c819, 0xcbaf46d8, 0x0d5bbe4b, 0xcd84308a, + 0xcce2d213, 0x0c3d5cd2, 0x8f2867fb, 0x4ff7e93a, 0x4e910ba3, + 0x8e4e8562, 0x837e8b5f, 0x43a1059e, 0x42c7e707, 0x821869c6, + 0x010d52ef, 0xc1d2dc2e, 0xc0b43eb7, 0x006bb076, 0xc69f48e5, + 0x0640c624, 0x072624bd, 0xc7f9aa7c, 0x44ec9155, 0x84331f94, + 0x8555fd0d, 0x458a73cc, 0x702ca9a1, 0xb0f32760, 0xb195c5f9, + 0x714a4b38, 0xf25f7011, 0x3280fed0, 0x33e61c49, 0xf3399288, + 0x35cd6a1b, 0xf512e4da, 0xf4740643, 0x34ab8882, 0xb7beb3ab, + 0x77613d6a, 0x7607dff3, 0xb6d85132, 0xbbe85f0f, 0x7b37d1ce, + 0x7a513357, 0xba8ebd96, 0x399b86bf, 0xf944087e, 0xf822eae7, + 0x38fd6426, 0xfe099cb5, 0x3ed61274, 0x3fb0f0ed, 0xff6f7e2c, + 0x7c7a4505, 0xbca5cbc4, 0xbdc3295d, 0x7d1ca79c, 0xa7a33527, + 0x677cbbe6, 0x661a597f, 0xa6c5d7be, 0x25d0ec97, 0xe50f6256, + 0xe46980cf, 0x24b60e0e, 0xe242f69d, 0x229d785c, 0x23fb9ac5, + 0xe3241404, 0x60312f2d, 0xa0eea1ec, 0xa1884375, 0x6157cdb4, + 0x6c67c389, 0xacb84d48, 0xaddeafd1, 0x6d012110, 0xee141a39, + 0x2ecb94f8, 0x2fad7661, 0xef72f8a0, 0x29860033, 0xe9598ef2, + 0xe83f6c6b, 0x28e0e2aa, 0xabf5d983, 0x6b2a5742, 0x6a4cb5db, + 0xaa933b1a}, + {0x00000000, 0x6f4ca59b, 0x9f9e3bec, 0xf0d29e77, 0x7f3b0603, + 0x1077a398, 0xe0a53def, 0x8fe99874, 0xfe760c06, 0x913aa99d, + 0x61e837ea, 0x0ea49271, 0x814d0a05, 0xee01af9e, 0x1ed331e9, + 0x719f9472, 0xfced180c, 0x93a1bd97, 0x637323e0, 0x0c3f867b, + 0x83d61e0f, 0xec9abb94, 0x1c4825e3, 0x73048078, 0x029b140a, + 0x6dd7b191, 0x9d052fe6, 0xf2498a7d, 0x7da01209, 0x12ecb792, + 0xe23e29e5, 0x8d728c7e, 0xf8db3118, 0x97979483, 0x67450af4, + 0x0809af6f, 0x87e0371b, 0xe8ac9280, 0x187e0cf7, 0x7732a96c, + 0x06ad3d1e, 0x69e19885, 0x993306f2, 0xf67fa369, 0x79963b1d, + 0x16da9e86, 0xe60800f1, 0x8944a56a, 0x04362914, 0x6b7a8c8f, + 0x9ba812f8, 0xf4e4b763, 0x7b0d2f17, 0x14418a8c, 0xe49314fb, + 0x8bdfb160, 0xfa402512, 0x950c8089, 0x65de1efe, 0x0a92bb65, + 0x857b2311, 0xea37868a, 0x1ae518fd, 0x75a9bd66, 0xf0b76330, + 0x9ffbc6ab, 0x6f2958dc, 0x0065fd47, 0x8f8c6533, 0xe0c0c0a8, + 0x10125edf, 0x7f5efb44, 0x0ec16f36, 0x618dcaad, 0x915f54da, + 0xfe13f141, 0x71fa6935, 0x1eb6ccae, 0xee6452d9, 0x8128f742, + 0x0c5a7b3c, 0x6316dea7, 0x93c440d0, 0xfc88e54b, 0x73617d3f, + 0x1c2dd8a4, 0xecff46d3, 0x83b3e348, 0xf22c773a, 0x9d60d2a1, + 0x6db24cd6, 0x02fee94d, 0x8d177139, 0xe25bd4a2, 0x12894ad5, + 0x7dc5ef4e, 0x086c5228, 0x6720f7b3, 0x97f269c4, 0xf8becc5f, + 0x7757542b, 0x181bf1b0, 0xe8c96fc7, 0x8785ca5c, 0xf61a5e2e, + 0x9956fbb5, 0x698465c2, 0x06c8c059, 0x8921582d, 0xe66dfdb6, + 0x16bf63c1, 0x79f3c65a, 0xf4814a24, 0x9bcdefbf, 0x6b1f71c8, + 0x0453d453, 0x8bba4c27, 0xe4f6e9bc, 0x142477cb, 0x7b68d250, + 0x0af74622, 0x65bbe3b9, 0x95697dce, 0xfa25d855, 0x75cc4021, + 0x1a80e5ba, 0xea527bcd, 0x851ede56, 0xe06fc760, 0x8f2362fb, + 0x7ff1fc8c, 0x10bd5917, 0x9f54c163, 0xf01864f8, 0x00cafa8f, + 0x6f865f14, 0x1e19cb66, 0x71556efd, 0x8187f08a, 0xeecb5511, + 0x6122cd65, 0x0e6e68fe, 0xfebcf689, 0x91f05312, 0x1c82df6c, + 0x73ce7af7, 0x831ce480, 0xec50411b, 0x63b9d96f, 0x0cf57cf4, + 0xfc27e283, 0x936b4718, 0xe2f4d36a, 0x8db876f1, 0x7d6ae886, + 0x12264d1d, 0x9dcfd569, 0xf28370f2, 0x0251ee85, 0x6d1d4b1e, + 0x18b4f678, 0x77f853e3, 0x872acd94, 0xe866680f, 0x678ff07b, + 0x08c355e0, 0xf811cb97, 0x975d6e0c, 0xe6c2fa7e, 0x898e5fe5, + 0x795cc192, 0x16106409, 0x99f9fc7d, 0xf6b559e6, 0x0667c791, + 0x692b620a, 0xe459ee74, 0x8b154bef, 0x7bc7d598, 0x148b7003, + 0x9b62e877, 0xf42e4dec, 0x04fcd39b, 0x6bb07600, 0x1a2fe272, + 0x756347e9, 0x85b1d99e, 0xeafd7c05, 0x6514e471, 0x0a5841ea, + 0xfa8adf9d, 0x95c67a06, 0x10d8a450, 0x7f9401cb, 0x8f469fbc, + 0xe00a3a27, 0x6fe3a253, 0x00af07c8, 0xf07d99bf, 0x9f313c24, + 0xeeaea856, 0x81e20dcd, 0x713093ba, 0x1e7c3621, 0x9195ae55, + 0xfed90bce, 0x0e0b95b9, 0x61473022, 0xec35bc5c, 0x837919c7, + 0x73ab87b0, 0x1ce7222b, 0x930eba5f, 0xfc421fc4, 0x0c9081b3, + 0x63dc2428, 0x1243b05a, 0x7d0f15c1, 0x8ddd8bb6, 0xe2912e2d, + 0x6d78b659, 0x023413c2, 0xf2e68db5, 0x9daa282e, 0xe8039548, + 0x874f30d3, 0x779daea4, 0x18d10b3f, 0x9738934b, 0xf87436d0, + 0x08a6a8a7, 0x67ea0d3c, 0x1675994e, 0x79393cd5, 0x89eba2a2, + 0xe6a70739, 0x694e9f4d, 0x06023ad6, 0xf6d0a4a1, 0x999c013a, + 0x14ee8d44, 0x7ba228df, 0x8b70b6a8, 0xe43c1333, 0x6bd58b47, + 0x04992edc, 0xf44bb0ab, 0x9b071530, 0xea988142, 0x85d424d9, + 0x7506baae, 0x1a4a1f35, 0x95a38741, 0xfaef22da, 0x0a3dbcad, + 0x65711936}}; + +#endif /* W */ + +#endif /* N == 3 */ +#if N == 4 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xf1da05aa, 0x38c50d15, 0xc91f08bf, 0x718a1a2a, + 0x80501f80, 0x494f173f, 0xb8951295, 0xe3143454, 0x12ce31fe, + 0xdbd13941, 0x2a0b3ceb, 0x929e2e7e, 0x63442bd4, 0xaa5b236b, + 0x5b8126c1, 0x1d596ee9, 0xec836b43, 0x259c63fc, 0xd4466656, + 0x6cd374c3, 0x9d097169, 0x541679d6, 0xa5cc7c7c, 0xfe4d5abd, + 0x0f975f17, 0xc68857a8, 0x37525202, 0x8fc74097, 0x7e1d453d, + 0xb7024d82, 0x46d84828, 0x3ab2ddd2, 0xcb68d878, 0x0277d0c7, + 0xf3add56d, 0x4b38c7f8, 0xbae2c252, 0x73fdcaed, 0x8227cf47, + 0xd9a6e986, 0x287cec2c, 0xe163e493, 0x10b9e139, 0xa82cf3ac, + 0x59f6f606, 0x90e9feb9, 0x6133fb13, 0x27ebb33b, 0xd631b691, + 0x1f2ebe2e, 0xeef4bb84, 0x5661a911, 0xa7bbacbb, 0x6ea4a404, + 0x9f7ea1ae, 0xc4ff876f, 0x352582c5, 0xfc3a8a7a, 0x0de08fd0, + 0xb5759d45, 0x44af98ef, 0x8db09050, 0x7c6a95fa, 0x7565bba4, + 0x84bfbe0e, 0x4da0b6b1, 0xbc7ab31b, 0x04efa18e, 0xf535a424, + 0x3c2aac9b, 0xcdf0a931, 0x96718ff0, 0x67ab8a5a, 0xaeb482e5, + 0x5f6e874f, 0xe7fb95da, 0x16219070, 0xdf3e98cf, 0x2ee49d65, + 0x683cd54d, 0x99e6d0e7, 0x50f9d858, 0xa123ddf2, 0x19b6cf67, + 0xe86ccacd, 0x2173c272, 0xd0a9c7d8, 0x8b28e119, 0x7af2e4b3, + 0xb3edec0c, 0x4237e9a6, 0xfaa2fb33, 0x0b78fe99, 0xc267f626, + 0x33bdf38c, 0x4fd76676, 0xbe0d63dc, 0x77126b63, 0x86c86ec9, + 0x3e5d7c5c, 0xcf8779f6, 0x06987149, 0xf74274e3, 0xacc35222, + 0x5d195788, 0x94065f37, 0x65dc5a9d, 0xdd494808, 0x2c934da2, + 0xe58c451d, 0x145640b7, 0x528e089f, 0xa3540d35, 0x6a4b058a, + 0x9b910020, 0x230412b5, 0xd2de171f, 0x1bc11fa0, 0xea1b1a0a, + 0xb19a3ccb, 0x40403961, 0x895f31de, 0x78853474, 0xc01026e1, + 0x31ca234b, 0xf8d52bf4, 0x090f2e5e, 0xeacb7748, 0x1b1172e2, + 0xd20e7a5d, 0x23d47ff7, 0x9b416d62, 0x6a9b68c8, 0xa3846077, + 0x525e65dd, 0x09df431c, 0xf80546b6, 0x311a4e09, 0xc0c04ba3, + 0x78555936, 0x898f5c9c, 0x40905423, 0xb14a5189, 0xf79219a1, + 0x06481c0b, 0xcf5714b4, 0x3e8d111e, 0x8618038b, 0x77c20621, + 0xbedd0e9e, 0x4f070b34, 0x14862df5, 0xe55c285f, 0x2c4320e0, + 0xdd99254a, 0x650c37df, 0x94d63275, 0x5dc93aca, 0xac133f60, + 0xd079aa9a, 0x21a3af30, 0xe8bca78f, 0x1966a225, 0xa1f3b0b0, + 0x5029b51a, 0x9936bda5, 0x68ecb80f, 0x336d9ece, 0xc2b79b64, + 0x0ba893db, 0xfa729671, 0x42e784e4, 0xb33d814e, 0x7a2289f1, + 0x8bf88c5b, 0xcd20c473, 0x3cfac1d9, 0xf5e5c966, 0x043fcccc, + 0xbcaade59, 0x4d70dbf3, 0x846fd34c, 0x75b5d6e6, 0x2e34f027, + 0xdfeef58d, 0x16f1fd32, 0xe72bf898, 0x5fbeea0d, 0xae64efa7, + 0x677be718, 0x96a1e2b2, 0x9faeccec, 0x6e74c946, 0xa76bc1f9, + 0x56b1c453, 0xee24d6c6, 0x1ffed36c, 0xd6e1dbd3, 0x273bde79, + 0x7cbaf8b8, 0x8d60fd12, 0x447ff5ad, 0xb5a5f007, 0x0d30e292, + 0xfceae738, 0x35f5ef87, 0xc42fea2d, 0x82f7a205, 0x732da7af, + 0xba32af10, 0x4be8aaba, 0xf37db82f, 0x02a7bd85, 0xcbb8b53a, + 0x3a62b090, 0x61e39651, 0x903993fb, 0x59269b44, 0xa8fc9eee, + 0x10698c7b, 0xe1b389d1, 0x28ac816e, 0xd97684c4, 0xa51c113e, + 0x54c61494, 0x9dd91c2b, 0x6c031981, 0xd4960b14, 0x254c0ebe, + 0xec530601, 0x1d8903ab, 0x4608256a, 0xb7d220c0, 0x7ecd287f, + 0x8f172dd5, 0x37823f40, 0xc6583aea, 0x0f473255, 0xfe9d37ff, + 0xb8457fd7, 0x499f7a7d, 0x808072c2, 0x715a7768, 0xc9cf65fd, + 0x38156057, 0xf10a68e8, 0x00d06d42, 0x5b514b83, 0xaa8b4e29, + 0x63944696, 0x924e433c, 0x2adb51a9, 0xdb015403, 0x121e5cbc, + 0xe3c45916}, + {0x00000000, 0x0ee7e8d1, 0x1dcfd1a2, 0x13283973, 0x3b9fa344, + 0x35784b95, 0x265072e6, 0x28b79a37, 0x773f4688, 0x79d8ae59, + 0x6af0972a, 0x64177ffb, 0x4ca0e5cc, 0x42470d1d, 0x516f346e, + 0x5f88dcbf, 0xee7e8d10, 0xe09965c1, 0xf3b15cb2, 0xfd56b463, + 0xd5e12e54, 0xdb06c685, 0xc82efff6, 0xc6c91727, 0x9941cb98, + 0x97a62349, 0x848e1a3a, 0x8a69f2eb, 0xa2de68dc, 0xac39800d, + 0xbf11b97e, 0xb1f651af, 0x078c1c61, 0x096bf4b0, 0x1a43cdc3, + 0x14a42512, 0x3c13bf25, 0x32f457f4, 0x21dc6e87, 0x2f3b8656, + 0x70b35ae9, 0x7e54b238, 0x6d7c8b4b, 0x639b639a, 0x4b2cf9ad, + 0x45cb117c, 0x56e3280f, 0x5804c0de, 0xe9f29171, 0xe71579a0, + 0xf43d40d3, 0xfadaa802, 0xd26d3235, 0xdc8adae4, 0xcfa2e397, + 0xc1450b46, 0x9ecdd7f9, 0x902a3f28, 0x8302065b, 0x8de5ee8a, + 0xa55274bd, 0xabb59c6c, 0xb89da51f, 0xb67a4dce, 0x0f1838c2, + 0x01ffd013, 0x12d7e960, 0x1c3001b1, 0x34879b86, 0x3a607357, + 0x29484a24, 0x27afa2f5, 0x78277e4a, 0x76c0969b, 0x65e8afe8, + 0x6b0f4739, 0x43b8dd0e, 0x4d5f35df, 0x5e770cac, 0x5090e47d, + 0xe166b5d2, 0xef815d03, 0xfca96470, 0xf24e8ca1, 0xdaf91696, + 0xd41efe47, 0xc736c734, 0xc9d12fe5, 0x9659f35a, 0x98be1b8b, + 0x8b9622f8, 0x8571ca29, 0xadc6501e, 0xa321b8cf, 0xb00981bc, + 0xbeee696d, 0x089424a3, 0x0673cc72, 0x155bf501, 0x1bbc1dd0, + 0x330b87e7, 0x3dec6f36, 0x2ec45645, 0x2023be94, 0x7fab622b, + 0x714c8afa, 0x6264b389, 0x6c835b58, 0x4434c16f, 0x4ad329be, + 0x59fb10cd, 0x571cf81c, 0xe6eaa9b3, 0xe80d4162, 0xfb257811, + 0xf5c290c0, 0xdd750af7, 0xd392e226, 0xc0badb55, 0xce5d3384, + 0x91d5ef3b, 0x9f3207ea, 0x8c1a3e99, 0x82fdd648, 0xaa4a4c7f, + 0xa4ada4ae, 0xb7859ddd, 0xb962750c, 0x1e307184, 0x10d79955, + 0x03ffa026, 0x0d1848f7, 0x25afd2c0, 0x2b483a11, 0x38600362, + 0x3687ebb3, 0x690f370c, 0x67e8dfdd, 0x74c0e6ae, 0x7a270e7f, + 0x52909448, 0x5c777c99, 0x4f5f45ea, 0x41b8ad3b, 0xf04efc94, + 0xfea91445, 0xed812d36, 0xe366c5e7, 0xcbd15fd0, 0xc536b701, + 0xd61e8e72, 0xd8f966a3, 0x8771ba1c, 0x899652cd, 0x9abe6bbe, + 0x9459836f, 0xbcee1958, 0xb209f189, 0xa121c8fa, 0xafc6202b, + 0x19bc6de5, 0x175b8534, 0x0473bc47, 0x0a945496, 0x2223cea1, + 0x2cc42670, 0x3fec1f03, 0x310bf7d2, 0x6e832b6d, 0x6064c3bc, + 0x734cfacf, 0x7dab121e, 0x551c8829, 0x5bfb60f8, 0x48d3598b, + 0x4634b15a, 0xf7c2e0f5, 0xf9250824, 0xea0d3157, 0xe4ead986, + 0xcc5d43b1, 0xc2baab60, 0xd1929213, 0xdf757ac2, 0x80fda67d, + 0x8e1a4eac, 0x9d3277df, 0x93d59f0e, 0xbb620539, 0xb585ede8, + 0xa6add49b, 0xa84a3c4a, 0x11284946, 0x1fcfa197, 0x0ce798e4, + 0x02007035, 0x2ab7ea02, 0x245002d3, 0x37783ba0, 0x399fd371, + 0x66170fce, 0x68f0e71f, 0x7bd8de6c, 0x753f36bd, 0x5d88ac8a, + 0x536f445b, 0x40477d28, 0x4ea095f9, 0xff56c456, 0xf1b12c87, + 0xe29915f4, 0xec7efd25, 0xc4c96712, 0xca2e8fc3, 0xd906b6b0, + 0xd7e15e61, 0x886982de, 0x868e6a0f, 0x95a6537c, 0x9b41bbad, + 0xb3f6219a, 0xbd11c94b, 0xae39f038, 0xa0de18e9, 0x16a45527, + 0x1843bdf6, 0x0b6b8485, 0x058c6c54, 0x2d3bf663, 0x23dc1eb2, + 0x30f427c1, 0x3e13cf10, 0x619b13af, 0x6f7cfb7e, 0x7c54c20d, + 0x72b32adc, 0x5a04b0eb, 0x54e3583a, 0x47cb6149, 0x492c8998, + 0xf8dad837, 0xf63d30e6, 0xe5150995, 0xebf2e144, 0xc3457b73, + 0xcda293a2, 0xde8aaad1, 0xd06d4200, 0x8fe59ebf, 0x8102766e, + 0x922a4f1d, 0x9ccda7cc, 0xb47a3dfb, 0xba9dd52a, 0xa9b5ec59, + 0xa7520488}, + {0x00000000, 0x3c60e308, 0x78c1c610, 0x44a12518, 0xf1838c20, + 0xcde36f28, 0x89424a30, 0xb522a938, 0x38761e01, 0x0416fd09, + 0x40b7d811, 0x7cd73b19, 0xc9f59221, 0xf5957129, 0xb1345431, + 0x8d54b739, 0x70ec3c02, 0x4c8cdf0a, 0x082dfa12, 0x344d191a, + 0x816fb022, 0xbd0f532a, 0xf9ae7632, 0xc5ce953a, 0x489a2203, + 0x74fac10b, 0x305be413, 0x0c3b071b, 0xb919ae23, 0x85794d2b, + 0xc1d86833, 0xfdb88b3b, 0xe1d87804, 0xddb89b0c, 0x9919be14, + 0xa5795d1c, 0x105bf424, 0x2c3b172c, 0x689a3234, 0x54fad13c, + 0xd9ae6605, 0xe5ce850d, 0xa16fa015, 0x9d0f431d, 0x282dea25, + 0x144d092d, 0x50ec2c35, 0x6c8ccf3d, 0x91344406, 0xad54a70e, + 0xe9f58216, 0xd595611e, 0x60b7c826, 0x5cd72b2e, 0x18760e36, + 0x2416ed3e, 0xa9425a07, 0x9522b90f, 0xd1839c17, 0xede37f1f, + 0x58c1d627, 0x64a1352f, 0x20001037, 0x1c60f33f, 0x18c1f649, + 0x24a11541, 0x60003059, 0x5c60d351, 0xe9427a69, 0xd5229961, + 0x9183bc79, 0xade35f71, 0x20b7e848, 0x1cd70b40, 0x58762e58, + 0x6416cd50, 0xd1346468, 0xed548760, 0xa9f5a278, 0x95954170, + 0x682dca4b, 0x544d2943, 0x10ec0c5b, 0x2c8cef53, 0x99ae466b, + 0xa5cea563, 0xe16f807b, 0xdd0f6373, 0x505bd44a, 0x6c3b3742, + 0x289a125a, 0x14faf152, 0xa1d8586a, 0x9db8bb62, 0xd9199e7a, + 0xe5797d72, 0xf9198e4d, 0xc5796d45, 0x81d8485d, 0xbdb8ab55, + 0x089a026d, 0x34fae165, 0x705bc47d, 0x4c3b2775, 0xc16f904c, + 0xfd0f7344, 0xb9ae565c, 0x85ceb554, 0x30ec1c6c, 0x0c8cff64, + 0x482dda7c, 0x744d3974, 0x89f5b24f, 0xb5955147, 0xf134745f, + 0xcd549757, 0x78763e6f, 0x4416dd67, 0x00b7f87f, 0x3cd71b77, + 0xb183ac4e, 0x8de34f46, 0xc9426a5e, 0xf5228956, 0x4000206e, + 0x7c60c366, 0x38c1e67e, 0x04a10576, 0x3183ec92, 0x0de30f9a, + 0x49422a82, 0x7522c98a, 0xc00060b2, 0xfc6083ba, 0xb8c1a6a2, + 0x84a145aa, 0x09f5f293, 0x3595119b, 0x71343483, 0x4d54d78b, + 0xf8767eb3, 0xc4169dbb, 0x80b7b8a3, 0xbcd75bab, 0x416fd090, + 0x7d0f3398, 0x39ae1680, 0x05cef588, 0xb0ec5cb0, 0x8c8cbfb8, + 0xc82d9aa0, 0xf44d79a8, 0x7919ce91, 0x45792d99, 0x01d80881, + 0x3db8eb89, 0x889a42b1, 0xb4faa1b9, 0xf05b84a1, 0xcc3b67a9, + 0xd05b9496, 0xec3b779e, 0xa89a5286, 0x94fab18e, 0x21d818b6, + 0x1db8fbbe, 0x5919dea6, 0x65793dae, 0xe82d8a97, 0xd44d699f, + 0x90ec4c87, 0xac8caf8f, 0x19ae06b7, 0x25cee5bf, 0x616fc0a7, + 0x5d0f23af, 0xa0b7a894, 0x9cd74b9c, 0xd8766e84, 0xe4168d8c, + 0x513424b4, 0x6d54c7bc, 0x29f5e2a4, 0x159501ac, 0x98c1b695, + 0xa4a1559d, 0xe0007085, 0xdc60938d, 0x69423ab5, 0x5522d9bd, + 0x1183fca5, 0x2de31fad, 0x29421adb, 0x1522f9d3, 0x5183dccb, + 0x6de33fc3, 0xd8c196fb, 0xe4a175f3, 0xa00050eb, 0x9c60b3e3, + 0x113404da, 0x2d54e7d2, 0x69f5c2ca, 0x559521c2, 0xe0b788fa, + 0xdcd76bf2, 0x98764eea, 0xa416ade2, 0x59ae26d9, 0x65cec5d1, + 0x216fe0c9, 0x1d0f03c1, 0xa82daaf9, 0x944d49f1, 0xd0ec6ce9, + 0xec8c8fe1, 0x61d838d8, 0x5db8dbd0, 0x1919fec8, 0x25791dc0, + 0x905bb4f8, 0xac3b57f0, 0xe89a72e8, 0xd4fa91e0, 0xc89a62df, + 0xf4fa81d7, 0xb05ba4cf, 0x8c3b47c7, 0x3919eeff, 0x05790df7, + 0x41d828ef, 0x7db8cbe7, 0xf0ec7cde, 0xcc8c9fd6, 0x882dbace, + 0xb44d59c6, 0x016ff0fe, 0x3d0f13f6, 0x79ae36ee, 0x45ced5e6, + 0xb8765edd, 0x8416bdd5, 0xc0b798cd, 0xfcd77bc5, 0x49f5d2fd, + 0x759531f5, 0x313414ed, 0x0d54f7e5, 0x800040dc, 0xbc60a3d4, + 0xf8c186cc, 0xc4a165c4, 0x7183ccfc, 0x4de32ff4, 0x09420aec, + 0x3522e9e4}, + {0x00000000, 0x6307d924, 0xc60fb248, 0xa5086b6c, 0x576e62d1, + 0x3469bbf5, 0x9161d099, 0xf26609bd, 0xaedcc5a2, 0xcddb1c86, + 0x68d377ea, 0x0bd4aece, 0xf9b2a773, 0x9ab57e57, 0x3fbd153b, + 0x5cbacc1f, 0x86c88d05, 0xe5cf5421, 0x40c73f4d, 0x23c0e669, + 0xd1a6efd4, 0xb2a136f0, 0x17a95d9c, 0x74ae84b8, 0x281448a7, + 0x4b139183, 0xee1bfaef, 0x8d1c23cb, 0x7f7a2a76, 0x1c7df352, + 0xb975983e, 0xda72411a, 0xd6e01c4b, 0xb5e7c56f, 0x10efae03, + 0x73e87727, 0x818e7e9a, 0xe289a7be, 0x4781ccd2, 0x248615f6, + 0x783cd9e9, 0x1b3b00cd, 0xbe336ba1, 0xdd34b285, 0x2f52bb38, + 0x4c55621c, 0xe95d0970, 0x8a5ad054, 0x5028914e, 0x332f486a, + 0x96272306, 0xf520fa22, 0x0746f39f, 0x64412abb, 0xc14941d7, + 0xa24e98f3, 0xfef454ec, 0x9df38dc8, 0x38fbe6a4, 0x5bfc3f80, + 0xa99a363d, 0xca9def19, 0x6f958475, 0x0c925d51, 0x76b13ed7, + 0x15b6e7f3, 0xb0be8c9f, 0xd3b955bb, 0x21df5c06, 0x42d88522, + 0xe7d0ee4e, 0x84d7376a, 0xd86dfb75, 0xbb6a2251, 0x1e62493d, + 0x7d659019, 0x8f0399a4, 0xec044080, 0x490c2bec, 0x2a0bf2c8, + 0xf079b3d2, 0x937e6af6, 0x3676019a, 0x5571d8be, 0xa717d103, + 0xc4100827, 0x6118634b, 0x021fba6f, 0x5ea57670, 0x3da2af54, + 0x98aac438, 0xfbad1d1c, 0x09cb14a1, 0x6acccd85, 0xcfc4a6e9, + 0xacc37fcd, 0xa051229c, 0xc356fbb8, 0x665e90d4, 0x055949f0, + 0xf73f404d, 0x94389969, 0x3130f205, 0x52372b21, 0x0e8de73e, + 0x6d8a3e1a, 0xc8825576, 0xab858c52, 0x59e385ef, 0x3ae45ccb, + 0x9fec37a7, 0xfcebee83, 0x2699af99, 0x459e76bd, 0xe0961dd1, + 0x8391c4f5, 0x71f7cd48, 0x12f0146c, 0xb7f87f00, 0xd4ffa624, + 0x88456a3b, 0xeb42b31f, 0x4e4ad873, 0x2d4d0157, 0xdf2b08ea, + 0xbc2cd1ce, 0x1924baa2, 0x7a236386, 0xed627dae, 0x8e65a48a, + 0x2b6dcfe6, 0x486a16c2, 0xba0c1f7f, 0xd90bc65b, 0x7c03ad37, + 0x1f047413, 0x43beb80c, 0x20b96128, 0x85b10a44, 0xe6b6d360, + 0x14d0dadd, 0x77d703f9, 0xd2df6895, 0xb1d8b1b1, 0x6baaf0ab, + 0x08ad298f, 0xada542e3, 0xcea29bc7, 0x3cc4927a, 0x5fc34b5e, + 0xfacb2032, 0x99ccf916, 0xc5763509, 0xa671ec2d, 0x03798741, + 0x607e5e65, 0x921857d8, 0xf11f8efc, 0x5417e590, 0x37103cb4, + 0x3b8261e5, 0x5885b8c1, 0xfd8dd3ad, 0x9e8a0a89, 0x6cec0334, + 0x0febda10, 0xaae3b17c, 0xc9e46858, 0x955ea447, 0xf6597d63, + 0x5351160f, 0x3056cf2b, 0xc230c696, 0xa1371fb2, 0x043f74de, + 0x6738adfa, 0xbd4aece0, 0xde4d35c4, 0x7b455ea8, 0x1842878c, + 0xea248e31, 0x89235715, 0x2c2b3c79, 0x4f2ce55d, 0x13962942, + 0x7091f066, 0xd5999b0a, 0xb69e422e, 0x44f84b93, 0x27ff92b7, + 0x82f7f9db, 0xe1f020ff, 0x9bd34379, 0xf8d49a5d, 0x5ddcf131, + 0x3edb2815, 0xccbd21a8, 0xafbaf88c, 0x0ab293e0, 0x69b54ac4, + 0x350f86db, 0x56085fff, 0xf3003493, 0x9007edb7, 0x6261e40a, + 0x01663d2e, 0xa46e5642, 0xc7698f66, 0x1d1bce7c, 0x7e1c1758, + 0xdb147c34, 0xb813a510, 0x4a75acad, 0x29727589, 0x8c7a1ee5, + 0xef7dc7c1, 0xb3c70bde, 0xd0c0d2fa, 0x75c8b996, 0x16cf60b2, + 0xe4a9690f, 0x87aeb02b, 0x22a6db47, 0x41a10263, 0x4d335f32, + 0x2e348616, 0x8b3ced7a, 0xe83b345e, 0x1a5d3de3, 0x795ae4c7, + 0xdc528fab, 0xbf55568f, 0xe3ef9a90, 0x80e843b4, 0x25e028d8, + 0x46e7f1fc, 0xb481f841, 0xd7862165, 0x728e4a09, 0x1189932d, + 0xcbfbd237, 0xa8fc0b13, 0x0df4607f, 0x6ef3b95b, 0x9c95b0e6, + 0xff9269c2, 0x5a9a02ae, 0x399ddb8a, 0x65271795, 0x0620ceb1, + 0xa328a5dd, 0xc02f7cf9, 0x32497544, 0x514eac60, 0xf446c70c, + 0x97411e28}, + {0x00000000, 0x01b5fd1d, 0x036bfa3a, 0x02de0727, 0x06d7f474, + 0x07620969, 0x05bc0e4e, 0x0409f353, 0x0dafe8e8, 0x0c1a15f5, + 0x0ec412d2, 0x0f71efcf, 0x0b781c9c, 0x0acde181, 0x0813e6a6, + 0x09a61bbb, 0x1b5fd1d0, 0x1aea2ccd, 0x18342bea, 0x1981d6f7, + 0x1d8825a4, 0x1c3dd8b9, 0x1ee3df9e, 0x1f562283, 0x16f03938, + 0x1745c425, 0x159bc302, 0x142e3e1f, 0x1027cd4c, 0x11923051, + 0x134c3776, 0x12f9ca6b, 0x36bfa3a0, 0x370a5ebd, 0x35d4599a, + 0x3461a487, 0x306857d4, 0x31ddaac9, 0x3303adee, 0x32b650f3, + 0x3b104b48, 0x3aa5b655, 0x387bb172, 0x39ce4c6f, 0x3dc7bf3c, + 0x3c724221, 0x3eac4506, 0x3f19b81b, 0x2de07270, 0x2c558f6d, + 0x2e8b884a, 0x2f3e7557, 0x2b378604, 0x2a827b19, 0x285c7c3e, + 0x29e98123, 0x204f9a98, 0x21fa6785, 0x232460a2, 0x22919dbf, + 0x26986eec, 0x272d93f1, 0x25f394d6, 0x244669cb, 0x6d7f4740, + 0x6ccaba5d, 0x6e14bd7a, 0x6fa14067, 0x6ba8b334, 0x6a1d4e29, + 0x68c3490e, 0x6976b413, 0x60d0afa8, 0x616552b5, 0x63bb5592, + 0x620ea88f, 0x66075bdc, 0x67b2a6c1, 0x656ca1e6, 0x64d95cfb, + 0x76209690, 0x77956b8d, 0x754b6caa, 0x74fe91b7, 0x70f762e4, + 0x71429ff9, 0x739c98de, 0x722965c3, 0x7b8f7e78, 0x7a3a8365, + 0x78e48442, 0x7951795f, 0x7d588a0c, 0x7ced7711, 0x7e337036, + 0x7f868d2b, 0x5bc0e4e0, 0x5a7519fd, 0x58ab1eda, 0x591ee3c7, + 0x5d171094, 0x5ca2ed89, 0x5e7ceaae, 0x5fc917b3, 0x566f0c08, + 0x57daf115, 0x5504f632, 0x54b10b2f, 0x50b8f87c, 0x510d0561, + 0x53d30246, 0x5266ff5b, 0x409f3530, 0x412ac82d, 0x43f4cf0a, + 0x42413217, 0x4648c144, 0x47fd3c59, 0x45233b7e, 0x4496c663, + 0x4d30ddd8, 0x4c8520c5, 0x4e5b27e2, 0x4feedaff, 0x4be729ac, + 0x4a52d4b1, 0x488cd396, 0x49392e8b, 0xdafe8e80, 0xdb4b739d, + 0xd99574ba, 0xd82089a7, 0xdc297af4, 0xdd9c87e9, 0xdf4280ce, + 0xdef77dd3, 0xd7516668, 0xd6e49b75, 0xd43a9c52, 0xd58f614f, + 0xd186921c, 0xd0336f01, 0xd2ed6826, 0xd358953b, 0xc1a15f50, + 0xc014a24d, 0xc2caa56a, 0xc37f5877, 0xc776ab24, 0xc6c35639, + 0xc41d511e, 0xc5a8ac03, 0xcc0eb7b8, 0xcdbb4aa5, 0xcf654d82, + 0xced0b09f, 0xcad943cc, 0xcb6cbed1, 0xc9b2b9f6, 0xc80744eb, + 0xec412d20, 0xedf4d03d, 0xef2ad71a, 0xee9f2a07, 0xea96d954, + 0xeb232449, 0xe9fd236e, 0xe848de73, 0xe1eec5c8, 0xe05b38d5, + 0xe2853ff2, 0xe330c2ef, 0xe73931bc, 0xe68ccca1, 0xe452cb86, + 0xe5e7369b, 0xf71efcf0, 0xf6ab01ed, 0xf47506ca, 0xf5c0fbd7, + 0xf1c90884, 0xf07cf599, 0xf2a2f2be, 0xf3170fa3, 0xfab11418, + 0xfb04e905, 0xf9daee22, 0xf86f133f, 0xfc66e06c, 0xfdd31d71, + 0xff0d1a56, 0xfeb8e74b, 0xb781c9c0, 0xb63434dd, 0xb4ea33fa, + 0xb55fcee7, 0xb1563db4, 0xb0e3c0a9, 0xb23dc78e, 0xb3883a93, + 0xba2e2128, 0xbb9bdc35, 0xb945db12, 0xb8f0260f, 0xbcf9d55c, + 0xbd4c2841, 0xbf922f66, 0xbe27d27b, 0xacde1810, 0xad6be50d, + 0xafb5e22a, 0xae001f37, 0xaa09ec64, 0xabbc1179, 0xa962165e, + 0xa8d7eb43, 0xa171f0f8, 0xa0c40de5, 0xa21a0ac2, 0xa3aff7df, + 0xa7a6048c, 0xa613f991, 0xa4cdfeb6, 0xa57803ab, 0x813e6a60, + 0x808b977d, 0x8255905a, 0x83e06d47, 0x87e99e14, 0x865c6309, + 0x8482642e, 0x85379933, 0x8c918288, 0x8d247f95, 0x8ffa78b2, + 0x8e4f85af, 0x8a4676fc, 0x8bf38be1, 0x892d8cc6, 0x889871db, + 0x9a61bbb0, 0x9bd446ad, 0x990a418a, 0x98bfbc97, 0x9cb64fc4, + 0x9d03b2d9, 0x9fddb5fe, 0x9e6848e3, 0x97ce5358, 0x967bae45, + 0x94a5a962, 0x9510547f, 0x9119a72c, 0x90ac5a31, 0x92725d16, + 0x93c7a00b}, + {0x00000000, 0x6e8c1b41, 0xdd183682, 0xb3942dc3, 0x61416b45, + 0x0fcd7004, 0xbc595dc7, 0xd2d54686, 0xc282d68a, 0xac0ecdcb, + 0x1f9ae008, 0x7116fb49, 0xa3c3bdcf, 0xcd4fa68e, 0x7edb8b4d, + 0x1057900c, 0x5e74ab55, 0x30f8b014, 0x836c9dd7, 0xede08696, + 0x3f35c010, 0x51b9db51, 0xe22df692, 0x8ca1edd3, 0x9cf67ddf, + 0xf27a669e, 0x41ee4b5d, 0x2f62501c, 0xfdb7169a, 0x933b0ddb, + 0x20af2018, 0x4e233b59, 0xbce956aa, 0xd2654deb, 0x61f16028, + 0x0f7d7b69, 0xdda83def, 0xb32426ae, 0x00b00b6d, 0x6e3c102c, + 0x7e6b8020, 0x10e79b61, 0xa373b6a2, 0xcdffade3, 0x1f2aeb65, + 0x71a6f024, 0xc232dde7, 0xacbec6a6, 0xe29dfdff, 0x8c11e6be, + 0x3f85cb7d, 0x5109d03c, 0x83dc96ba, 0xed508dfb, 0x5ec4a038, + 0x3048bb79, 0x201f2b75, 0x4e933034, 0xfd071df7, 0x938b06b6, + 0x415e4030, 0x2fd25b71, 0x9c4676b2, 0xf2ca6df3, 0xa2a3ab15, + 0xcc2fb054, 0x7fbb9d97, 0x113786d6, 0xc3e2c050, 0xad6edb11, + 0x1efaf6d2, 0x7076ed93, 0x60217d9f, 0x0ead66de, 0xbd394b1d, + 0xd3b5505c, 0x016016da, 0x6fec0d9b, 0xdc782058, 0xb2f43b19, + 0xfcd70040, 0x925b1b01, 0x21cf36c2, 0x4f432d83, 0x9d966b05, + 0xf31a7044, 0x408e5d87, 0x2e0246c6, 0x3e55d6ca, 0x50d9cd8b, + 0xe34de048, 0x8dc1fb09, 0x5f14bd8f, 0x3198a6ce, 0x820c8b0d, + 0xec80904c, 0x1e4afdbf, 0x70c6e6fe, 0xc352cb3d, 0xadded07c, + 0x7f0b96fa, 0x11878dbb, 0xa213a078, 0xcc9fbb39, 0xdcc82b35, + 0xb2443074, 0x01d01db7, 0x6f5c06f6, 0xbd894070, 0xd3055b31, + 0x609176f2, 0x0e1d6db3, 0x403e56ea, 0x2eb24dab, 0x9d266068, + 0xf3aa7b29, 0x217f3daf, 0x4ff326ee, 0xfc670b2d, 0x92eb106c, + 0x82bc8060, 0xec309b21, 0x5fa4b6e2, 0x3128ada3, 0xe3fdeb25, + 0x8d71f064, 0x3ee5dda7, 0x5069c6e6, 0x9e36506b, 0xf0ba4b2a, + 0x432e66e9, 0x2da27da8, 0xff773b2e, 0x91fb206f, 0x226f0dac, + 0x4ce316ed, 0x5cb486e1, 0x32389da0, 0x81acb063, 0xef20ab22, + 0x3df5eda4, 0x5379f6e5, 0xe0eddb26, 0x8e61c067, 0xc042fb3e, + 0xaecee07f, 0x1d5acdbc, 0x73d6d6fd, 0xa103907b, 0xcf8f8b3a, + 0x7c1ba6f9, 0x1297bdb8, 0x02c02db4, 0x6c4c36f5, 0xdfd81b36, + 0xb1540077, 0x638146f1, 0x0d0d5db0, 0xbe997073, 0xd0156b32, + 0x22df06c1, 0x4c531d80, 0xffc73043, 0x914b2b02, 0x439e6d84, + 0x2d1276c5, 0x9e865b06, 0xf00a4047, 0xe05dd04b, 0x8ed1cb0a, + 0x3d45e6c9, 0x53c9fd88, 0x811cbb0e, 0xef90a04f, 0x5c048d8c, + 0x328896cd, 0x7cabad94, 0x1227b6d5, 0xa1b39b16, 0xcf3f8057, + 0x1deac6d1, 0x7366dd90, 0xc0f2f053, 0xae7eeb12, 0xbe297b1e, + 0xd0a5605f, 0x63314d9c, 0x0dbd56dd, 0xdf68105b, 0xb1e40b1a, + 0x027026d9, 0x6cfc3d98, 0x3c95fb7e, 0x5219e03f, 0xe18dcdfc, + 0x8f01d6bd, 0x5dd4903b, 0x33588b7a, 0x80cca6b9, 0xee40bdf8, + 0xfe172df4, 0x909b36b5, 0x230f1b76, 0x4d830037, 0x9f5646b1, + 0xf1da5df0, 0x424e7033, 0x2cc26b72, 0x62e1502b, 0x0c6d4b6a, + 0xbff966a9, 0xd1757de8, 0x03a03b6e, 0x6d2c202f, 0xdeb80dec, + 0xb03416ad, 0xa06386a1, 0xceef9de0, 0x7d7bb023, 0x13f7ab62, + 0xc122ede4, 0xafaef6a5, 0x1c3adb66, 0x72b6c027, 0x807cadd4, + 0xeef0b695, 0x5d649b56, 0x33e88017, 0xe13dc691, 0x8fb1ddd0, + 0x3c25f013, 0x52a9eb52, 0x42fe7b5e, 0x2c72601f, 0x9fe64ddc, + 0xf16a569d, 0x23bf101b, 0x4d330b5a, 0xfea72699, 0x902b3dd8, + 0xde080681, 0xb0841dc0, 0x03103003, 0x6d9c2b42, 0xbf496dc4, + 0xd1c57685, 0x62515b46, 0x0cdd4007, 0x1c8ad00b, 0x7206cb4a, + 0xc192e689, 0xaf1efdc8, 0x7dcbbb4e, 0x1347a00f, 0xa0d38dcc, + 0xce5f968d}, + {0x00000000, 0xe71da697, 0x154a4b6f, 0xf257edf8, 0x2a9496de, + 0xcd893049, 0x3fdeddb1, 0xd8c37b26, 0x55292dbc, 0xb2348b2b, + 0x406366d3, 0xa77ec044, 0x7fbdbb62, 0x98a01df5, 0x6af7f00d, + 0x8dea569a, 0xaa525b78, 0x4d4ffdef, 0xbf181017, 0x5805b680, + 0x80c6cda6, 0x67db6b31, 0x958c86c9, 0x7291205e, 0xff7b76c4, + 0x1866d053, 0xea313dab, 0x0d2c9b3c, 0xd5efe01a, 0x32f2468d, + 0xc0a5ab75, 0x27b80de2, 0x8fd5b0b1, 0x68c81626, 0x9a9ffbde, + 0x7d825d49, 0xa541266f, 0x425c80f8, 0xb00b6d00, 0x5716cb97, + 0xdafc9d0d, 0x3de13b9a, 0xcfb6d662, 0x28ab70f5, 0xf0680bd3, + 0x1775ad44, 0xe52240bc, 0x023fe62b, 0x2587ebc9, 0xc29a4d5e, + 0x30cda0a6, 0xd7d00631, 0x0f137d17, 0xe80edb80, 0x1a593678, + 0xfd4490ef, 0x70aec675, 0x97b360e2, 0x65e48d1a, 0x82f92b8d, + 0x5a3a50ab, 0xbd27f63c, 0x4f701bc4, 0xa86dbd53, 0xc4da6723, + 0x23c7c1b4, 0xd1902c4c, 0x368d8adb, 0xee4ef1fd, 0x0953576a, + 0xfb04ba92, 0x1c191c05, 0x91f34a9f, 0x76eeec08, 0x84b901f0, + 0x63a4a767, 0xbb67dc41, 0x5c7a7ad6, 0xae2d972e, 0x493031b9, + 0x6e883c5b, 0x89959acc, 0x7bc27734, 0x9cdfd1a3, 0x441caa85, + 0xa3010c12, 0x5156e1ea, 0xb64b477d, 0x3ba111e7, 0xdcbcb770, + 0x2eeb5a88, 0xc9f6fc1f, 0x11358739, 0xf62821ae, 0x047fcc56, + 0xe3626ac1, 0x4b0fd792, 0xac127105, 0x5e459cfd, 0xb9583a6a, + 0x619b414c, 0x8686e7db, 0x74d10a23, 0x93ccacb4, 0x1e26fa2e, + 0xf93b5cb9, 0x0b6cb141, 0xec7117d6, 0x34b26cf0, 0xd3afca67, + 0x21f8279f, 0xc6e58108, 0xe15d8cea, 0x06402a7d, 0xf417c785, + 0x130a6112, 0xcbc91a34, 0x2cd4bca3, 0xde83515b, 0x399ef7cc, + 0xb474a156, 0x536907c1, 0xa13eea39, 0x46234cae, 0x9ee03788, + 0x79fd911f, 0x8baa7ce7, 0x6cb7da70, 0x52c5c807, 0xb5d86e90, + 0x478f8368, 0xa09225ff, 0x78515ed9, 0x9f4cf84e, 0x6d1b15b6, + 0x8a06b321, 0x07ece5bb, 0xe0f1432c, 0x12a6aed4, 0xf5bb0843, + 0x2d787365, 0xca65d5f2, 0x3832380a, 0xdf2f9e9d, 0xf897937f, + 0x1f8a35e8, 0xedddd810, 0x0ac07e87, 0xd20305a1, 0x351ea336, + 0xc7494ece, 0x2054e859, 0xadbebec3, 0x4aa31854, 0xb8f4f5ac, + 0x5fe9533b, 0x872a281d, 0x60378e8a, 0x92606372, 0x757dc5e5, + 0xdd1078b6, 0x3a0dde21, 0xc85a33d9, 0x2f47954e, 0xf784ee68, + 0x109948ff, 0xe2cea507, 0x05d30390, 0x8839550a, 0x6f24f39d, + 0x9d731e65, 0x7a6eb8f2, 0xa2adc3d4, 0x45b06543, 0xb7e788bb, + 0x50fa2e2c, 0x774223ce, 0x905f8559, 0x620868a1, 0x8515ce36, + 0x5dd6b510, 0xbacb1387, 0x489cfe7f, 0xaf8158e8, 0x226b0e72, + 0xc576a8e5, 0x3721451d, 0xd03ce38a, 0x08ff98ac, 0xefe23e3b, + 0x1db5d3c3, 0xfaa87554, 0x961faf24, 0x710209b3, 0x8355e44b, + 0x644842dc, 0xbc8b39fa, 0x5b969f6d, 0xa9c17295, 0x4edcd402, + 0xc3368298, 0x242b240f, 0xd67cc9f7, 0x31616f60, 0xe9a21446, + 0x0ebfb2d1, 0xfce85f29, 0x1bf5f9be, 0x3c4df45c, 0xdb5052cb, + 0x2907bf33, 0xce1a19a4, 0x16d96282, 0xf1c4c415, 0x039329ed, + 0xe48e8f7a, 0x6964d9e0, 0x8e797f77, 0x7c2e928f, 0x9b333418, + 0x43f04f3e, 0xa4ede9a9, 0x56ba0451, 0xb1a7a2c6, 0x19ca1f95, + 0xfed7b902, 0x0c8054fa, 0xeb9df26d, 0x335e894b, 0xd4432fdc, + 0x2614c224, 0xc10964b3, 0x4ce33229, 0xabfe94be, 0x59a97946, + 0xbeb4dfd1, 0x6677a4f7, 0x816a0260, 0x733def98, 0x9420490f, + 0xb39844ed, 0x5485e27a, 0xa6d20f82, 0x41cfa915, 0x990cd233, + 0x7e1174a4, 0x8c46995c, 0x6b5b3fcb, 0xe6b16951, 0x01accfc6, + 0xf3fb223e, 0x14e684a9, 0xcc25ff8f, 0x2b385918, 0xd96fb4e0, + 0x3e721277}, + {0x00000000, 0xa58b900e, 0x9066265d, 0x35edb653, 0xfbbd4afb, + 0x5e36daf5, 0x6bdb6ca6, 0xce50fca8, 0x2c0b93b7, 0x898003b9, + 0xbc6db5ea, 0x19e625e4, 0xd7b6d94c, 0x723d4942, 0x47d0ff11, + 0xe25b6f1f, 0x5817276e, 0xfd9cb760, 0xc8710133, 0x6dfa913d, + 0xa3aa6d95, 0x0621fd9b, 0x33cc4bc8, 0x9647dbc6, 0x741cb4d9, + 0xd19724d7, 0xe47a9284, 0x41f1028a, 0x8fa1fe22, 0x2a2a6e2c, + 0x1fc7d87f, 0xba4c4871, 0xb02e4edc, 0x15a5ded2, 0x20486881, + 0x85c3f88f, 0x4b930427, 0xee189429, 0xdbf5227a, 0x7e7eb274, + 0x9c25dd6b, 0x39ae4d65, 0x0c43fb36, 0xa9c86b38, 0x67989790, + 0xc213079e, 0xf7feb1cd, 0x527521c3, 0xe83969b2, 0x4db2f9bc, + 0x785f4fef, 0xddd4dfe1, 0x13842349, 0xb60fb347, 0x83e20514, + 0x2669951a, 0xc432fa05, 0x61b96a0b, 0x5454dc58, 0xf1df4c56, + 0x3f8fb0fe, 0x9a0420f0, 0xafe996a3, 0x0a6206ad, 0xbb2d9bf9, + 0x1ea60bf7, 0x2b4bbda4, 0x8ec02daa, 0x4090d102, 0xe51b410c, + 0xd0f6f75f, 0x757d6751, 0x9726084e, 0x32ad9840, 0x07402e13, + 0xa2cbbe1d, 0x6c9b42b5, 0xc910d2bb, 0xfcfd64e8, 0x5976f4e6, + 0xe33abc97, 0x46b12c99, 0x735c9aca, 0xd6d70ac4, 0x1887f66c, + 0xbd0c6662, 0x88e1d031, 0x2d6a403f, 0xcf312f20, 0x6ababf2e, + 0x5f57097d, 0xfadc9973, 0x348c65db, 0x9107f5d5, 0xa4ea4386, + 0x0161d388, 0x0b03d525, 0xae88452b, 0x9b65f378, 0x3eee6376, + 0xf0be9fde, 0x55350fd0, 0x60d8b983, 0xc553298d, 0x27084692, + 0x8283d69c, 0xb76e60cf, 0x12e5f0c1, 0xdcb50c69, 0x793e9c67, + 0x4cd32a34, 0xe958ba3a, 0x5314f24b, 0xf69f6245, 0xc372d416, + 0x66f94418, 0xa8a9b8b0, 0x0d2228be, 0x38cf9eed, 0x9d440ee3, + 0x7f1f61fc, 0xda94f1f2, 0xef7947a1, 0x4af2d7af, 0x84a22b07, + 0x2129bb09, 0x14c40d5a, 0xb14f9d54, 0xad2a31b3, 0x08a1a1bd, + 0x3d4c17ee, 0x98c787e0, 0x56977b48, 0xf31ceb46, 0xc6f15d15, + 0x637acd1b, 0x8121a204, 0x24aa320a, 0x11478459, 0xb4cc1457, + 0x7a9ce8ff, 0xdf1778f1, 0xeafacea2, 0x4f715eac, 0xf53d16dd, + 0x50b686d3, 0x655b3080, 0xc0d0a08e, 0x0e805c26, 0xab0bcc28, + 0x9ee67a7b, 0x3b6dea75, 0xd936856a, 0x7cbd1564, 0x4950a337, + 0xecdb3339, 0x228bcf91, 0x87005f9f, 0xb2ede9cc, 0x176679c2, + 0x1d047f6f, 0xb88fef61, 0x8d625932, 0x28e9c93c, 0xe6b93594, + 0x4332a59a, 0x76df13c9, 0xd35483c7, 0x310fecd8, 0x94847cd6, + 0xa169ca85, 0x04e25a8b, 0xcab2a623, 0x6f39362d, 0x5ad4807e, + 0xff5f1070, 0x45135801, 0xe098c80f, 0xd5757e5c, 0x70feee52, + 0xbeae12fa, 0x1b2582f4, 0x2ec834a7, 0x8b43a4a9, 0x6918cbb6, + 0xcc935bb8, 0xf97eedeb, 0x5cf57de5, 0x92a5814d, 0x372e1143, + 0x02c3a710, 0xa748371e, 0x1607aa4a, 0xb38c3a44, 0x86618c17, + 0x23ea1c19, 0xedbae0b1, 0x483170bf, 0x7ddcc6ec, 0xd85756e2, + 0x3a0c39fd, 0x9f87a9f3, 0xaa6a1fa0, 0x0fe18fae, 0xc1b17306, + 0x643ae308, 0x51d7555b, 0xf45cc555, 0x4e108d24, 0xeb9b1d2a, + 0xde76ab79, 0x7bfd3b77, 0xb5adc7df, 0x102657d1, 0x25cbe182, + 0x8040718c, 0x621b1e93, 0xc7908e9d, 0xf27d38ce, 0x57f6a8c0, + 0x99a65468, 0x3c2dc466, 0x09c07235, 0xac4be23b, 0xa629e496, + 0x03a27498, 0x364fc2cb, 0x93c452c5, 0x5d94ae6d, 0xf81f3e63, + 0xcdf28830, 0x6879183e, 0x8a227721, 0x2fa9e72f, 0x1a44517c, + 0xbfcfc172, 0x719f3dda, 0xd414add4, 0xe1f91b87, 0x44728b89, + 0xfe3ec3f8, 0x5bb553f6, 0x6e58e5a5, 0xcbd375ab, 0x05838903, + 0xa008190d, 0x95e5af5e, 0x306e3f50, 0xd235504f, 0x77bec041, + 0x42537612, 0xe7d8e61c, 0x29881ab4, 0x8c038aba, 0xb9ee3ce9, + 0x1c65ace7}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0x0e908ba500000000, 0x5d26669000000000, + 0x53b6ed3500000000, 0xfb4abdfb00000000, 0xf5da365e00000000, + 0xa66cdb6b00000000, 0xa8fc50ce00000000, 0xb7930b2c00000000, + 0xb903808900000000, 0xeab56dbc00000000, 0xe425e61900000000, + 0x4cd9b6d700000000, 0x42493d7200000000, 0x11ffd04700000000, + 0x1f6f5be200000000, 0x6e27175800000000, 0x60b79cfd00000000, + 0x330171c800000000, 0x3d91fa6d00000000, 0x956daaa300000000, + 0x9bfd210600000000, 0xc84bcc3300000000, 0xc6db479600000000, + 0xd9b41c7400000000, 0xd72497d100000000, 0x84927ae400000000, + 0x8a02f14100000000, 0x22fea18f00000000, 0x2c6e2a2a00000000, + 0x7fd8c71f00000000, 0x71484cba00000000, 0xdc4e2eb000000000, + 0xd2dea51500000000, 0x8168482000000000, 0x8ff8c38500000000, + 0x2704934b00000000, 0x299418ee00000000, 0x7a22f5db00000000, + 0x74b27e7e00000000, 0x6bdd259c00000000, 0x654dae3900000000, + 0x36fb430c00000000, 0x386bc8a900000000, 0x9097986700000000, + 0x9e0713c200000000, 0xcdb1fef700000000, 0xc321755200000000, + 0xb26939e800000000, 0xbcf9b24d00000000, 0xef4f5f7800000000, + 0xe1dfd4dd00000000, 0x4923841300000000, 0x47b30fb600000000, + 0x1405e28300000000, 0x1a95692600000000, 0x05fa32c400000000, + 0x0b6ab96100000000, 0x58dc545400000000, 0x564cdff100000000, + 0xfeb08f3f00000000, 0xf020049a00000000, 0xa396e9af00000000, + 0xad06620a00000000, 0xf99b2dbb00000000, 0xf70ba61e00000000, + 0xa4bd4b2b00000000, 0xaa2dc08e00000000, 0x02d1904000000000, + 0x0c411be500000000, 0x5ff7f6d000000000, 0x51677d7500000000, + 0x4e08269700000000, 0x4098ad3200000000, 0x132e400700000000, + 0x1dbecba200000000, 0xb5429b6c00000000, 0xbbd210c900000000, + 0xe864fdfc00000000, 0xe6f4765900000000, 0x97bc3ae300000000, + 0x992cb14600000000, 0xca9a5c7300000000, 0xc40ad7d600000000, + 0x6cf6871800000000, 0x62660cbd00000000, 0x31d0e18800000000, + 0x3f406a2d00000000, 0x202f31cf00000000, 0x2ebfba6a00000000, + 0x7d09575f00000000, 0x7399dcfa00000000, 0xdb658c3400000000, + 0xd5f5079100000000, 0x8643eaa400000000, 0x88d3610100000000, + 0x25d5030b00000000, 0x2b4588ae00000000, 0x78f3659b00000000, + 0x7663ee3e00000000, 0xde9fbef000000000, 0xd00f355500000000, + 0x83b9d86000000000, 0x8d2953c500000000, 0x9246082700000000, + 0x9cd6838200000000, 0xcf606eb700000000, 0xc1f0e51200000000, + 0x690cb5dc00000000, 0x679c3e7900000000, 0x342ad34c00000000, + 0x3aba58e900000000, 0x4bf2145300000000, 0x45629ff600000000, + 0x16d472c300000000, 0x1844f96600000000, 0xb0b8a9a800000000, + 0xbe28220d00000000, 0xed9ecf3800000000, 0xe30e449d00000000, + 0xfc611f7f00000000, 0xf2f194da00000000, 0xa14779ef00000000, + 0xafd7f24a00000000, 0x072ba28400000000, 0x09bb292100000000, + 0x5a0dc41400000000, 0x549d4fb100000000, 0xb3312aad00000000, + 0xbda1a10800000000, 0xee174c3d00000000, 0xe087c79800000000, + 0x487b975600000000, 0x46eb1cf300000000, 0x155df1c600000000, + 0x1bcd7a6300000000, 0x04a2218100000000, 0x0a32aa2400000000, + 0x5984471100000000, 0x5714ccb400000000, 0xffe89c7a00000000, + 0xf17817df00000000, 0xa2cefaea00000000, 0xac5e714f00000000, + 0xdd163df500000000, 0xd386b65000000000, 0x80305b6500000000, + 0x8ea0d0c000000000, 0x265c800e00000000, 0x28cc0bab00000000, + 0x7b7ae69e00000000, 0x75ea6d3b00000000, 0x6a8536d900000000, + 0x6415bd7c00000000, 0x37a3504900000000, 0x3933dbec00000000, + 0x91cf8b2200000000, 0x9f5f008700000000, 0xcce9edb200000000, + 0xc279661700000000, 0x6f7f041d00000000, 0x61ef8fb800000000, + 0x3259628d00000000, 0x3cc9e92800000000, 0x9435b9e600000000, + 0x9aa5324300000000, 0xc913df7600000000, 0xc78354d300000000, + 0xd8ec0f3100000000, 0xd67c849400000000, 0x85ca69a100000000, + 0x8b5ae20400000000, 0x23a6b2ca00000000, 0x2d36396f00000000, + 0x7e80d45a00000000, 0x70105fff00000000, 0x0158134500000000, + 0x0fc898e000000000, 0x5c7e75d500000000, 0x52eefe7000000000, + 0xfa12aebe00000000, 0xf482251b00000000, 0xa734c82e00000000, + 0xa9a4438b00000000, 0xb6cb186900000000, 0xb85b93cc00000000, + 0xebed7ef900000000, 0xe57df55c00000000, 0x4d81a59200000000, + 0x43112e3700000000, 0x10a7c30200000000, 0x1e3748a700000000, + 0x4aaa071600000000, 0x443a8cb300000000, 0x178c618600000000, + 0x191cea2300000000, 0xb1e0baed00000000, 0xbf70314800000000, + 0xecc6dc7d00000000, 0xe25657d800000000, 0xfd390c3a00000000, + 0xf3a9879f00000000, 0xa01f6aaa00000000, 0xae8fe10f00000000, + 0x0673b1c100000000, 0x08e33a6400000000, 0x5b55d75100000000, + 0x55c55cf400000000, 0x248d104e00000000, 0x2a1d9beb00000000, + 0x79ab76de00000000, 0x773bfd7b00000000, 0xdfc7adb500000000, + 0xd157261000000000, 0x82e1cb2500000000, 0x8c71408000000000, + 0x931e1b6200000000, 0x9d8e90c700000000, 0xce387df200000000, + 0xc0a8f65700000000, 0x6854a69900000000, 0x66c42d3c00000000, + 0x3572c00900000000, 0x3be24bac00000000, 0x96e429a600000000, + 0x9874a20300000000, 0xcbc24f3600000000, 0xc552c49300000000, + 0x6dae945d00000000, 0x633e1ff800000000, 0x3088f2cd00000000, + 0x3e18796800000000, 0x2177228a00000000, 0x2fe7a92f00000000, + 0x7c51441a00000000, 0x72c1cfbf00000000, 0xda3d9f7100000000, + 0xd4ad14d400000000, 0x871bf9e100000000, 0x898b724400000000, + 0xf8c33efe00000000, 0xf653b55b00000000, 0xa5e5586e00000000, + 0xab75d3cb00000000, 0x0389830500000000, 0x0d1908a000000000, + 0x5eafe59500000000, 0x503f6e3000000000, 0x4f5035d200000000, + 0x41c0be7700000000, 0x1276534200000000, 0x1ce6d8e700000000, + 0xb41a882900000000, 0xba8a038c00000000, 0xe93ceeb900000000, + 0xe7ac651c00000000}, + {0x0000000000000000, 0x97a61de700000000, 0x6f4b4a1500000000, + 0xf8ed57f200000000, 0xde96942a00000000, 0x493089cd00000000, + 0xb1ddde3f00000000, 0x267bc3d800000000, 0xbc2d295500000000, + 0x2b8b34b200000000, 0xd366634000000000, 0x44c07ea700000000, + 0x62bbbd7f00000000, 0xf51da09800000000, 0x0df0f76a00000000, + 0x9a56ea8d00000000, 0x785b52aa00000000, 0xeffd4f4d00000000, + 0x171018bf00000000, 0x80b6055800000000, 0xa6cdc68000000000, + 0x316bdb6700000000, 0xc9868c9500000000, 0x5e20917200000000, + 0xc4767bff00000000, 0x53d0661800000000, 0xab3d31ea00000000, + 0x3c9b2c0d00000000, 0x1ae0efd500000000, 0x8d46f23200000000, + 0x75aba5c000000000, 0xe20db82700000000, 0xb1b0d58f00000000, + 0x2616c86800000000, 0xdefb9f9a00000000, 0x495d827d00000000, + 0x6f2641a500000000, 0xf8805c4200000000, 0x006d0bb000000000, + 0x97cb165700000000, 0x0d9dfcda00000000, 0x9a3be13d00000000, + 0x62d6b6cf00000000, 0xf570ab2800000000, 0xd30b68f000000000, + 0x44ad751700000000, 0xbc4022e500000000, 0x2be63f0200000000, + 0xc9eb872500000000, 0x5e4d9ac200000000, 0xa6a0cd3000000000, + 0x3106d0d700000000, 0x177d130f00000000, 0x80db0ee800000000, + 0x7836591a00000000, 0xef9044fd00000000, 0x75c6ae7000000000, + 0xe260b39700000000, 0x1a8de46500000000, 0x8d2bf98200000000, + 0xab503a5a00000000, 0x3cf627bd00000000, 0xc41b704f00000000, + 0x53bd6da800000000, 0x2367dac400000000, 0xb4c1c72300000000, + 0x4c2c90d100000000, 0xdb8a8d3600000000, 0xfdf14eee00000000, + 0x6a57530900000000, 0x92ba04fb00000000, 0x051c191c00000000, + 0x9f4af39100000000, 0x08ecee7600000000, 0xf001b98400000000, + 0x67a7a46300000000, 0x41dc67bb00000000, 0xd67a7a5c00000000, + 0x2e972dae00000000, 0xb931304900000000, 0x5b3c886e00000000, + 0xcc9a958900000000, 0x3477c27b00000000, 0xa3d1df9c00000000, + 0x85aa1c4400000000, 0x120c01a300000000, 0xeae1565100000000, + 0x7d474bb600000000, 0xe711a13b00000000, 0x70b7bcdc00000000, + 0x885aeb2e00000000, 0x1ffcf6c900000000, 0x3987351100000000, + 0xae2128f600000000, 0x56cc7f0400000000, 0xc16a62e300000000, + 0x92d70f4b00000000, 0x057112ac00000000, 0xfd9c455e00000000, + 0x6a3a58b900000000, 0x4c419b6100000000, 0xdbe7868600000000, + 0x230ad17400000000, 0xb4accc9300000000, 0x2efa261e00000000, + 0xb95c3bf900000000, 0x41b16c0b00000000, 0xd61771ec00000000, + 0xf06cb23400000000, 0x67caafd300000000, 0x9f27f82100000000, + 0x0881e5c600000000, 0xea8c5de100000000, 0x7d2a400600000000, + 0x85c717f400000000, 0x12610a1300000000, 0x341ac9cb00000000, + 0xa3bcd42c00000000, 0x5b5183de00000000, 0xccf79e3900000000, + 0x56a174b400000000, 0xc107695300000000, 0x39ea3ea100000000, + 0xae4c234600000000, 0x8837e09e00000000, 0x1f91fd7900000000, + 0xe77caa8b00000000, 0x70dab76c00000000, 0x07c8c55200000000, + 0x906ed8b500000000, 0x68838f4700000000, 0xff2592a000000000, + 0xd95e517800000000, 0x4ef84c9f00000000, 0xb6151b6d00000000, + 0x21b3068a00000000, 0xbbe5ec0700000000, 0x2c43f1e000000000, + 0xd4aea61200000000, 0x4308bbf500000000, 0x6573782d00000000, + 0xf2d565ca00000000, 0x0a38323800000000, 0x9d9e2fdf00000000, + 0x7f9397f800000000, 0xe8358a1f00000000, 0x10d8dded00000000, + 0x877ec00a00000000, 0xa10503d200000000, 0x36a31e3500000000, + 0xce4e49c700000000, 0x59e8542000000000, 0xc3bebead00000000, + 0x5418a34a00000000, 0xacf5f4b800000000, 0x3b53e95f00000000, + 0x1d282a8700000000, 0x8a8e376000000000, 0x7263609200000000, + 0xe5c57d7500000000, 0xb67810dd00000000, 0x21de0d3a00000000, + 0xd9335ac800000000, 0x4e95472f00000000, 0x68ee84f700000000, + 0xff48991000000000, 0x07a5cee200000000, 0x9003d30500000000, + 0x0a55398800000000, 0x9df3246f00000000, 0x651e739d00000000, + 0xf2b86e7a00000000, 0xd4c3ada200000000, 0x4365b04500000000, + 0xbb88e7b700000000, 0x2c2efa5000000000, 0xce23427700000000, + 0x59855f9000000000, 0xa168086200000000, 0x36ce158500000000, + 0x10b5d65d00000000, 0x8713cbba00000000, 0x7ffe9c4800000000, + 0xe85881af00000000, 0x720e6b2200000000, 0xe5a876c500000000, + 0x1d45213700000000, 0x8ae33cd000000000, 0xac98ff0800000000, + 0x3b3ee2ef00000000, 0xc3d3b51d00000000, 0x5475a8fa00000000, + 0x24af1f9600000000, 0xb309027100000000, 0x4be4558300000000, + 0xdc42486400000000, 0xfa398bbc00000000, 0x6d9f965b00000000, + 0x9572c1a900000000, 0x02d4dc4e00000000, 0x988236c300000000, + 0x0f242b2400000000, 0xf7c97cd600000000, 0x606f613100000000, + 0x4614a2e900000000, 0xd1b2bf0e00000000, 0x295fe8fc00000000, + 0xbef9f51b00000000, 0x5cf44d3c00000000, 0xcb5250db00000000, + 0x33bf072900000000, 0xa4191ace00000000, 0x8262d91600000000, + 0x15c4c4f100000000, 0xed29930300000000, 0x7a8f8ee400000000, + 0xe0d9646900000000, 0x777f798e00000000, 0x8f922e7c00000000, + 0x1834339b00000000, 0x3e4ff04300000000, 0xa9e9eda400000000, + 0x5104ba5600000000, 0xc6a2a7b100000000, 0x951fca1900000000, + 0x02b9d7fe00000000, 0xfa54800c00000000, 0x6df29deb00000000, + 0x4b895e3300000000, 0xdc2f43d400000000, 0x24c2142600000000, + 0xb36409c100000000, 0x2932e34c00000000, 0xbe94feab00000000, + 0x4679a95900000000, 0xd1dfb4be00000000, 0xf7a4776600000000, + 0x60026a8100000000, 0x98ef3d7300000000, 0x0f49209400000000, + 0xed4498b300000000, 0x7ae2855400000000, 0x820fd2a600000000, + 0x15a9cf4100000000, 0x33d20c9900000000, 0xa474117e00000000, + 0x5c99468c00000000, 0xcb3f5b6b00000000, 0x5169b1e600000000, + 0xc6cfac0100000000, 0x3e22fbf300000000, 0xa984e61400000000, + 0x8fff25cc00000000, 0x1859382b00000000, 0xe0b46fd900000000, + 0x7712723e00000000}, + {0x0000000000000000, 0x411b8c6e00000000, 0x823618dd00000000, + 0xc32d94b300000000, 0x456b416100000000, 0x0470cd0f00000000, + 0xc75d59bc00000000, 0x8646d5d200000000, 0x8ad682c200000000, + 0xcbcd0eac00000000, 0x08e09a1f00000000, 0x49fb167100000000, + 0xcfbdc3a300000000, 0x8ea64fcd00000000, 0x4d8bdb7e00000000, + 0x0c90571000000000, 0x55ab745e00000000, 0x14b0f83000000000, + 0xd79d6c8300000000, 0x9686e0ed00000000, 0x10c0353f00000000, + 0x51dbb95100000000, 0x92f62de200000000, 0xd3eda18c00000000, + 0xdf7df69c00000000, 0x9e667af200000000, 0x5d4bee4100000000, + 0x1c50622f00000000, 0x9a16b7fd00000000, 0xdb0d3b9300000000, + 0x1820af2000000000, 0x593b234e00000000, 0xaa56e9bc00000000, + 0xeb4d65d200000000, 0x2860f16100000000, 0x697b7d0f00000000, + 0xef3da8dd00000000, 0xae2624b300000000, 0x6d0bb00000000000, + 0x2c103c6e00000000, 0x20806b7e00000000, 0x619be71000000000, + 0xa2b673a300000000, 0xe3adffcd00000000, 0x65eb2a1f00000000, + 0x24f0a67100000000, 0xe7dd32c200000000, 0xa6c6beac00000000, + 0xfffd9de200000000, 0xbee6118c00000000, 0x7dcb853f00000000, + 0x3cd0095100000000, 0xba96dc8300000000, 0xfb8d50ed00000000, + 0x38a0c45e00000000, 0x79bb483000000000, 0x752b1f2000000000, + 0x3430934e00000000, 0xf71d07fd00000000, 0xb6068b9300000000, + 0x30405e4100000000, 0x715bd22f00000000, 0xb276469c00000000, + 0xf36dcaf200000000, 0x15aba3a200000000, 0x54b02fcc00000000, + 0x979dbb7f00000000, 0xd686371100000000, 0x50c0e2c300000000, + 0x11db6ead00000000, 0xd2f6fa1e00000000, 0x93ed767000000000, + 0x9f7d216000000000, 0xde66ad0e00000000, 0x1d4b39bd00000000, + 0x5c50b5d300000000, 0xda16600100000000, 0x9b0dec6f00000000, + 0x582078dc00000000, 0x193bf4b200000000, 0x4000d7fc00000000, + 0x011b5b9200000000, 0xc236cf2100000000, 0x832d434f00000000, + 0x056b969d00000000, 0x44701af300000000, 0x875d8e4000000000, + 0xc646022e00000000, 0xcad6553e00000000, 0x8bcdd95000000000, + 0x48e04de300000000, 0x09fbc18d00000000, 0x8fbd145f00000000, + 0xcea6983100000000, 0x0d8b0c8200000000, 0x4c9080ec00000000, + 0xbffd4a1e00000000, 0xfee6c67000000000, 0x3dcb52c300000000, + 0x7cd0dead00000000, 0xfa960b7f00000000, 0xbb8d871100000000, + 0x78a013a200000000, 0x39bb9fcc00000000, 0x352bc8dc00000000, + 0x743044b200000000, 0xb71dd00100000000, 0xf6065c6f00000000, + 0x704089bd00000000, 0x315b05d300000000, 0xf276916000000000, + 0xb36d1d0e00000000, 0xea563e4000000000, 0xab4db22e00000000, + 0x6860269d00000000, 0x297baaf300000000, 0xaf3d7f2100000000, + 0xee26f34f00000000, 0x2d0b67fc00000000, 0x6c10eb9200000000, + 0x6080bc8200000000, 0x219b30ec00000000, 0xe2b6a45f00000000, + 0xa3ad283100000000, 0x25ebfde300000000, 0x64f0718d00000000, + 0xa7dde53e00000000, 0xe6c6695000000000, 0x6b50369e00000000, + 0x2a4bbaf000000000, 0xe9662e4300000000, 0xa87da22d00000000, + 0x2e3b77ff00000000, 0x6f20fb9100000000, 0xac0d6f2200000000, + 0xed16e34c00000000, 0xe186b45c00000000, 0xa09d383200000000, + 0x63b0ac8100000000, 0x22ab20ef00000000, 0xa4edf53d00000000, + 0xe5f6795300000000, 0x26dbede000000000, 0x67c0618e00000000, + 0x3efb42c000000000, 0x7fe0ceae00000000, 0xbccd5a1d00000000, + 0xfdd6d67300000000, 0x7b9003a100000000, 0x3a8b8fcf00000000, + 0xf9a61b7c00000000, 0xb8bd971200000000, 0xb42dc00200000000, + 0xf5364c6c00000000, 0x361bd8df00000000, 0x770054b100000000, + 0xf146816300000000, 0xb05d0d0d00000000, 0x737099be00000000, + 0x326b15d000000000, 0xc106df2200000000, 0x801d534c00000000, + 0x4330c7ff00000000, 0x022b4b9100000000, 0x846d9e4300000000, + 0xc576122d00000000, 0x065b869e00000000, 0x47400af000000000, + 0x4bd05de000000000, 0x0acbd18e00000000, 0xc9e6453d00000000, + 0x88fdc95300000000, 0x0ebb1c8100000000, 0x4fa090ef00000000, + 0x8c8d045c00000000, 0xcd96883200000000, 0x94adab7c00000000, + 0xd5b6271200000000, 0x169bb3a100000000, 0x57803fcf00000000, + 0xd1c6ea1d00000000, 0x90dd667300000000, 0x53f0f2c000000000, + 0x12eb7eae00000000, 0x1e7b29be00000000, 0x5f60a5d000000000, + 0x9c4d316300000000, 0xdd56bd0d00000000, 0x5b1068df00000000, + 0x1a0be4b100000000, 0xd926700200000000, 0x983dfc6c00000000, + 0x7efb953c00000000, 0x3fe0195200000000, 0xfccd8de100000000, + 0xbdd6018f00000000, 0x3b90d45d00000000, 0x7a8b583300000000, + 0xb9a6cc8000000000, 0xf8bd40ee00000000, 0xf42d17fe00000000, + 0xb5369b9000000000, 0x761b0f2300000000, 0x3700834d00000000, + 0xb146569f00000000, 0xf05ddaf100000000, 0x33704e4200000000, + 0x726bc22c00000000, 0x2b50e16200000000, 0x6a4b6d0c00000000, + 0xa966f9bf00000000, 0xe87d75d100000000, 0x6e3ba00300000000, + 0x2f202c6d00000000, 0xec0db8de00000000, 0xad1634b000000000, + 0xa18663a000000000, 0xe09defce00000000, 0x23b07b7d00000000, + 0x62abf71300000000, 0xe4ed22c100000000, 0xa5f6aeaf00000000, + 0x66db3a1c00000000, 0x27c0b67200000000, 0xd4ad7c8000000000, + 0x95b6f0ee00000000, 0x569b645d00000000, 0x1780e83300000000, + 0x91c63de100000000, 0xd0ddb18f00000000, 0x13f0253c00000000, + 0x52eba95200000000, 0x5e7bfe4200000000, 0x1f60722c00000000, + 0xdc4de69f00000000, 0x9d566af100000000, 0x1b10bf2300000000, + 0x5a0b334d00000000, 0x9926a7fe00000000, 0xd83d2b9000000000, + 0x810608de00000000, 0xc01d84b000000000, 0x0330100300000000, + 0x422b9c6d00000000, 0xc46d49bf00000000, 0x8576c5d100000000, + 0x465b516200000000, 0x0740dd0c00000000, 0x0bd08a1c00000000, + 0x4acb067200000000, 0x89e692c100000000, 0xc8fd1eaf00000000, + 0x4ebbcb7d00000000, 0x0fa0471300000000, 0xcc8dd3a000000000, + 0x8d965fce00000000}, + {0x0000000000000000, 0x1dfdb50100000000, 0x3afa6b0300000000, + 0x2707de0200000000, 0x74f4d70600000000, 0x6909620700000000, + 0x4e0ebc0500000000, 0x53f3090400000000, 0xe8e8af0d00000000, + 0xf5151a0c00000000, 0xd212c40e00000000, 0xcfef710f00000000, + 0x9c1c780b00000000, 0x81e1cd0a00000000, 0xa6e6130800000000, + 0xbb1ba60900000000, 0xd0d15f1b00000000, 0xcd2cea1a00000000, + 0xea2b341800000000, 0xf7d6811900000000, 0xa425881d00000000, + 0xb9d83d1c00000000, 0x9edfe31e00000000, 0x8322561f00000000, + 0x3839f01600000000, 0x25c4451700000000, 0x02c39b1500000000, + 0x1f3e2e1400000000, 0x4ccd271000000000, 0x5130921100000000, + 0x76374c1300000000, 0x6bcaf91200000000, 0xa0a3bf3600000000, + 0xbd5e0a3700000000, 0x9a59d43500000000, 0x87a4613400000000, + 0xd457683000000000, 0xc9aadd3100000000, 0xeead033300000000, + 0xf350b63200000000, 0x484b103b00000000, 0x55b6a53a00000000, + 0x72b17b3800000000, 0x6f4cce3900000000, 0x3cbfc73d00000000, + 0x2142723c00000000, 0x0645ac3e00000000, 0x1bb8193f00000000, + 0x7072e02d00000000, 0x6d8f552c00000000, 0x4a888b2e00000000, + 0x57753e2f00000000, 0x0486372b00000000, 0x197b822a00000000, + 0x3e7c5c2800000000, 0x2381e92900000000, 0x989a4f2000000000, + 0x8567fa2100000000, 0xa260242300000000, 0xbf9d912200000000, + 0xec6e982600000000, 0xf1932d2700000000, 0xd694f32500000000, + 0xcb69462400000000, 0x40477f6d00000000, 0x5dbaca6c00000000, + 0x7abd146e00000000, 0x6740a16f00000000, 0x34b3a86b00000000, + 0x294e1d6a00000000, 0x0e49c36800000000, 0x13b4766900000000, + 0xa8afd06000000000, 0xb552656100000000, 0x9255bb6300000000, + 0x8fa80e6200000000, 0xdc5b076600000000, 0xc1a6b26700000000, + 0xe6a16c6500000000, 0xfb5cd96400000000, 0x9096207600000000, + 0x8d6b957700000000, 0xaa6c4b7500000000, 0xb791fe7400000000, + 0xe462f77000000000, 0xf99f427100000000, 0xde989c7300000000, + 0xc365297200000000, 0x787e8f7b00000000, 0x65833a7a00000000, + 0x4284e47800000000, 0x5f79517900000000, 0x0c8a587d00000000, + 0x1177ed7c00000000, 0x3670337e00000000, 0x2b8d867f00000000, + 0xe0e4c05b00000000, 0xfd19755a00000000, 0xda1eab5800000000, + 0xc7e31e5900000000, 0x9410175d00000000, 0x89eda25c00000000, + 0xaeea7c5e00000000, 0xb317c95f00000000, 0x080c6f5600000000, + 0x15f1da5700000000, 0x32f6045500000000, 0x2f0bb15400000000, + 0x7cf8b85000000000, 0x61050d5100000000, 0x4602d35300000000, + 0x5bff665200000000, 0x30359f4000000000, 0x2dc82a4100000000, + 0x0acff44300000000, 0x1732414200000000, 0x44c1484600000000, + 0x593cfd4700000000, 0x7e3b234500000000, 0x63c6964400000000, + 0xd8dd304d00000000, 0xc520854c00000000, 0xe2275b4e00000000, + 0xffdaee4f00000000, 0xac29e74b00000000, 0xb1d4524a00000000, + 0x96d38c4800000000, 0x8b2e394900000000, 0x808efeda00000000, + 0x9d734bdb00000000, 0xba7495d900000000, 0xa78920d800000000, + 0xf47a29dc00000000, 0xe9879cdd00000000, 0xce8042df00000000, + 0xd37df7de00000000, 0x686651d700000000, 0x759be4d600000000, + 0x529c3ad400000000, 0x4f618fd500000000, 0x1c9286d100000000, + 0x016f33d000000000, 0x2668edd200000000, 0x3b9558d300000000, + 0x505fa1c100000000, 0x4da214c000000000, 0x6aa5cac200000000, + 0x77587fc300000000, 0x24ab76c700000000, 0x3956c3c600000000, + 0x1e511dc400000000, 0x03aca8c500000000, 0xb8b70ecc00000000, + 0xa54abbcd00000000, 0x824d65cf00000000, 0x9fb0d0ce00000000, + 0xcc43d9ca00000000, 0xd1be6ccb00000000, 0xf6b9b2c900000000, + 0xeb4407c800000000, 0x202d41ec00000000, 0x3dd0f4ed00000000, + 0x1ad72aef00000000, 0x072a9fee00000000, 0x54d996ea00000000, + 0x492423eb00000000, 0x6e23fde900000000, 0x73de48e800000000, + 0xc8c5eee100000000, 0xd5385be000000000, 0xf23f85e200000000, + 0xefc230e300000000, 0xbc3139e700000000, 0xa1cc8ce600000000, + 0x86cb52e400000000, 0x9b36e7e500000000, 0xf0fc1ef700000000, + 0xed01abf600000000, 0xca0675f400000000, 0xd7fbc0f500000000, + 0x8408c9f100000000, 0x99f57cf000000000, 0xbef2a2f200000000, + 0xa30f17f300000000, 0x1814b1fa00000000, 0x05e904fb00000000, + 0x22eedaf900000000, 0x3f136ff800000000, 0x6ce066fc00000000, + 0x711dd3fd00000000, 0x561a0dff00000000, 0x4be7b8fe00000000, + 0xc0c981b700000000, 0xdd3434b600000000, 0xfa33eab400000000, + 0xe7ce5fb500000000, 0xb43d56b100000000, 0xa9c0e3b000000000, + 0x8ec73db200000000, 0x933a88b300000000, 0x28212eba00000000, + 0x35dc9bbb00000000, 0x12db45b900000000, 0x0f26f0b800000000, + 0x5cd5f9bc00000000, 0x41284cbd00000000, 0x662f92bf00000000, + 0x7bd227be00000000, 0x1018deac00000000, 0x0de56bad00000000, + 0x2ae2b5af00000000, 0x371f00ae00000000, 0x64ec09aa00000000, + 0x7911bcab00000000, 0x5e1662a900000000, 0x43ebd7a800000000, + 0xf8f071a100000000, 0xe50dc4a000000000, 0xc20a1aa200000000, + 0xdff7afa300000000, 0x8c04a6a700000000, 0x91f913a600000000, + 0xb6fecda400000000, 0xab0378a500000000, 0x606a3e8100000000, + 0x7d978b8000000000, 0x5a90558200000000, 0x476de08300000000, + 0x149ee98700000000, 0x09635c8600000000, 0x2e64828400000000, + 0x3399378500000000, 0x8882918c00000000, 0x957f248d00000000, + 0xb278fa8f00000000, 0xaf854f8e00000000, 0xfc76468a00000000, + 0xe18bf38b00000000, 0xc68c2d8900000000, 0xdb71988800000000, + 0xb0bb619a00000000, 0xad46d49b00000000, 0x8a410a9900000000, + 0x97bcbf9800000000, 0xc44fb69c00000000, 0xd9b2039d00000000, + 0xfeb5dd9f00000000, 0xe348689e00000000, 0x5853ce9700000000, + 0x45ae7b9600000000, 0x62a9a59400000000, 0x7f54109500000000, + 0x2ca7199100000000, 0x315aac9000000000, 0x165d729200000000, + 0x0ba0c79300000000}, + {0x0000000000000000, 0x24d9076300000000, 0x48b20fc600000000, + 0x6c6b08a500000000, 0xd1626e5700000000, 0xf5bb693400000000, + 0x99d0619100000000, 0xbd0966f200000000, 0xa2c5dcae00000000, + 0x861cdbcd00000000, 0xea77d36800000000, 0xceaed40b00000000, + 0x73a7b2f900000000, 0x577eb59a00000000, 0x3b15bd3f00000000, + 0x1fccba5c00000000, 0x058dc88600000000, 0x2154cfe500000000, + 0x4d3fc74000000000, 0x69e6c02300000000, 0xd4efa6d100000000, + 0xf036a1b200000000, 0x9c5da91700000000, 0xb884ae7400000000, + 0xa748142800000000, 0x8391134b00000000, 0xeffa1bee00000000, + 0xcb231c8d00000000, 0x762a7a7f00000000, 0x52f37d1c00000000, + 0x3e9875b900000000, 0x1a4172da00000000, 0x4b1ce0d600000000, + 0x6fc5e7b500000000, 0x03aeef1000000000, 0x2777e87300000000, + 0x9a7e8e8100000000, 0xbea789e200000000, 0xd2cc814700000000, + 0xf615862400000000, 0xe9d93c7800000000, 0xcd003b1b00000000, + 0xa16b33be00000000, 0x85b234dd00000000, 0x38bb522f00000000, + 0x1c62554c00000000, 0x70095de900000000, 0x54d05a8a00000000, + 0x4e91285000000000, 0x6a482f3300000000, 0x0623279600000000, + 0x22fa20f500000000, 0x9ff3460700000000, 0xbb2a416400000000, + 0xd74149c100000000, 0xf3984ea200000000, 0xec54f4fe00000000, + 0xc88df39d00000000, 0xa4e6fb3800000000, 0x803ffc5b00000000, + 0x3d369aa900000000, 0x19ef9dca00000000, 0x7584956f00000000, + 0x515d920c00000000, 0xd73eb17600000000, 0xf3e7b61500000000, + 0x9f8cbeb000000000, 0xbb55b9d300000000, 0x065cdf2100000000, + 0x2285d84200000000, 0x4eeed0e700000000, 0x6a37d78400000000, + 0x75fb6dd800000000, 0x51226abb00000000, 0x3d49621e00000000, + 0x1990657d00000000, 0xa499038f00000000, 0x804004ec00000000, + 0xec2b0c4900000000, 0xc8f20b2a00000000, 0xd2b379f000000000, + 0xf66a7e9300000000, 0x9a01763600000000, 0xbed8715500000000, + 0x03d117a700000000, 0x270810c400000000, 0x4b63186100000000, + 0x6fba1f0200000000, 0x7076a55e00000000, 0x54afa23d00000000, + 0x38c4aa9800000000, 0x1c1dadfb00000000, 0xa114cb0900000000, + 0x85cdcc6a00000000, 0xe9a6c4cf00000000, 0xcd7fc3ac00000000, + 0x9c2251a000000000, 0xb8fb56c300000000, 0xd4905e6600000000, + 0xf049590500000000, 0x4d403ff700000000, 0x6999389400000000, + 0x05f2303100000000, 0x212b375200000000, 0x3ee78d0e00000000, + 0x1a3e8a6d00000000, 0x765582c800000000, 0x528c85ab00000000, + 0xef85e35900000000, 0xcb5ce43a00000000, 0xa737ec9f00000000, + 0x83eeebfc00000000, 0x99af992600000000, 0xbd769e4500000000, + 0xd11d96e000000000, 0xf5c4918300000000, 0x48cdf77100000000, + 0x6c14f01200000000, 0x007ff8b700000000, 0x24a6ffd400000000, + 0x3b6a458800000000, 0x1fb342eb00000000, 0x73d84a4e00000000, + 0x57014d2d00000000, 0xea082bdf00000000, 0xced12cbc00000000, + 0xa2ba241900000000, 0x8663237a00000000, 0xae7d62ed00000000, + 0x8aa4658e00000000, 0xe6cf6d2b00000000, 0xc2166a4800000000, + 0x7f1f0cba00000000, 0x5bc60bd900000000, 0x37ad037c00000000, + 0x1374041f00000000, 0x0cb8be4300000000, 0x2861b92000000000, + 0x440ab18500000000, 0x60d3b6e600000000, 0xdddad01400000000, + 0xf903d77700000000, 0x9568dfd200000000, 0xb1b1d8b100000000, + 0xabf0aa6b00000000, 0x8f29ad0800000000, 0xe342a5ad00000000, + 0xc79ba2ce00000000, 0x7a92c43c00000000, 0x5e4bc35f00000000, + 0x3220cbfa00000000, 0x16f9cc9900000000, 0x093576c500000000, + 0x2dec71a600000000, 0x4187790300000000, 0x655e7e6000000000, + 0xd857189200000000, 0xfc8e1ff100000000, 0x90e5175400000000, + 0xb43c103700000000, 0xe561823b00000000, 0xc1b8855800000000, + 0xadd38dfd00000000, 0x890a8a9e00000000, 0x3403ec6c00000000, + 0x10daeb0f00000000, 0x7cb1e3aa00000000, 0x5868e4c900000000, + 0x47a45e9500000000, 0x637d59f600000000, 0x0f16515300000000, + 0x2bcf563000000000, 0x96c630c200000000, 0xb21f37a100000000, + 0xde743f0400000000, 0xfaad386700000000, 0xe0ec4abd00000000, + 0xc4354dde00000000, 0xa85e457b00000000, 0x8c87421800000000, + 0x318e24ea00000000, 0x1557238900000000, 0x793c2b2c00000000, + 0x5de52c4f00000000, 0x4229961300000000, 0x66f0917000000000, + 0x0a9b99d500000000, 0x2e429eb600000000, 0x934bf84400000000, + 0xb792ff2700000000, 0xdbf9f78200000000, 0xff20f0e100000000, + 0x7943d39b00000000, 0x5d9ad4f800000000, 0x31f1dc5d00000000, + 0x1528db3e00000000, 0xa821bdcc00000000, 0x8cf8baaf00000000, + 0xe093b20a00000000, 0xc44ab56900000000, 0xdb860f3500000000, + 0xff5f085600000000, 0x933400f300000000, 0xb7ed079000000000, + 0x0ae4616200000000, 0x2e3d660100000000, 0x42566ea400000000, + 0x668f69c700000000, 0x7cce1b1d00000000, 0x58171c7e00000000, + 0x347c14db00000000, 0x10a513b800000000, 0xadac754a00000000, + 0x8975722900000000, 0xe51e7a8c00000000, 0xc1c77def00000000, + 0xde0bc7b300000000, 0xfad2c0d000000000, 0x96b9c87500000000, + 0xb260cf1600000000, 0x0f69a9e400000000, 0x2bb0ae8700000000, + 0x47dba62200000000, 0x6302a14100000000, 0x325f334d00000000, + 0x1686342e00000000, 0x7aed3c8b00000000, 0x5e343be800000000, + 0xe33d5d1a00000000, 0xc7e45a7900000000, 0xab8f52dc00000000, + 0x8f5655bf00000000, 0x909aefe300000000, 0xb443e88000000000, + 0xd828e02500000000, 0xfcf1e74600000000, 0x41f881b400000000, + 0x652186d700000000, 0x094a8e7200000000, 0x2d93891100000000, + 0x37d2fbcb00000000, 0x130bfca800000000, 0x7f60f40d00000000, + 0x5bb9f36e00000000, 0xe6b0959c00000000, 0xc26992ff00000000, + 0xae029a5a00000000, 0x8adb9d3900000000, 0x9517276500000000, + 0xb1ce200600000000, 0xdda528a300000000, 0xf97c2fc000000000, + 0x4475493200000000, 0x60ac4e5100000000, 0x0cc746f400000000, + 0x281e419700000000}, + {0x0000000000000000, 0x08e3603c00000000, 0x10c6c17800000000, + 0x1825a14400000000, 0x208c83f100000000, 0x286fe3cd00000000, + 0x304a428900000000, 0x38a922b500000000, 0x011e763800000000, + 0x09fd160400000000, 0x11d8b74000000000, 0x193bd77c00000000, + 0x2192f5c900000000, 0x297195f500000000, 0x315434b100000000, + 0x39b7548d00000000, 0x023cec7000000000, 0x0adf8c4c00000000, + 0x12fa2d0800000000, 0x1a194d3400000000, 0x22b06f8100000000, + 0x2a530fbd00000000, 0x3276aef900000000, 0x3a95cec500000000, + 0x03229a4800000000, 0x0bc1fa7400000000, 0x13e45b3000000000, + 0x1b073b0c00000000, 0x23ae19b900000000, 0x2b4d798500000000, + 0x3368d8c100000000, 0x3b8bb8fd00000000, 0x0478d8e100000000, + 0x0c9bb8dd00000000, 0x14be199900000000, 0x1c5d79a500000000, + 0x24f45b1000000000, 0x2c173b2c00000000, 0x34329a6800000000, + 0x3cd1fa5400000000, 0x0566aed900000000, 0x0d85cee500000000, + 0x15a06fa100000000, 0x1d430f9d00000000, 0x25ea2d2800000000, + 0x2d094d1400000000, 0x352cec5000000000, 0x3dcf8c6c00000000, + 0x0644349100000000, 0x0ea754ad00000000, 0x1682f5e900000000, + 0x1e6195d500000000, 0x26c8b76000000000, 0x2e2bd75c00000000, + 0x360e761800000000, 0x3eed162400000000, 0x075a42a900000000, + 0x0fb9229500000000, 0x179c83d100000000, 0x1f7fe3ed00000000, + 0x27d6c15800000000, 0x2f35a16400000000, 0x3710002000000000, + 0x3ff3601c00000000, 0x49f6c11800000000, 0x4115a12400000000, + 0x5930006000000000, 0x51d3605c00000000, 0x697a42e900000000, + 0x619922d500000000, 0x79bc839100000000, 0x715fe3ad00000000, + 0x48e8b72000000000, 0x400bd71c00000000, 0x582e765800000000, + 0x50cd166400000000, 0x686434d100000000, 0x608754ed00000000, + 0x78a2f5a900000000, 0x7041959500000000, 0x4bca2d6800000000, + 0x43294d5400000000, 0x5b0cec1000000000, 0x53ef8c2c00000000, + 0x6b46ae9900000000, 0x63a5cea500000000, 0x7b806fe100000000, + 0x73630fdd00000000, 0x4ad45b5000000000, 0x42373b6c00000000, + 0x5a129a2800000000, 0x52f1fa1400000000, 0x6a58d8a100000000, + 0x62bbb89d00000000, 0x7a9e19d900000000, 0x727d79e500000000, + 0x4d8e19f900000000, 0x456d79c500000000, 0x5d48d88100000000, + 0x55abb8bd00000000, 0x6d029a0800000000, 0x65e1fa3400000000, + 0x7dc45b7000000000, 0x75273b4c00000000, 0x4c906fc100000000, + 0x44730ffd00000000, 0x5c56aeb900000000, 0x54b5ce8500000000, + 0x6c1cec3000000000, 0x64ff8c0c00000000, 0x7cda2d4800000000, + 0x74394d7400000000, 0x4fb2f58900000000, 0x475195b500000000, + 0x5f7434f100000000, 0x579754cd00000000, 0x6f3e767800000000, + 0x67dd164400000000, 0x7ff8b70000000000, 0x771bd73c00000000, + 0x4eac83b100000000, 0x464fe38d00000000, 0x5e6a42c900000000, + 0x568922f500000000, 0x6e20004000000000, 0x66c3607c00000000, + 0x7ee6c13800000000, 0x7605a10400000000, 0x92ec833100000000, + 0x9a0fe30d00000000, 0x822a424900000000, 0x8ac9227500000000, + 0xb26000c000000000, 0xba8360fc00000000, 0xa2a6c1b800000000, + 0xaa45a18400000000, 0x93f2f50900000000, 0x9b11953500000000, + 0x8334347100000000, 0x8bd7544d00000000, 0xb37e76f800000000, + 0xbb9d16c400000000, 0xa3b8b78000000000, 0xab5bd7bc00000000, + 0x90d06f4100000000, 0x98330f7d00000000, 0x8016ae3900000000, + 0x88f5ce0500000000, 0xb05cecb000000000, 0xb8bf8c8c00000000, + 0xa09a2dc800000000, 0xa8794df400000000, 0x91ce197900000000, + 0x992d794500000000, 0x8108d80100000000, 0x89ebb83d00000000, + 0xb1429a8800000000, 0xb9a1fab400000000, 0xa1845bf000000000, + 0xa9673bcc00000000, 0x96945bd000000000, 0x9e773bec00000000, + 0x86529aa800000000, 0x8eb1fa9400000000, 0xb618d82100000000, + 0xbefbb81d00000000, 0xa6de195900000000, 0xae3d796500000000, + 0x978a2de800000000, 0x9f694dd400000000, 0x874cec9000000000, + 0x8faf8cac00000000, 0xb706ae1900000000, 0xbfe5ce2500000000, + 0xa7c06f6100000000, 0xaf230f5d00000000, 0x94a8b7a000000000, + 0x9c4bd79c00000000, 0x846e76d800000000, 0x8c8d16e400000000, + 0xb424345100000000, 0xbcc7546d00000000, 0xa4e2f52900000000, + 0xac01951500000000, 0x95b6c19800000000, 0x9d55a1a400000000, + 0x857000e000000000, 0x8d9360dc00000000, 0xb53a426900000000, + 0xbdd9225500000000, 0xa5fc831100000000, 0xad1fe32d00000000, + 0xdb1a422900000000, 0xd3f9221500000000, 0xcbdc835100000000, + 0xc33fe36d00000000, 0xfb96c1d800000000, 0xf375a1e400000000, + 0xeb5000a000000000, 0xe3b3609c00000000, 0xda04341100000000, + 0xd2e7542d00000000, 0xcac2f56900000000, 0xc221955500000000, + 0xfa88b7e000000000, 0xf26bd7dc00000000, 0xea4e769800000000, + 0xe2ad16a400000000, 0xd926ae5900000000, 0xd1c5ce6500000000, + 0xc9e06f2100000000, 0xc1030f1d00000000, 0xf9aa2da800000000, + 0xf1494d9400000000, 0xe96cecd000000000, 0xe18f8cec00000000, + 0xd838d86100000000, 0xd0dbb85d00000000, 0xc8fe191900000000, + 0xc01d792500000000, 0xf8b45b9000000000, 0xf0573bac00000000, + 0xe8729ae800000000, 0xe091fad400000000, 0xdf629ac800000000, + 0xd781faf400000000, 0xcfa45bb000000000, 0xc7473b8c00000000, + 0xffee193900000000, 0xf70d790500000000, 0xef28d84100000000, + 0xe7cbb87d00000000, 0xde7cecf000000000, 0xd69f8ccc00000000, + 0xceba2d8800000000, 0xc6594db400000000, 0xfef06f0100000000, + 0xf6130f3d00000000, 0xee36ae7900000000, 0xe6d5ce4500000000, + 0xdd5e76b800000000, 0xd5bd168400000000, 0xcd98b7c000000000, + 0xc57bd7fc00000000, 0xfdd2f54900000000, 0xf531957500000000, + 0xed14343100000000, 0xe5f7540d00000000, 0xdc40008000000000, + 0xd4a360bc00000000, 0xcc86c1f800000000, 0xc465a1c400000000, + 0xfccc837100000000, 0xf42fe34d00000000, 0xec0a420900000000, + 0xe4e9223500000000}, + {0x0000000000000000, 0xd1e8e70e00000000, 0xa2d1cf1d00000000, + 0x7339281300000000, 0x44a39f3b00000000, 0x954b783500000000, + 0xe672502600000000, 0x379ab72800000000, 0x88463f7700000000, + 0x59aed87900000000, 0x2a97f06a00000000, 0xfb7f176400000000, + 0xcce5a04c00000000, 0x1d0d474200000000, 0x6e346f5100000000, + 0xbfdc885f00000000, 0x108d7eee00000000, 0xc16599e000000000, + 0xb25cb1f300000000, 0x63b456fd00000000, 0x542ee1d500000000, + 0x85c606db00000000, 0xf6ff2ec800000000, 0x2717c9c600000000, + 0x98cb419900000000, 0x4923a69700000000, 0x3a1a8e8400000000, + 0xebf2698a00000000, 0xdc68dea200000000, 0x0d8039ac00000000, + 0x7eb911bf00000000, 0xaf51f6b100000000, 0x611c8c0700000000, + 0xb0f46b0900000000, 0xc3cd431a00000000, 0x1225a41400000000, + 0x25bf133c00000000, 0xf457f43200000000, 0x876edc2100000000, + 0x56863b2f00000000, 0xe95ab37000000000, 0x38b2547e00000000, + 0x4b8b7c6d00000000, 0x9a639b6300000000, 0xadf92c4b00000000, + 0x7c11cb4500000000, 0x0f28e35600000000, 0xdec0045800000000, + 0x7191f2e900000000, 0xa07915e700000000, 0xd3403df400000000, + 0x02a8dafa00000000, 0x35326dd200000000, 0xe4da8adc00000000, + 0x97e3a2cf00000000, 0x460b45c100000000, 0xf9d7cd9e00000000, + 0x283f2a9000000000, 0x5b06028300000000, 0x8aeee58d00000000, + 0xbd7452a500000000, 0x6c9cb5ab00000000, 0x1fa59db800000000, + 0xce4d7ab600000000, 0xc238180f00000000, 0x13d0ff0100000000, + 0x60e9d71200000000, 0xb101301c00000000, 0x869b873400000000, + 0x5773603a00000000, 0x244a482900000000, 0xf5a2af2700000000, + 0x4a7e277800000000, 0x9b96c07600000000, 0xe8afe86500000000, + 0x39470f6b00000000, 0x0eddb84300000000, 0xdf355f4d00000000, + 0xac0c775e00000000, 0x7de4905000000000, 0xd2b566e100000000, + 0x035d81ef00000000, 0x7064a9fc00000000, 0xa18c4ef200000000, + 0x9616f9da00000000, 0x47fe1ed400000000, 0x34c736c700000000, + 0xe52fd1c900000000, 0x5af3599600000000, 0x8b1bbe9800000000, + 0xf822968b00000000, 0x29ca718500000000, 0x1e50c6ad00000000, + 0xcfb821a300000000, 0xbc8109b000000000, 0x6d69eebe00000000, + 0xa324940800000000, 0x72cc730600000000, 0x01f55b1500000000, + 0xd01dbc1b00000000, 0xe7870b3300000000, 0x366fec3d00000000, + 0x4556c42e00000000, 0x94be232000000000, 0x2b62ab7f00000000, + 0xfa8a4c7100000000, 0x89b3646200000000, 0x585b836c00000000, + 0x6fc1344400000000, 0xbe29d34a00000000, 0xcd10fb5900000000, + 0x1cf81c5700000000, 0xb3a9eae600000000, 0x62410de800000000, + 0x117825fb00000000, 0xc090c2f500000000, 0xf70a75dd00000000, + 0x26e292d300000000, 0x55dbbac000000000, 0x84335dce00000000, + 0x3befd59100000000, 0xea07329f00000000, 0x993e1a8c00000000, + 0x48d6fd8200000000, 0x7f4c4aaa00000000, 0xaea4ada400000000, + 0xdd9d85b700000000, 0x0c7562b900000000, 0x8471301e00000000, + 0x5599d71000000000, 0x26a0ff0300000000, 0xf748180d00000000, + 0xc0d2af2500000000, 0x113a482b00000000, 0x6203603800000000, + 0xb3eb873600000000, 0x0c370f6900000000, 0xdddfe86700000000, + 0xaee6c07400000000, 0x7f0e277a00000000, 0x4894905200000000, + 0x997c775c00000000, 0xea455f4f00000000, 0x3badb84100000000, + 0x94fc4ef000000000, 0x4514a9fe00000000, 0x362d81ed00000000, + 0xe7c566e300000000, 0xd05fd1cb00000000, 0x01b736c500000000, + 0x728e1ed600000000, 0xa366f9d800000000, 0x1cba718700000000, + 0xcd52968900000000, 0xbe6bbe9a00000000, 0x6f83599400000000, + 0x5819eebc00000000, 0x89f109b200000000, 0xfac821a100000000, + 0x2b20c6af00000000, 0xe56dbc1900000000, 0x34855b1700000000, + 0x47bc730400000000, 0x9654940a00000000, 0xa1ce232200000000, + 0x7026c42c00000000, 0x031fec3f00000000, 0xd2f70b3100000000, + 0x6d2b836e00000000, 0xbcc3646000000000, 0xcffa4c7300000000, + 0x1e12ab7d00000000, 0x29881c5500000000, 0xf860fb5b00000000, + 0x8b59d34800000000, 0x5ab1344600000000, 0xf5e0c2f700000000, + 0x240825f900000000, 0x57310dea00000000, 0x86d9eae400000000, + 0xb1435dcc00000000, 0x60abbac200000000, 0x139292d100000000, + 0xc27a75df00000000, 0x7da6fd8000000000, 0xac4e1a8e00000000, + 0xdf77329d00000000, 0x0e9fd59300000000, 0x390562bb00000000, + 0xe8ed85b500000000, 0x9bd4ada600000000, 0x4a3c4aa800000000, + 0x4649281100000000, 0x97a1cf1f00000000, 0xe498e70c00000000, + 0x3570000200000000, 0x02eab72a00000000, 0xd302502400000000, + 0xa03b783700000000, 0x71d39f3900000000, 0xce0f176600000000, + 0x1fe7f06800000000, 0x6cded87b00000000, 0xbd363f7500000000, + 0x8aac885d00000000, 0x5b446f5300000000, 0x287d474000000000, + 0xf995a04e00000000, 0x56c456ff00000000, 0x872cb1f100000000, + 0xf41599e200000000, 0x25fd7eec00000000, 0x1267c9c400000000, + 0xc38f2eca00000000, 0xb0b606d900000000, 0x615ee1d700000000, + 0xde82698800000000, 0x0f6a8e8600000000, 0x7c53a69500000000, + 0xadbb419b00000000, 0x9a21f6b300000000, 0x4bc911bd00000000, + 0x38f039ae00000000, 0xe918dea000000000, 0x2755a41600000000, + 0xf6bd431800000000, 0x85846b0b00000000, 0x546c8c0500000000, + 0x63f63b2d00000000, 0xb21edc2300000000, 0xc127f43000000000, + 0x10cf133e00000000, 0xaf139b6100000000, 0x7efb7c6f00000000, + 0x0dc2547c00000000, 0xdc2ab37200000000, 0xebb0045a00000000, + 0x3a58e35400000000, 0x4961cb4700000000, 0x98892c4900000000, + 0x37d8daf800000000, 0xe6303df600000000, 0x950915e500000000, + 0x44e1f2eb00000000, 0x737b45c300000000, 0xa293a2cd00000000, + 0xd1aa8ade00000000, 0x00426dd000000000, 0xbf9ee58f00000000, + 0x6e76028100000000, 0x1d4f2a9200000000, 0xcca7cd9c00000000, + 0xfb3d7ab400000000, 0x2ad59dba00000000, 0x59ecb5a900000000, + 0x880452a700000000}, + {0x0000000000000000, 0xaa05daf100000000, 0x150dc53800000000, + 0xbf081fc900000000, 0x2a1a8a7100000000, 0x801f508000000000, + 0x3f174f4900000000, 0x951295b800000000, 0x543414e300000000, + 0xfe31ce1200000000, 0x4139d1db00000000, 0xeb3c0b2a00000000, + 0x7e2e9e9200000000, 0xd42b446300000000, 0x6b235baa00000000, + 0xc126815b00000000, 0xe96e591d00000000, 0x436b83ec00000000, + 0xfc639c2500000000, 0x566646d400000000, 0xc374d36c00000000, + 0x6971099d00000000, 0xd679165400000000, 0x7c7ccca500000000, + 0xbd5a4dfe00000000, 0x175f970f00000000, 0xa85788c600000000, + 0x0252523700000000, 0x9740c78f00000000, 0x3d451d7e00000000, + 0x824d02b700000000, 0x2848d84600000000, 0xd2ddb23a00000000, + 0x78d868cb00000000, 0xc7d0770200000000, 0x6dd5adf300000000, + 0xf8c7384b00000000, 0x52c2e2ba00000000, 0xedcafd7300000000, + 0x47cf278200000000, 0x86e9a6d900000000, 0x2cec7c2800000000, + 0x93e463e100000000, 0x39e1b91000000000, 0xacf32ca800000000, + 0x06f6f65900000000, 0xb9fee99000000000, 0x13fb336100000000, + 0x3bb3eb2700000000, 0x91b631d600000000, 0x2ebe2e1f00000000, + 0x84bbf4ee00000000, 0x11a9615600000000, 0xbbacbba700000000, + 0x04a4a46e00000000, 0xaea17e9f00000000, 0x6f87ffc400000000, + 0xc582253500000000, 0x7a8a3afc00000000, 0xd08fe00d00000000, + 0x459d75b500000000, 0xef98af4400000000, 0x5090b08d00000000, + 0xfa956a7c00000000, 0xa4bb657500000000, 0x0ebebf8400000000, + 0xb1b6a04d00000000, 0x1bb37abc00000000, 0x8ea1ef0400000000, + 0x24a435f500000000, 0x9bac2a3c00000000, 0x31a9f0cd00000000, + 0xf08f719600000000, 0x5a8aab6700000000, 0xe582b4ae00000000, + 0x4f876e5f00000000, 0xda95fbe700000000, 0x7090211600000000, + 0xcf983edf00000000, 0x659de42e00000000, 0x4dd53c6800000000, + 0xe7d0e69900000000, 0x58d8f95000000000, 0xf2dd23a100000000, + 0x67cfb61900000000, 0xcdca6ce800000000, 0x72c2732100000000, + 0xd8c7a9d000000000, 0x19e1288b00000000, 0xb3e4f27a00000000, + 0x0cecedb300000000, 0xa6e9374200000000, 0x33fba2fa00000000, + 0x99fe780b00000000, 0x26f667c200000000, 0x8cf3bd3300000000, + 0x7666d74f00000000, 0xdc630dbe00000000, 0x636b127700000000, + 0xc96ec88600000000, 0x5c7c5d3e00000000, 0xf67987cf00000000, + 0x4971980600000000, 0xe37442f700000000, 0x2252c3ac00000000, + 0x8857195d00000000, 0x375f069400000000, 0x9d5adc6500000000, + 0x084849dd00000000, 0xa24d932c00000000, 0x1d458ce500000000, + 0xb740561400000000, 0x9f088e5200000000, 0x350d54a300000000, + 0x8a054b6a00000000, 0x2000919b00000000, 0xb512042300000000, + 0x1f17ded200000000, 0xa01fc11b00000000, 0x0a1a1bea00000000, + 0xcb3c9ab100000000, 0x6139404000000000, 0xde315f8900000000, + 0x7434857800000000, 0xe12610c000000000, 0x4b23ca3100000000, + 0xf42bd5f800000000, 0x5e2e0f0900000000, 0x4877cbea00000000, + 0xe272111b00000000, 0x5d7a0ed200000000, 0xf77fd42300000000, + 0x626d419b00000000, 0xc8689b6a00000000, 0x776084a300000000, + 0xdd655e5200000000, 0x1c43df0900000000, 0xb64605f800000000, + 0x094e1a3100000000, 0xa34bc0c000000000, 0x3659557800000000, + 0x9c5c8f8900000000, 0x2354904000000000, 0x89514ab100000000, + 0xa11992f700000000, 0x0b1c480600000000, 0xb41457cf00000000, + 0x1e118d3e00000000, 0x8b03188600000000, 0x2106c27700000000, + 0x9e0eddbe00000000, 0x340b074f00000000, 0xf52d861400000000, + 0x5f285ce500000000, 0xe020432c00000000, 0x4a2599dd00000000, + 0xdf370c6500000000, 0x7532d69400000000, 0xca3ac95d00000000, + 0x603f13ac00000000, 0x9aaa79d000000000, 0x30afa32100000000, + 0x8fa7bce800000000, 0x25a2661900000000, 0xb0b0f3a100000000, + 0x1ab5295000000000, 0xa5bd369900000000, 0x0fb8ec6800000000, + 0xce9e6d3300000000, 0x649bb7c200000000, 0xdb93a80b00000000, + 0x719672fa00000000, 0xe484e74200000000, 0x4e813db300000000, + 0xf189227a00000000, 0x5b8cf88b00000000, 0x73c420cd00000000, + 0xd9c1fa3c00000000, 0x66c9e5f500000000, 0xcccc3f0400000000, + 0x59deaabc00000000, 0xf3db704d00000000, 0x4cd36f8400000000, + 0xe6d6b57500000000, 0x27f0342e00000000, 0x8df5eedf00000000, + 0x32fdf11600000000, 0x98f82be700000000, 0x0deabe5f00000000, + 0xa7ef64ae00000000, 0x18e77b6700000000, 0xb2e2a19600000000, + 0xecccae9f00000000, 0x46c9746e00000000, 0xf9c16ba700000000, + 0x53c4b15600000000, 0xc6d624ee00000000, 0x6cd3fe1f00000000, + 0xd3dbe1d600000000, 0x79de3b2700000000, 0xb8f8ba7c00000000, + 0x12fd608d00000000, 0xadf57f4400000000, 0x07f0a5b500000000, + 0x92e2300d00000000, 0x38e7eafc00000000, 0x87eff53500000000, + 0x2dea2fc400000000, 0x05a2f78200000000, 0xafa72d7300000000, + 0x10af32ba00000000, 0xbaaae84b00000000, 0x2fb87df300000000, + 0x85bda70200000000, 0x3ab5b8cb00000000, 0x90b0623a00000000, + 0x5196e36100000000, 0xfb93399000000000, 0x449b265900000000, + 0xee9efca800000000, 0x7b8c691000000000, 0xd189b3e100000000, + 0x6e81ac2800000000, 0xc48476d900000000, 0x3e111ca500000000, + 0x9414c65400000000, 0x2b1cd99d00000000, 0x8119036c00000000, + 0x140b96d400000000, 0xbe0e4c2500000000, 0x010653ec00000000, + 0xab03891d00000000, 0x6a25084600000000, 0xc020d2b700000000, + 0x7f28cd7e00000000, 0xd52d178f00000000, 0x403f823700000000, + 0xea3a58c600000000, 0x5532470f00000000, 0xff379dfe00000000, + 0xd77f45b800000000, 0x7d7a9f4900000000, 0xc272808000000000, + 0x68775a7100000000, 0xfd65cfc900000000, 0x5760153800000000, + 0xe8680af100000000, 0x426dd00000000000, 0x834b515b00000000, + 0x294e8baa00000000, 0x9646946300000000, 0x3c434e9200000000, + 0xa951db2a00000000, 0x035401db00000000, 0xbc5c1e1200000000, + 0x1659c4e300000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xae689191, 0x87a02563, 0x29c8b4f2, 0xd4314c87, + 0x7a59dd16, 0x539169e4, 0xfdf9f875, 0x73139f4f, 0xdd7b0ede, + 0xf4b3ba2c, 0x5adb2bbd, 0xa722d3c8, 0x094a4259, 0x2082f6ab, + 0x8eea673a, 0xe6273e9e, 0x484faf0f, 0x61871bfd, 0xcfef8a6c, + 0x32167219, 0x9c7ee388, 0xb5b6577a, 0x1bdec6eb, 0x9534a1d1, + 0x3b5c3040, 0x129484b2, 0xbcfc1523, 0x4105ed56, 0xef6d7cc7, + 0xc6a5c835, 0x68cd59a4, 0x173f7b7d, 0xb957eaec, 0x909f5e1e, + 0x3ef7cf8f, 0xc30e37fa, 0x6d66a66b, 0x44ae1299, 0xeac68308, + 0x642ce432, 0xca4475a3, 0xe38cc151, 0x4de450c0, 0xb01da8b5, + 0x1e753924, 0x37bd8dd6, 0x99d51c47, 0xf11845e3, 0x5f70d472, + 0x76b86080, 0xd8d0f111, 0x25290964, 0x8b4198f5, 0xa2892c07, + 0x0ce1bd96, 0x820bdaac, 0x2c634b3d, 0x05abffcf, 0xabc36e5e, + 0x563a962b, 0xf85207ba, 0xd19ab348, 0x7ff222d9, 0x2e7ef6fa, + 0x8016676b, 0xa9ded399, 0x07b64208, 0xfa4fba7d, 0x54272bec, + 0x7def9f1e, 0xd3870e8f, 0x5d6d69b5, 0xf305f824, 0xdacd4cd6, + 0x74a5dd47, 0x895c2532, 0x2734b4a3, 0x0efc0051, 0xa09491c0, + 0xc859c864, 0x663159f5, 0x4ff9ed07, 0xe1917c96, 0x1c6884e3, + 0xb2001572, 0x9bc8a180, 0x35a03011, 0xbb4a572b, 0x1522c6ba, + 0x3cea7248, 0x9282e3d9, 0x6f7b1bac, 0xc1138a3d, 0xe8db3ecf, + 0x46b3af5e, 0x39418d87, 0x97291c16, 0xbee1a8e4, 0x10893975, + 0xed70c100, 0x43185091, 0x6ad0e463, 0xc4b875f2, 0x4a5212c8, + 0xe43a8359, 0xcdf237ab, 0x639aa63a, 0x9e635e4f, 0x300bcfde, + 0x19c37b2c, 0xb7abeabd, 0xdf66b319, 0x710e2288, 0x58c6967a, + 0xf6ae07eb, 0x0b57ff9e, 0xa53f6e0f, 0x8cf7dafd, 0x229f4b6c, + 0xac752c56, 0x021dbdc7, 0x2bd50935, 0x85bd98a4, 0x784460d1, + 0xd62cf140, 0xffe445b2, 0x518cd423, 0x5cfdedf4, 0xf2957c65, + 0xdb5dc897, 0x75355906, 0x88cca173, 0x26a430e2, 0x0f6c8410, + 0xa1041581, 0x2fee72bb, 0x8186e32a, 0xa84e57d8, 0x0626c649, + 0xfbdf3e3c, 0x55b7afad, 0x7c7f1b5f, 0xd2178ace, 0xbadad36a, + 0x14b242fb, 0x3d7af609, 0x93126798, 0x6eeb9fed, 0xc0830e7c, + 0xe94bba8e, 0x47232b1f, 0xc9c94c25, 0x67a1ddb4, 0x4e696946, + 0xe001f8d7, 0x1df800a2, 0xb3909133, 0x9a5825c1, 0x3430b450, + 0x4bc29689, 0xe5aa0718, 0xcc62b3ea, 0x620a227b, 0x9ff3da0e, + 0x319b4b9f, 0x1853ff6d, 0xb63b6efc, 0x38d109c6, 0x96b99857, + 0xbf712ca5, 0x1119bd34, 0xece04541, 0x4288d4d0, 0x6b406022, + 0xc528f1b3, 0xade5a817, 0x038d3986, 0x2a458d74, 0x842d1ce5, + 0x79d4e490, 0xd7bc7501, 0xfe74c1f3, 0x501c5062, 0xdef63758, + 0x709ea6c9, 0x5956123b, 0xf73e83aa, 0x0ac77bdf, 0xa4afea4e, + 0x8d675ebc, 0x230fcf2d, 0x72831b0e, 0xdceb8a9f, 0xf5233e6d, + 0x5b4baffc, 0xa6b25789, 0x08dac618, 0x211272ea, 0x8f7ae37b, + 0x01908441, 0xaff815d0, 0x8630a122, 0x285830b3, 0xd5a1c8c6, + 0x7bc95957, 0x5201eda5, 0xfc697c34, 0x94a42590, 0x3accb401, + 0x130400f3, 0xbd6c9162, 0x40956917, 0xeefdf886, 0xc7354c74, + 0x695ddde5, 0xe7b7badf, 0x49df2b4e, 0x60179fbc, 0xce7f0e2d, + 0x3386f658, 0x9dee67c9, 0xb426d33b, 0x1a4e42aa, 0x65bc6073, + 0xcbd4f1e2, 0xe21c4510, 0x4c74d481, 0xb18d2cf4, 0x1fe5bd65, + 0x362d0997, 0x98459806, 0x16afff3c, 0xb8c76ead, 0x910fda5f, + 0x3f674bce, 0xc29eb3bb, 0x6cf6222a, 0x453e96d8, 0xeb560749, + 0x839b5eed, 0x2df3cf7c, 0x043b7b8e, 0xaa53ea1f, 0x57aa126a, + 0xf9c283fb, 0xd00a3709, 0x7e62a698, 0xf088c1a2, 0x5ee05033, + 0x7728e4c1, 0xd9407550, 0x24b98d25, 0x8ad11cb4, 0xa319a846, + 0x0d7139d7}, + {0x00000000, 0xb9fbdbe8, 0xa886b191, 0x117d6a79, 0x8a7c6563, + 0x3387be8b, 0x22fad4f2, 0x9b010f1a, 0xcf89cc87, 0x7672176f, + 0x670f7d16, 0xdef4a6fe, 0x45f5a9e4, 0xfc0e720c, 0xed731875, + 0x5488c39d, 0x44629f4f, 0xfd9944a7, 0xece42ede, 0x551ff536, + 0xce1efa2c, 0x77e521c4, 0x66984bbd, 0xdf639055, 0x8beb53c8, + 0x32108820, 0x236de259, 0x9a9639b1, 0x019736ab, 0xb86ced43, + 0xa911873a, 0x10ea5cd2, 0x88c53e9e, 0x313ee576, 0x20438f0f, + 0x99b854e7, 0x02b95bfd, 0xbb428015, 0xaa3fea6c, 0x13c43184, + 0x474cf219, 0xfeb729f1, 0xefca4388, 0x56319860, 0xcd30977a, + 0x74cb4c92, 0x65b626eb, 0xdc4dfd03, 0xcca7a1d1, 0x755c7a39, + 0x64211040, 0xdddacba8, 0x46dbc4b2, 0xff201f5a, 0xee5d7523, + 0x57a6aecb, 0x032e6d56, 0xbad5b6be, 0xaba8dcc7, 0x1253072f, + 0x89520835, 0x30a9d3dd, 0x21d4b9a4, 0x982f624c, 0xcafb7b7d, + 0x7300a095, 0x627dcaec, 0xdb861104, 0x40871e1e, 0xf97cc5f6, + 0xe801af8f, 0x51fa7467, 0x0572b7fa, 0xbc896c12, 0xadf4066b, + 0x140fdd83, 0x8f0ed299, 0x36f50971, 0x27886308, 0x9e73b8e0, + 0x8e99e432, 0x37623fda, 0x261f55a3, 0x9fe48e4b, 0x04e58151, + 0xbd1e5ab9, 0xac6330c0, 0x1598eb28, 0x411028b5, 0xf8ebf35d, + 0xe9969924, 0x506d42cc, 0xcb6c4dd6, 0x7297963e, 0x63eafc47, + 0xda1127af, 0x423e45e3, 0xfbc59e0b, 0xeab8f472, 0x53432f9a, + 0xc8422080, 0x71b9fb68, 0x60c49111, 0xd93f4af9, 0x8db78964, + 0x344c528c, 0x253138f5, 0x9ccae31d, 0x07cbec07, 0xbe3037ef, + 0xaf4d5d96, 0x16b6867e, 0x065cdaac, 0xbfa70144, 0xaeda6b3d, + 0x1721b0d5, 0x8c20bfcf, 0x35db6427, 0x24a60e5e, 0x9d5dd5b6, + 0xc9d5162b, 0x702ecdc3, 0x6153a7ba, 0xd8a87c52, 0x43a97348, + 0xfa52a8a0, 0xeb2fc2d9, 0x52d41931, 0x4e87f0bb, 0xf77c2b53, + 0xe601412a, 0x5ffa9ac2, 0xc4fb95d8, 0x7d004e30, 0x6c7d2449, + 0xd586ffa1, 0x810e3c3c, 0x38f5e7d4, 0x29888dad, 0x90735645, + 0x0b72595f, 0xb28982b7, 0xa3f4e8ce, 0x1a0f3326, 0x0ae56ff4, + 0xb31eb41c, 0xa263de65, 0x1b98058d, 0x80990a97, 0x3962d17f, + 0x281fbb06, 0x91e460ee, 0xc56ca373, 0x7c97789b, 0x6dea12e2, + 0xd411c90a, 0x4f10c610, 0xf6eb1df8, 0xe7967781, 0x5e6dac69, + 0xc642ce25, 0x7fb915cd, 0x6ec47fb4, 0xd73fa45c, 0x4c3eab46, + 0xf5c570ae, 0xe4b81ad7, 0x5d43c13f, 0x09cb02a2, 0xb030d94a, + 0xa14db333, 0x18b668db, 0x83b767c1, 0x3a4cbc29, 0x2b31d650, + 0x92ca0db8, 0x8220516a, 0x3bdb8a82, 0x2aa6e0fb, 0x935d3b13, + 0x085c3409, 0xb1a7efe1, 0xa0da8598, 0x19215e70, 0x4da99ded, + 0xf4524605, 0xe52f2c7c, 0x5cd4f794, 0xc7d5f88e, 0x7e2e2366, + 0x6f53491f, 0xd6a892f7, 0x847c8bc6, 0x3d87502e, 0x2cfa3a57, + 0x9501e1bf, 0x0e00eea5, 0xb7fb354d, 0xa6865f34, 0x1f7d84dc, + 0x4bf54741, 0xf20e9ca9, 0xe373f6d0, 0x5a882d38, 0xc1892222, + 0x7872f9ca, 0x690f93b3, 0xd0f4485b, 0xc01e1489, 0x79e5cf61, + 0x6898a518, 0xd1637ef0, 0x4a6271ea, 0xf399aa02, 0xe2e4c07b, + 0x5b1f1b93, 0x0f97d80e, 0xb66c03e6, 0xa711699f, 0x1eeab277, + 0x85ebbd6d, 0x3c106685, 0x2d6d0cfc, 0x9496d714, 0x0cb9b558, + 0xb5426eb0, 0xa43f04c9, 0x1dc4df21, 0x86c5d03b, 0x3f3e0bd3, + 0x2e4361aa, 0x97b8ba42, 0xc33079df, 0x7acba237, 0x6bb6c84e, + 0xd24d13a6, 0x494c1cbc, 0xf0b7c754, 0xe1caad2d, 0x583176c5, + 0x48db2a17, 0xf120f1ff, 0xe05d9b86, 0x59a6406e, 0xc2a74f74, + 0x7b5c949c, 0x6a21fee5, 0xd3da250d, 0x8752e690, 0x3ea93d78, + 0x2fd45701, 0x962f8ce9, 0x0d2e83f3, 0xb4d5581b, 0xa5a83262, + 0x1c53e98a}, + {0x00000000, 0x9d0fe176, 0xe16ec4ad, 0x7c6125db, 0x19ac8f1b, + 0x84a36e6d, 0xf8c24bb6, 0x65cdaac0, 0x33591e36, 0xae56ff40, + 0xd237da9b, 0x4f383bed, 0x2af5912d, 0xb7fa705b, 0xcb9b5580, + 0x5694b4f6, 0x66b23c6c, 0xfbbddd1a, 0x87dcf8c1, 0x1ad319b7, + 0x7f1eb377, 0xe2115201, 0x9e7077da, 0x037f96ac, 0x55eb225a, + 0xc8e4c32c, 0xb485e6f7, 0x298a0781, 0x4c47ad41, 0xd1484c37, + 0xad2969ec, 0x3026889a, 0xcd6478d8, 0x506b99ae, 0x2c0abc75, + 0xb1055d03, 0xd4c8f7c3, 0x49c716b5, 0x35a6336e, 0xa8a9d218, + 0xfe3d66ee, 0x63328798, 0x1f53a243, 0x825c4335, 0xe791e9f5, + 0x7a9e0883, 0x06ff2d58, 0x9bf0cc2e, 0xabd644b4, 0x36d9a5c2, + 0x4ab88019, 0xd7b7616f, 0xb27acbaf, 0x2f752ad9, 0x53140f02, + 0xce1bee74, 0x988f5a82, 0x0580bbf4, 0x79e19e2f, 0xe4ee7f59, + 0x8123d599, 0x1c2c34ef, 0x604d1134, 0xfd42f042, 0x41b9f7f1, + 0xdcb61687, 0xa0d7335c, 0x3dd8d22a, 0x581578ea, 0xc51a999c, + 0xb97bbc47, 0x24745d31, 0x72e0e9c7, 0xefef08b1, 0x938e2d6a, + 0x0e81cc1c, 0x6b4c66dc, 0xf64387aa, 0x8a22a271, 0x172d4307, + 0x270bcb9d, 0xba042aeb, 0xc6650f30, 0x5b6aee46, 0x3ea74486, + 0xa3a8a5f0, 0xdfc9802b, 0x42c6615d, 0x1452d5ab, 0x895d34dd, + 0xf53c1106, 0x6833f070, 0x0dfe5ab0, 0x90f1bbc6, 0xec909e1d, + 0x719f7f6b, 0x8cdd8f29, 0x11d26e5f, 0x6db34b84, 0xf0bcaaf2, + 0x95710032, 0x087ee144, 0x741fc49f, 0xe91025e9, 0xbf84911f, + 0x228b7069, 0x5eea55b2, 0xc3e5b4c4, 0xa6281e04, 0x3b27ff72, + 0x4746daa9, 0xda493bdf, 0xea6fb345, 0x77605233, 0x0b0177e8, + 0x960e969e, 0xf3c33c5e, 0x6eccdd28, 0x12adf8f3, 0x8fa21985, + 0xd936ad73, 0x44394c05, 0x385869de, 0xa55788a8, 0xc09a2268, + 0x5d95c31e, 0x21f4e6c5, 0xbcfb07b3, 0x8373efe2, 0x1e7c0e94, + 0x621d2b4f, 0xff12ca39, 0x9adf60f9, 0x07d0818f, 0x7bb1a454, + 0xe6be4522, 0xb02af1d4, 0x2d2510a2, 0x51443579, 0xcc4bd40f, + 0xa9867ecf, 0x34899fb9, 0x48e8ba62, 0xd5e75b14, 0xe5c1d38e, + 0x78ce32f8, 0x04af1723, 0x99a0f655, 0xfc6d5c95, 0x6162bde3, + 0x1d039838, 0x800c794e, 0xd698cdb8, 0x4b972cce, 0x37f60915, + 0xaaf9e863, 0xcf3442a3, 0x523ba3d5, 0x2e5a860e, 0xb3556778, + 0x4e17973a, 0xd318764c, 0xaf795397, 0x3276b2e1, 0x57bb1821, + 0xcab4f957, 0xb6d5dc8c, 0x2bda3dfa, 0x7d4e890c, 0xe041687a, + 0x9c204da1, 0x012facd7, 0x64e20617, 0xf9ede761, 0x858cc2ba, + 0x188323cc, 0x28a5ab56, 0xb5aa4a20, 0xc9cb6ffb, 0x54c48e8d, + 0x3109244d, 0xac06c53b, 0xd067e0e0, 0x4d680196, 0x1bfcb560, + 0x86f35416, 0xfa9271cd, 0x679d90bb, 0x02503a7b, 0x9f5fdb0d, + 0xe33efed6, 0x7e311fa0, 0xc2ca1813, 0x5fc5f965, 0x23a4dcbe, + 0xbeab3dc8, 0xdb669708, 0x4669767e, 0x3a0853a5, 0xa707b2d3, + 0xf1930625, 0x6c9ce753, 0x10fdc288, 0x8df223fe, 0xe83f893e, + 0x75306848, 0x09514d93, 0x945eace5, 0xa478247f, 0x3977c509, + 0x4516e0d2, 0xd81901a4, 0xbdd4ab64, 0x20db4a12, 0x5cba6fc9, + 0xc1b58ebf, 0x97213a49, 0x0a2edb3f, 0x764ffee4, 0xeb401f92, + 0x8e8db552, 0x13825424, 0x6fe371ff, 0xf2ec9089, 0x0fae60cb, + 0x92a181bd, 0xeec0a466, 0x73cf4510, 0x1602efd0, 0x8b0d0ea6, + 0xf76c2b7d, 0x6a63ca0b, 0x3cf77efd, 0xa1f89f8b, 0xdd99ba50, + 0x40965b26, 0x255bf1e6, 0xb8541090, 0xc435354b, 0x593ad43d, + 0x691c5ca7, 0xf413bdd1, 0x8872980a, 0x157d797c, 0x70b0d3bc, + 0xedbf32ca, 0x91de1711, 0x0cd1f667, 0x5a454291, 0xc74aa3e7, + 0xbb2b863c, 0x2624674a, 0x43e9cd8a, 0xdee62cfc, 0xa2870927, + 0x3f88e851}, + {0x00000000, 0xdd96d985, 0x605cb54b, 0xbdca6cce, 0xc0b96a96, + 0x1d2fb313, 0xa0e5dfdd, 0x7d730658, 0x5a03d36d, 0x87950ae8, + 0x3a5f6626, 0xe7c9bfa3, 0x9abab9fb, 0x472c607e, 0xfae60cb0, + 0x2770d535, 0xb407a6da, 0x69917f5f, 0xd45b1391, 0x09cdca14, + 0x74becc4c, 0xa92815c9, 0x14e27907, 0xc974a082, 0xee0475b7, + 0x3392ac32, 0x8e58c0fc, 0x53ce1979, 0x2ebd1f21, 0xf32bc6a4, + 0x4ee1aa6a, 0x937773ef, 0xb37e4bf5, 0x6ee89270, 0xd322febe, + 0x0eb4273b, 0x73c72163, 0xae51f8e6, 0x139b9428, 0xce0d4dad, + 0xe97d9898, 0x34eb411d, 0x89212dd3, 0x54b7f456, 0x29c4f20e, + 0xf4522b8b, 0x49984745, 0x940e9ec0, 0x0779ed2f, 0xdaef34aa, + 0x67255864, 0xbab381e1, 0xc7c087b9, 0x1a565e3c, 0xa79c32f2, + 0x7a0aeb77, 0x5d7a3e42, 0x80ece7c7, 0x3d268b09, 0xe0b0528c, + 0x9dc354d4, 0x40558d51, 0xfd9fe19f, 0x2009381a, 0xbd8d91ab, + 0x601b482e, 0xddd124e0, 0x0047fd65, 0x7d34fb3d, 0xa0a222b8, + 0x1d684e76, 0xc0fe97f3, 0xe78e42c6, 0x3a189b43, 0x87d2f78d, + 0x5a442e08, 0x27372850, 0xfaa1f1d5, 0x476b9d1b, 0x9afd449e, + 0x098a3771, 0xd41ceef4, 0x69d6823a, 0xb4405bbf, 0xc9335de7, + 0x14a58462, 0xa96fe8ac, 0x74f93129, 0x5389e41c, 0x8e1f3d99, + 0x33d55157, 0xee4388d2, 0x93308e8a, 0x4ea6570f, 0xf36c3bc1, + 0x2efae244, 0x0ef3da5e, 0xd36503db, 0x6eaf6f15, 0xb339b690, + 0xce4ab0c8, 0x13dc694d, 0xae160583, 0x7380dc06, 0x54f00933, + 0x8966d0b6, 0x34acbc78, 0xe93a65fd, 0x944963a5, 0x49dfba20, + 0xf415d6ee, 0x29830f6b, 0xbaf47c84, 0x6762a501, 0xdaa8c9cf, + 0x073e104a, 0x7a4d1612, 0xa7dbcf97, 0x1a11a359, 0xc7877adc, + 0xe0f7afe9, 0x3d61766c, 0x80ab1aa2, 0x5d3dc327, 0x204ec57f, + 0xfdd81cfa, 0x40127034, 0x9d84a9b1, 0xa06a2517, 0x7dfcfc92, + 0xc036905c, 0x1da049d9, 0x60d34f81, 0xbd459604, 0x008ffaca, + 0xdd19234f, 0xfa69f67a, 0x27ff2fff, 0x9a354331, 0x47a39ab4, + 0x3ad09cec, 0xe7464569, 0x5a8c29a7, 0x871af022, 0x146d83cd, + 0xc9fb5a48, 0x74313686, 0xa9a7ef03, 0xd4d4e95b, 0x094230de, + 0xb4885c10, 0x691e8595, 0x4e6e50a0, 0x93f88925, 0x2e32e5eb, + 0xf3a43c6e, 0x8ed73a36, 0x5341e3b3, 0xee8b8f7d, 0x331d56f8, + 0x13146ee2, 0xce82b767, 0x7348dba9, 0xaede022c, 0xd3ad0474, + 0x0e3bddf1, 0xb3f1b13f, 0x6e6768ba, 0x4917bd8f, 0x9481640a, + 0x294b08c4, 0xf4ddd141, 0x89aed719, 0x54380e9c, 0xe9f26252, + 0x3464bbd7, 0xa713c838, 0x7a8511bd, 0xc74f7d73, 0x1ad9a4f6, + 0x67aaa2ae, 0xba3c7b2b, 0x07f617e5, 0xda60ce60, 0xfd101b55, + 0x2086c2d0, 0x9d4cae1e, 0x40da779b, 0x3da971c3, 0xe03fa846, + 0x5df5c488, 0x80631d0d, 0x1de7b4bc, 0xc0716d39, 0x7dbb01f7, + 0xa02dd872, 0xdd5ede2a, 0x00c807af, 0xbd026b61, 0x6094b2e4, + 0x47e467d1, 0x9a72be54, 0x27b8d29a, 0xfa2e0b1f, 0x875d0d47, + 0x5acbd4c2, 0xe701b80c, 0x3a976189, 0xa9e01266, 0x7476cbe3, + 0xc9bca72d, 0x142a7ea8, 0x695978f0, 0xb4cfa175, 0x0905cdbb, + 0xd493143e, 0xf3e3c10b, 0x2e75188e, 0x93bf7440, 0x4e29adc5, + 0x335aab9d, 0xeecc7218, 0x53061ed6, 0x8e90c753, 0xae99ff49, + 0x730f26cc, 0xcec54a02, 0x13539387, 0x6e2095df, 0xb3b64c5a, + 0x0e7c2094, 0xd3eaf911, 0xf49a2c24, 0x290cf5a1, 0x94c6996f, + 0x495040ea, 0x342346b2, 0xe9b59f37, 0x547ff3f9, 0x89e92a7c, + 0x1a9e5993, 0xc7088016, 0x7ac2ecd8, 0xa754355d, 0xda273305, + 0x07b1ea80, 0xba7b864e, 0x67ed5fcb, 0x409d8afe, 0x9d0b537b, + 0x20c13fb5, 0xfd57e630, 0x8024e068, 0x5db239ed, 0xe0785523, + 0x3dee8ca6}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x85d996dd, 0x4bb55c60, 0xce6ccabd, 0x966ab9c0, + 0x13b32f1d, 0xdddfe5a0, 0x5806737d, 0x6dd3035a, 0xe80a9587, + 0x26665f3a, 0xa3bfc9e7, 0xfbb9ba9a, 0x7e602c47, 0xb00ce6fa, + 0x35d57027, 0xdaa607b4, 0x5f7f9169, 0x91135bd4, 0x14cacd09, + 0x4cccbe74, 0xc91528a9, 0x0779e214, 0x82a074c9, 0xb77504ee, + 0x32ac9233, 0xfcc0588e, 0x7919ce53, 0x211fbd2e, 0xa4c62bf3, + 0x6aaae14e, 0xef737793, 0xf54b7eb3, 0x7092e86e, 0xbefe22d3, + 0x3b27b40e, 0x6321c773, 0xe6f851ae, 0x28949b13, 0xad4d0dce, + 0x98987de9, 0x1d41eb34, 0xd32d2189, 0x56f4b754, 0x0ef2c429, + 0x8b2b52f4, 0x45479849, 0xc09e0e94, 0x2fed7907, 0xaa34efda, + 0x64582567, 0xe181b3ba, 0xb987c0c7, 0x3c5e561a, 0xf2329ca7, + 0x77eb0a7a, 0x423e7a5d, 0xc7e7ec80, 0x098b263d, 0x8c52b0e0, + 0xd454c39d, 0x518d5540, 0x9fe19ffd, 0x1a380920, 0xab918dbd, + 0x2e481b60, 0xe024d1dd, 0x65fd4700, 0x3dfb347d, 0xb822a2a0, + 0x764e681d, 0xf397fec0, 0xc6428ee7, 0x439b183a, 0x8df7d287, + 0x082e445a, 0x50283727, 0xd5f1a1fa, 0x1b9d6b47, 0x9e44fd9a, + 0x71378a09, 0xf4ee1cd4, 0x3a82d669, 0xbf5b40b4, 0xe75d33c9, + 0x6284a514, 0xace86fa9, 0x2931f974, 0x1ce48953, 0x993d1f8e, + 0x5751d533, 0xd28843ee, 0x8a8e3093, 0x0f57a64e, 0xc13b6cf3, + 0x44e2fa2e, 0x5edaf30e, 0xdb0365d3, 0x156faf6e, 0x90b639b3, + 0xc8b04ace, 0x4d69dc13, 0x830516ae, 0x06dc8073, 0x3309f054, + 0xb6d06689, 0x78bcac34, 0xfd653ae9, 0xa5634994, 0x20badf49, + 0xeed615f4, 0x6b0f8329, 0x847cf4ba, 0x01a56267, 0xcfc9a8da, + 0x4a103e07, 0x12164d7a, 0x97cfdba7, 0x59a3111a, 0xdc7a87c7, + 0xe9aff7e0, 0x6c76613d, 0xa21aab80, 0x27c33d5d, 0x7fc54e20, + 0xfa1cd8fd, 0x34701240, 0xb1a9849d, 0x17256aa0, 0x92fcfc7d, + 0x5c9036c0, 0xd949a01d, 0x814fd360, 0x049645bd, 0xcafa8f00, + 0x4f2319dd, 0x7af669fa, 0xff2fff27, 0x3143359a, 0xb49aa347, + 0xec9cd03a, 0x694546e7, 0xa7298c5a, 0x22f01a87, 0xcd836d14, + 0x485afbc9, 0x86363174, 0x03efa7a9, 0x5be9d4d4, 0xde304209, + 0x105c88b4, 0x95851e69, 0xa0506e4e, 0x2589f893, 0xebe5322e, + 0x6e3ca4f3, 0x363ad78e, 0xb3e34153, 0x7d8f8bee, 0xf8561d33, + 0xe26e1413, 0x67b782ce, 0xa9db4873, 0x2c02deae, 0x7404add3, + 0xf1dd3b0e, 0x3fb1f1b3, 0xba68676e, 0x8fbd1749, 0x0a648194, + 0xc4084b29, 0x41d1ddf4, 0x19d7ae89, 0x9c0e3854, 0x5262f2e9, + 0xd7bb6434, 0x38c813a7, 0xbd11857a, 0x737d4fc7, 0xf6a4d91a, + 0xaea2aa67, 0x2b7b3cba, 0xe517f607, 0x60ce60da, 0x551b10fd, + 0xd0c28620, 0x1eae4c9d, 0x9b77da40, 0xc371a93d, 0x46a83fe0, + 0x88c4f55d, 0x0d1d6380, 0xbcb4e71d, 0x396d71c0, 0xf701bb7d, + 0x72d82da0, 0x2ade5edd, 0xaf07c800, 0x616b02bd, 0xe4b29460, + 0xd167e447, 0x54be729a, 0x9ad2b827, 0x1f0b2efa, 0x470d5d87, + 0xc2d4cb5a, 0x0cb801e7, 0x8961973a, 0x6612e0a9, 0xe3cb7674, + 0x2da7bcc9, 0xa87e2a14, 0xf0785969, 0x75a1cfb4, 0xbbcd0509, + 0x3e1493d4, 0x0bc1e3f3, 0x8e18752e, 0x4074bf93, 0xc5ad294e, + 0x9dab5a33, 0x1872ccee, 0xd61e0653, 0x53c7908e, 0x49ff99ae, + 0xcc260f73, 0x024ac5ce, 0x87935313, 0xdf95206e, 0x5a4cb6b3, + 0x94207c0e, 0x11f9ead3, 0x242c9af4, 0xa1f50c29, 0x6f99c694, + 0xea405049, 0xb2462334, 0x379fb5e9, 0xf9f37f54, 0x7c2ae989, + 0x93599e1a, 0x168008c7, 0xd8ecc27a, 0x5d3554a7, 0x053327da, + 0x80eab107, 0x4e867bba, 0xcb5fed67, 0xfe8a9d40, 0x7b530b9d, + 0xb53fc120, 0x30e657fd, 0x68e02480, 0xed39b25d, 0x235578e0, + 0xa68cee3d}, + {0x00000000, 0x76e10f9d, 0xadc46ee1, 0xdb25617c, 0x1b8fac19, + 0x6d6ea384, 0xb64bc2f8, 0xc0aacd65, 0x361e5933, 0x40ff56ae, + 0x9bda37d2, 0xed3b384f, 0x2d91f52a, 0x5b70fab7, 0x80559bcb, + 0xf6b49456, 0x6c3cb266, 0x1addbdfb, 0xc1f8dc87, 0xb719d31a, + 0x77b31e7f, 0x015211e2, 0xda77709e, 0xac967f03, 0x5a22eb55, + 0x2cc3e4c8, 0xf7e685b4, 0x81078a29, 0x41ad474c, 0x374c48d1, + 0xec6929ad, 0x9a882630, 0xd87864cd, 0xae996b50, 0x75bc0a2c, + 0x035d05b1, 0xc3f7c8d4, 0xb516c749, 0x6e33a635, 0x18d2a9a8, + 0xee663dfe, 0x98873263, 0x43a2531f, 0x35435c82, 0xf5e991e7, + 0x83089e7a, 0x582dff06, 0x2eccf09b, 0xb444d6ab, 0xc2a5d936, + 0x1980b84a, 0x6f61b7d7, 0xafcb7ab2, 0xd92a752f, 0x020f1453, + 0x74ee1bce, 0x825a8f98, 0xf4bb8005, 0x2f9ee179, 0x597feee4, + 0x99d52381, 0xef342c1c, 0x34114d60, 0x42f042fd, 0xf1f7b941, + 0x8716b6dc, 0x5c33d7a0, 0x2ad2d83d, 0xea781558, 0x9c991ac5, + 0x47bc7bb9, 0x315d7424, 0xc7e9e072, 0xb108efef, 0x6a2d8e93, + 0x1ccc810e, 0xdc664c6b, 0xaa8743f6, 0x71a2228a, 0x07432d17, + 0x9dcb0b27, 0xeb2a04ba, 0x300f65c6, 0x46ee6a5b, 0x8644a73e, + 0xf0a5a8a3, 0x2b80c9df, 0x5d61c642, 0xabd55214, 0xdd345d89, + 0x06113cf5, 0x70f03368, 0xb05afe0d, 0xc6bbf190, 0x1d9e90ec, + 0x6b7f9f71, 0x298fdd8c, 0x5f6ed211, 0x844bb36d, 0xf2aabcf0, + 0x32007195, 0x44e17e08, 0x9fc41f74, 0xe92510e9, 0x1f9184bf, + 0x69708b22, 0xb255ea5e, 0xc4b4e5c3, 0x041e28a6, 0x72ff273b, + 0xa9da4647, 0xdf3b49da, 0x45b36fea, 0x33526077, 0xe877010b, + 0x9e960e96, 0x5e3cc3f3, 0x28ddcc6e, 0xf3f8ad12, 0x8519a28f, + 0x73ad36d9, 0x054c3944, 0xde695838, 0xa88857a5, 0x68229ac0, + 0x1ec3955d, 0xc5e6f421, 0xb307fbbc, 0xe2ef7383, 0x940e7c1e, + 0x4f2b1d62, 0x39ca12ff, 0xf960df9a, 0x8f81d007, 0x54a4b17b, + 0x2245bee6, 0xd4f12ab0, 0xa210252d, 0x79354451, 0x0fd44bcc, + 0xcf7e86a9, 0xb99f8934, 0x62bae848, 0x145be7d5, 0x8ed3c1e5, + 0xf832ce78, 0x2317af04, 0x55f6a099, 0x955c6dfc, 0xe3bd6261, + 0x3898031d, 0x4e790c80, 0xb8cd98d6, 0xce2c974b, 0x1509f637, + 0x63e8f9aa, 0xa34234cf, 0xd5a33b52, 0x0e865a2e, 0x786755b3, + 0x3a97174e, 0x4c7618d3, 0x975379af, 0xe1b27632, 0x2118bb57, + 0x57f9b4ca, 0x8cdcd5b6, 0xfa3dda2b, 0x0c894e7d, 0x7a6841e0, + 0xa14d209c, 0xd7ac2f01, 0x1706e264, 0x61e7edf9, 0xbac28c85, + 0xcc238318, 0x56aba528, 0x204aaab5, 0xfb6fcbc9, 0x8d8ec454, + 0x4d240931, 0x3bc506ac, 0xe0e067d0, 0x9601684d, 0x60b5fc1b, + 0x1654f386, 0xcd7192fa, 0xbb909d67, 0x7b3a5002, 0x0ddb5f9f, + 0xd6fe3ee3, 0xa01f317e, 0x1318cac2, 0x65f9c55f, 0xbedca423, + 0xc83dabbe, 0x089766db, 0x7e766946, 0xa553083a, 0xd3b207a7, + 0x250693f1, 0x53e79c6c, 0x88c2fd10, 0xfe23f28d, 0x3e893fe8, + 0x48683075, 0x934d5109, 0xe5ac5e94, 0x7f2478a4, 0x09c57739, + 0xd2e01645, 0xa40119d8, 0x64abd4bd, 0x124adb20, 0xc96fba5c, + 0xbf8eb5c1, 0x493a2197, 0x3fdb2e0a, 0xe4fe4f76, 0x921f40eb, + 0x52b58d8e, 0x24548213, 0xff71e36f, 0x8990ecf2, 0xcb60ae0f, + 0xbd81a192, 0x66a4c0ee, 0x1045cf73, 0xd0ef0216, 0xa60e0d8b, + 0x7d2b6cf7, 0x0bca636a, 0xfd7ef73c, 0x8b9ff8a1, 0x50ba99dd, + 0x265b9640, 0xe6f15b25, 0x901054b8, 0x4b3535c4, 0x3dd43a59, + 0xa75c1c69, 0xd1bd13f4, 0x0a987288, 0x7c797d15, 0xbcd3b070, + 0xca32bfed, 0x1117de91, 0x67f6d10c, 0x9142455a, 0xe7a34ac7, + 0x3c862bbb, 0x4a672426, 0x8acde943, 0xfc2ce6de, 0x270987a2, + 0x51e8883f}, + {0x00000000, 0xe8dbfbb9, 0x91b186a8, 0x796a7d11, 0x63657c8a, + 0x8bbe8733, 0xf2d4fa22, 0x1a0f019b, 0x87cc89cf, 0x6f177276, + 0x167d0f67, 0xfea6f4de, 0xe4a9f545, 0x0c720efc, 0x751873ed, + 0x9dc38854, 0x4f9f6244, 0xa74499fd, 0xde2ee4ec, 0x36f51f55, + 0x2cfa1ece, 0xc421e577, 0xbd4b9866, 0x559063df, 0xc853eb8b, + 0x20881032, 0x59e26d23, 0xb139969a, 0xab369701, 0x43ed6cb8, + 0x3a8711a9, 0xd25cea10, 0x9e3ec588, 0x76e53e31, 0x0f8f4320, + 0xe754b899, 0xfd5bb902, 0x158042bb, 0x6cea3faa, 0x8431c413, + 0x19f24c47, 0xf129b7fe, 0x8843caef, 0x60983156, 0x7a9730cd, + 0x924ccb74, 0xeb26b665, 0x03fd4ddc, 0xd1a1a7cc, 0x397a5c75, + 0x40102164, 0xa8cbdadd, 0xb2c4db46, 0x5a1f20ff, 0x23755dee, + 0xcbaea657, 0x566d2e03, 0xbeb6d5ba, 0xc7dca8ab, 0x2f075312, + 0x35085289, 0xddd3a930, 0xa4b9d421, 0x4c622f98, 0x7d7bfbca, + 0x95a00073, 0xecca7d62, 0x041186db, 0x1e1e8740, 0xf6c57cf9, + 0x8faf01e8, 0x6774fa51, 0xfab77205, 0x126c89bc, 0x6b06f4ad, + 0x83dd0f14, 0x99d20e8f, 0x7109f536, 0x08638827, 0xe0b8739e, + 0x32e4998e, 0xda3f6237, 0xa3551f26, 0x4b8ee49f, 0x5181e504, + 0xb95a1ebd, 0xc03063ac, 0x28eb9815, 0xb5281041, 0x5df3ebf8, + 0x249996e9, 0xcc426d50, 0xd64d6ccb, 0x3e969772, 0x47fcea63, + 0xaf2711da, 0xe3453e42, 0x0b9ec5fb, 0x72f4b8ea, 0x9a2f4353, + 0x802042c8, 0x68fbb971, 0x1191c460, 0xf94a3fd9, 0x6489b78d, + 0x8c524c34, 0xf5383125, 0x1de3ca9c, 0x07eccb07, 0xef3730be, + 0x965d4daf, 0x7e86b616, 0xacda5c06, 0x4401a7bf, 0x3d6bdaae, + 0xd5b02117, 0xcfbf208c, 0x2764db35, 0x5e0ea624, 0xb6d55d9d, + 0x2b16d5c9, 0xc3cd2e70, 0xbaa75361, 0x527ca8d8, 0x4873a943, + 0xa0a852fa, 0xd9c22feb, 0x3119d452, 0xbbf0874e, 0x532b7cf7, + 0x2a4101e6, 0xc29afa5f, 0xd895fbc4, 0x304e007d, 0x49247d6c, + 0xa1ff86d5, 0x3c3c0e81, 0xd4e7f538, 0xad8d8829, 0x45567390, + 0x5f59720b, 0xb78289b2, 0xcee8f4a3, 0x26330f1a, 0xf46fe50a, + 0x1cb41eb3, 0x65de63a2, 0x8d05981b, 0x970a9980, 0x7fd16239, + 0x06bb1f28, 0xee60e491, 0x73a36cc5, 0x9b78977c, 0xe212ea6d, + 0x0ac911d4, 0x10c6104f, 0xf81debf6, 0x817796e7, 0x69ac6d5e, + 0x25ce42c6, 0xcd15b97f, 0xb47fc46e, 0x5ca43fd7, 0x46ab3e4c, + 0xae70c5f5, 0xd71ab8e4, 0x3fc1435d, 0xa202cb09, 0x4ad930b0, + 0x33b34da1, 0xdb68b618, 0xc167b783, 0x29bc4c3a, 0x50d6312b, + 0xb80dca92, 0x6a512082, 0x828adb3b, 0xfbe0a62a, 0x133b5d93, + 0x09345c08, 0xe1efa7b1, 0x9885daa0, 0x705e2119, 0xed9da94d, + 0x054652f4, 0x7c2c2fe5, 0x94f7d45c, 0x8ef8d5c7, 0x66232e7e, + 0x1f49536f, 0xf792a8d6, 0xc68b7c84, 0x2e50873d, 0x573afa2c, + 0xbfe10195, 0xa5ee000e, 0x4d35fbb7, 0x345f86a6, 0xdc847d1f, + 0x4147f54b, 0xa99c0ef2, 0xd0f673e3, 0x382d885a, 0x222289c1, + 0xcaf97278, 0xb3930f69, 0x5b48f4d0, 0x89141ec0, 0x61cfe579, + 0x18a59868, 0xf07e63d1, 0xea71624a, 0x02aa99f3, 0x7bc0e4e2, + 0x931b1f5b, 0x0ed8970f, 0xe6036cb6, 0x9f6911a7, 0x77b2ea1e, + 0x6dbdeb85, 0x8566103c, 0xfc0c6d2d, 0x14d79694, 0x58b5b90c, + 0xb06e42b5, 0xc9043fa4, 0x21dfc41d, 0x3bd0c586, 0xd30b3e3f, + 0xaa61432e, 0x42bab897, 0xdf7930c3, 0x37a2cb7a, 0x4ec8b66b, + 0xa6134dd2, 0xbc1c4c49, 0x54c7b7f0, 0x2dadcae1, 0xc5763158, + 0x172adb48, 0xfff120f1, 0x869b5de0, 0x6e40a659, 0x744fa7c2, + 0x9c945c7b, 0xe5fe216a, 0x0d25dad3, 0x90e65287, 0x783da93e, + 0x0157d42f, 0xe98c2f96, 0xf3832e0d, 0x1b58d5b4, 0x6232a8a5, + 0x8ae9531c}, + {0x00000000, 0x919168ae, 0x6325a087, 0xf2b4c829, 0x874c31d4, + 0x16dd597a, 0xe4699153, 0x75f8f9fd, 0x4f9f1373, 0xde0e7bdd, + 0x2cbab3f4, 0xbd2bdb5a, 0xc8d322a7, 0x59424a09, 0xabf68220, + 0x3a67ea8e, 0x9e3e27e6, 0x0faf4f48, 0xfd1b8761, 0x6c8aefcf, + 0x19721632, 0x88e37e9c, 0x7a57b6b5, 0xebc6de1b, 0xd1a13495, + 0x40305c3b, 0xb2849412, 0x2315fcbc, 0x56ed0541, 0xc77c6def, + 0x35c8a5c6, 0xa459cd68, 0x7d7b3f17, 0xecea57b9, 0x1e5e9f90, + 0x8fcff73e, 0xfa370ec3, 0x6ba6666d, 0x9912ae44, 0x0883c6ea, + 0x32e42c64, 0xa37544ca, 0x51c18ce3, 0xc050e44d, 0xb5a81db0, + 0x2439751e, 0xd68dbd37, 0x471cd599, 0xe34518f1, 0x72d4705f, + 0x8060b876, 0x11f1d0d8, 0x64092925, 0xf598418b, 0x072c89a2, + 0x96bde10c, 0xacda0b82, 0x3d4b632c, 0xcfffab05, 0x5e6ec3ab, + 0x2b963a56, 0xba0752f8, 0x48b39ad1, 0xd922f27f, 0xfaf67e2e, + 0x6b671680, 0x99d3dea9, 0x0842b607, 0x7dba4ffa, 0xec2b2754, + 0x1e9fef7d, 0x8f0e87d3, 0xb5696d5d, 0x24f805f3, 0xd64ccdda, + 0x47dda574, 0x32255c89, 0xa3b43427, 0x5100fc0e, 0xc09194a0, + 0x64c859c8, 0xf5593166, 0x07edf94f, 0x967c91e1, 0xe384681c, + 0x721500b2, 0x80a1c89b, 0x1130a035, 0x2b574abb, 0xbac62215, + 0x4872ea3c, 0xd9e38292, 0xac1b7b6f, 0x3d8a13c1, 0xcf3edbe8, + 0x5eafb346, 0x878d4139, 0x161c2997, 0xe4a8e1be, 0x75398910, + 0x00c170ed, 0x91501843, 0x63e4d06a, 0xf275b8c4, 0xc812524a, + 0x59833ae4, 0xab37f2cd, 0x3aa69a63, 0x4f5e639e, 0xdecf0b30, + 0x2c7bc319, 0xbdeaabb7, 0x19b366df, 0x88220e71, 0x7a96c658, + 0xeb07aef6, 0x9eff570b, 0x0f6e3fa5, 0xfddaf78c, 0x6c4b9f22, + 0x562c75ac, 0xc7bd1d02, 0x3509d52b, 0xa498bd85, 0xd1604478, + 0x40f12cd6, 0xb245e4ff, 0x23d48c51, 0xf4edfd5c, 0x657c95f2, + 0x97c85ddb, 0x06593575, 0x73a1cc88, 0xe230a426, 0x10846c0f, + 0x811504a1, 0xbb72ee2f, 0x2ae38681, 0xd8574ea8, 0x49c62606, + 0x3c3edffb, 0xadafb755, 0x5f1b7f7c, 0xce8a17d2, 0x6ad3daba, + 0xfb42b214, 0x09f67a3d, 0x98671293, 0xed9feb6e, 0x7c0e83c0, + 0x8eba4be9, 0x1f2b2347, 0x254cc9c9, 0xb4dda167, 0x4669694e, + 0xd7f801e0, 0xa200f81d, 0x339190b3, 0xc125589a, 0x50b43034, + 0x8996c24b, 0x1807aae5, 0xeab362cc, 0x7b220a62, 0x0edaf39f, + 0x9f4b9b31, 0x6dff5318, 0xfc6e3bb6, 0xc609d138, 0x5798b996, + 0xa52c71bf, 0x34bd1911, 0x4145e0ec, 0xd0d48842, 0x2260406b, + 0xb3f128c5, 0x17a8e5ad, 0x86398d03, 0x748d452a, 0xe51c2d84, + 0x90e4d479, 0x0175bcd7, 0xf3c174fe, 0x62501c50, 0x5837f6de, + 0xc9a69e70, 0x3b125659, 0xaa833ef7, 0xdf7bc70a, 0x4eeaafa4, + 0xbc5e678d, 0x2dcf0f23, 0x0e1b8372, 0x9f8aebdc, 0x6d3e23f5, + 0xfcaf4b5b, 0x8957b2a6, 0x18c6da08, 0xea721221, 0x7be37a8f, + 0x41849001, 0xd015f8af, 0x22a13086, 0xb3305828, 0xc6c8a1d5, + 0x5759c97b, 0xa5ed0152, 0x347c69fc, 0x9025a494, 0x01b4cc3a, + 0xf3000413, 0x62916cbd, 0x17699540, 0x86f8fdee, 0x744c35c7, + 0xe5dd5d69, 0xdfbab7e7, 0x4e2bdf49, 0xbc9f1760, 0x2d0e7fce, + 0x58f68633, 0xc967ee9d, 0x3bd326b4, 0xaa424e1a, 0x7360bc65, + 0xe2f1d4cb, 0x10451ce2, 0x81d4744c, 0xf42c8db1, 0x65bde51f, + 0x97092d36, 0x06984598, 0x3cffaf16, 0xad6ec7b8, 0x5fda0f91, + 0xce4b673f, 0xbbb39ec2, 0x2a22f66c, 0xd8963e45, 0x490756eb, + 0xed5e9b83, 0x7ccff32d, 0x8e7b3b04, 0x1fea53aa, 0x6a12aa57, + 0xfb83c2f9, 0x09370ad0, 0x98a6627e, 0xa2c188f0, 0x3350e05e, + 0xc1e42877, 0x507540d9, 0x258db924, 0xb41cd18a, 0x46a819a3, + 0xd739710d}}; + +#endif /* W */ + +#endif /* N == 4 */ +#if N == 5 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0xaf449247, 0x85f822cf, 0x2abcb088, 0xd08143df, + 0x7fc5d198, 0x55796110, 0xfa3df357, 0x7a7381ff, 0xd53713b8, + 0xff8ba330, 0x50cf3177, 0xaaf2c220, 0x05b65067, 0x2f0ae0ef, + 0x804e72a8, 0xf4e703fe, 0x5ba391b9, 0x711f2131, 0xde5bb376, + 0x24664021, 0x8b22d266, 0xa19e62ee, 0x0edaf0a9, 0x8e948201, + 0x21d01046, 0x0b6ca0ce, 0xa4283289, 0x5e15c1de, 0xf1515399, + 0xdbede311, 0x74a97156, 0x32bf01bd, 0x9dfb93fa, 0xb7472372, + 0x1803b135, 0xe23e4262, 0x4d7ad025, 0x67c660ad, 0xc882f2ea, + 0x48cc8042, 0xe7881205, 0xcd34a28d, 0x627030ca, 0x984dc39d, + 0x370951da, 0x1db5e152, 0xb2f17315, 0xc6580243, 0x691c9004, + 0x43a0208c, 0xece4b2cb, 0x16d9419c, 0xb99dd3db, 0x93216353, + 0x3c65f114, 0xbc2b83bc, 0x136f11fb, 0x39d3a173, 0x96973334, + 0x6caac063, 0xc3ee5224, 0xe952e2ac, 0x461670eb, 0x657e037a, + 0xca3a913d, 0xe08621b5, 0x4fc2b3f2, 0xb5ff40a5, 0x1abbd2e2, + 0x3007626a, 0x9f43f02d, 0x1f0d8285, 0xb04910c2, 0x9af5a04a, + 0x35b1320d, 0xcf8cc15a, 0x60c8531d, 0x4a74e395, 0xe53071d2, + 0x91990084, 0x3edd92c3, 0x1461224b, 0xbb25b00c, 0x4118435b, + 0xee5cd11c, 0xc4e06194, 0x6ba4f3d3, 0xebea817b, 0x44ae133c, + 0x6e12a3b4, 0xc15631f3, 0x3b6bc2a4, 0x942f50e3, 0xbe93e06b, + 0x11d7722c, 0x57c102c7, 0xf8859080, 0xd2392008, 0x7d7db24f, + 0x87404118, 0x2804d35f, 0x02b863d7, 0xadfcf190, 0x2db28338, + 0x82f6117f, 0xa84aa1f7, 0x070e33b0, 0xfd33c0e7, 0x527752a0, + 0x78cbe228, 0xd78f706f, 0xa3260139, 0x0c62937e, 0x26de23f6, + 0x899ab1b1, 0x73a742e6, 0xdce3d0a1, 0xf65f6029, 0x591bf26e, + 0xd95580c6, 0x76111281, 0x5cada209, 0xf3e9304e, 0x09d4c319, + 0xa690515e, 0x8c2ce1d6, 0x23687391, 0xcafc06f4, 0x65b894b3, + 0x4f04243b, 0xe040b67c, 0x1a7d452b, 0xb539d76c, 0x9f8567e4, + 0x30c1f5a3, 0xb08f870b, 0x1fcb154c, 0x3577a5c4, 0x9a333783, + 0x600ec4d4, 0xcf4a5693, 0xe5f6e61b, 0x4ab2745c, 0x3e1b050a, + 0x915f974d, 0xbbe327c5, 0x14a7b582, 0xee9a46d5, 0x41ded492, + 0x6b62641a, 0xc426f65d, 0x446884f5, 0xeb2c16b2, 0xc190a63a, + 0x6ed4347d, 0x94e9c72a, 0x3bad556d, 0x1111e5e5, 0xbe5577a2, + 0xf8430749, 0x5707950e, 0x7dbb2586, 0xd2ffb7c1, 0x28c24496, + 0x8786d6d1, 0xad3a6659, 0x027ef41e, 0x823086b6, 0x2d7414f1, + 0x07c8a479, 0xa88c363e, 0x52b1c569, 0xfdf5572e, 0xd749e7a6, + 0x780d75e1, 0x0ca404b7, 0xa3e096f0, 0x895c2678, 0x2618b43f, + 0xdc254768, 0x7361d52f, 0x59dd65a7, 0xf699f7e0, 0x76d78548, + 0xd993170f, 0xf32fa787, 0x5c6b35c0, 0xa656c697, 0x091254d0, + 0x23aee458, 0x8cea761f, 0xaf82058e, 0x00c697c9, 0x2a7a2741, + 0x853eb506, 0x7f034651, 0xd047d416, 0xfafb649e, 0x55bff6d9, + 0xd5f18471, 0x7ab51636, 0x5009a6be, 0xff4d34f9, 0x0570c7ae, + 0xaa3455e9, 0x8088e561, 0x2fcc7726, 0x5b650670, 0xf4219437, + 0xde9d24bf, 0x71d9b6f8, 0x8be445af, 0x24a0d7e8, 0x0e1c6760, + 0xa158f527, 0x2116878f, 0x8e5215c8, 0xa4eea540, 0x0baa3707, + 0xf197c450, 0x5ed35617, 0x746fe69f, 0xdb2b74d8, 0x9d3d0433, + 0x32799674, 0x18c526fc, 0xb781b4bb, 0x4dbc47ec, 0xe2f8d5ab, + 0xc8446523, 0x6700f764, 0xe74e85cc, 0x480a178b, 0x62b6a703, + 0xcdf23544, 0x37cfc613, 0x988b5454, 0xb237e4dc, 0x1d73769b, + 0x69da07cd, 0xc69e958a, 0xec222502, 0x4366b745, 0xb95b4412, + 0x161fd655, 0x3ca366dd, 0x93e7f49a, 0x13a98632, 0xbced1475, + 0x9651a4fd, 0x391536ba, 0xc328c5ed, 0x6c6c57aa, 0x46d0e722, + 0xe9947565}, + {0x00000000, 0x4e890ba9, 0x9d121752, 0xd39b1cfb, 0xe15528e5, + 0xafdc234c, 0x7c473fb7, 0x32ce341e, 0x19db578b, 0x57525c22, + 0x84c940d9, 0xca404b70, 0xf88e7f6e, 0xb60774c7, 0x659c683c, + 0x2b156395, 0x33b6af16, 0x7d3fa4bf, 0xaea4b844, 0xe02db3ed, + 0xd2e387f3, 0x9c6a8c5a, 0x4ff190a1, 0x01789b08, 0x2a6df89d, + 0x64e4f334, 0xb77fefcf, 0xf9f6e466, 0xcb38d078, 0x85b1dbd1, + 0x562ac72a, 0x18a3cc83, 0x676d5e2c, 0x29e45585, 0xfa7f497e, + 0xb4f642d7, 0x863876c9, 0xc8b17d60, 0x1b2a619b, 0x55a36a32, + 0x7eb609a7, 0x303f020e, 0xe3a41ef5, 0xad2d155c, 0x9fe32142, + 0xd16a2aeb, 0x02f13610, 0x4c783db9, 0x54dbf13a, 0x1a52fa93, + 0xc9c9e668, 0x8740edc1, 0xb58ed9df, 0xfb07d276, 0x289cce8d, + 0x6615c524, 0x4d00a6b1, 0x0389ad18, 0xd012b1e3, 0x9e9bba4a, + 0xac558e54, 0xe2dc85fd, 0x31479906, 0x7fce92af, 0xcedabc58, + 0x8053b7f1, 0x53c8ab0a, 0x1d41a0a3, 0x2f8f94bd, 0x61069f14, + 0xb29d83ef, 0xfc148846, 0xd701ebd3, 0x9988e07a, 0x4a13fc81, + 0x049af728, 0x3654c336, 0x78ddc89f, 0xab46d464, 0xe5cfdfcd, + 0xfd6c134e, 0xb3e518e7, 0x607e041c, 0x2ef70fb5, 0x1c393bab, + 0x52b03002, 0x812b2cf9, 0xcfa22750, 0xe4b744c5, 0xaa3e4f6c, + 0x79a55397, 0x372c583e, 0x05e26c20, 0x4b6b6789, 0x98f07b72, + 0xd67970db, 0xa9b7e274, 0xe73ee9dd, 0x34a5f526, 0x7a2cfe8f, + 0x48e2ca91, 0x066bc138, 0xd5f0ddc3, 0x9b79d66a, 0xb06cb5ff, + 0xfee5be56, 0x2d7ea2ad, 0x63f7a904, 0x51399d1a, 0x1fb096b3, + 0xcc2b8a48, 0x82a281e1, 0x9a014d62, 0xd48846cb, 0x07135a30, + 0x499a5199, 0x7b546587, 0x35dd6e2e, 0xe64672d5, 0xa8cf797c, + 0x83da1ae9, 0xcd531140, 0x1ec80dbb, 0x50410612, 0x628f320c, + 0x2c0639a5, 0xff9d255e, 0xb1142ef7, 0x46c47ef1, 0x084d7558, + 0xdbd669a3, 0x955f620a, 0xa7915614, 0xe9185dbd, 0x3a834146, + 0x740a4aef, 0x5f1f297a, 0x119622d3, 0xc20d3e28, 0x8c843581, + 0xbe4a019f, 0xf0c30a36, 0x235816cd, 0x6dd11d64, 0x7572d1e7, + 0x3bfbda4e, 0xe860c6b5, 0xa6e9cd1c, 0x9427f902, 0xdaaef2ab, + 0x0935ee50, 0x47bce5f9, 0x6ca9866c, 0x22208dc5, 0xf1bb913e, + 0xbf329a97, 0x8dfcae89, 0xc375a520, 0x10eeb9db, 0x5e67b272, + 0x21a920dd, 0x6f202b74, 0xbcbb378f, 0xf2323c26, 0xc0fc0838, + 0x8e750391, 0x5dee1f6a, 0x136714c3, 0x38727756, 0x76fb7cff, + 0xa5606004, 0xebe96bad, 0xd9275fb3, 0x97ae541a, 0x443548e1, + 0x0abc4348, 0x121f8fcb, 0x5c968462, 0x8f0d9899, 0xc1849330, + 0xf34aa72e, 0xbdc3ac87, 0x6e58b07c, 0x20d1bbd5, 0x0bc4d840, + 0x454dd3e9, 0x96d6cf12, 0xd85fc4bb, 0xea91f0a5, 0xa418fb0c, + 0x7783e7f7, 0x390aec5e, 0x881ec2a9, 0xc697c900, 0x150cd5fb, + 0x5b85de52, 0x694bea4c, 0x27c2e1e5, 0xf459fd1e, 0xbad0f6b7, + 0x91c59522, 0xdf4c9e8b, 0x0cd78270, 0x425e89d9, 0x7090bdc7, + 0x3e19b66e, 0xed82aa95, 0xa30ba13c, 0xbba86dbf, 0xf5216616, + 0x26ba7aed, 0x68337144, 0x5afd455a, 0x14744ef3, 0xc7ef5208, + 0x896659a1, 0xa2733a34, 0xecfa319d, 0x3f612d66, 0x71e826cf, + 0x432612d1, 0x0daf1978, 0xde340583, 0x90bd0e2a, 0xef739c85, + 0xa1fa972c, 0x72618bd7, 0x3ce8807e, 0x0e26b460, 0x40afbfc9, + 0x9334a332, 0xddbda89b, 0xf6a8cb0e, 0xb821c0a7, 0x6bbadc5c, + 0x2533d7f5, 0x17fde3eb, 0x5974e842, 0x8aeff4b9, 0xc466ff10, + 0xdcc53393, 0x924c383a, 0x41d724c1, 0x0f5e2f68, 0x3d901b76, + 0x731910df, 0xa0820c24, 0xee0b078d, 0xc51e6418, 0x8b976fb1, + 0x580c734a, 0x168578e3, 0x244b4cfd, 0x6ac24754, 0xb9595baf, + 0xf7d05006}, + {0x00000000, 0x8d88fde2, 0xc060fd85, 0x4de80067, 0x5bb0fd4b, + 0xd63800a9, 0x9bd000ce, 0x1658fd2c, 0xb761fa96, 0x3ae90774, + 0x77010713, 0xfa89faf1, 0xecd107dd, 0x6159fa3f, 0x2cb1fa58, + 0xa13907ba, 0xb5b2f36d, 0x383a0e8f, 0x75d20ee8, 0xf85af30a, + 0xee020e26, 0x638af3c4, 0x2e62f3a3, 0xa3ea0e41, 0x02d309fb, + 0x8f5bf419, 0xc2b3f47e, 0x4f3b099c, 0x5963f4b0, 0xd4eb0952, + 0x99030935, 0x148bf4d7, 0xb014e09b, 0x3d9c1d79, 0x70741d1e, + 0xfdfce0fc, 0xeba41dd0, 0x662ce032, 0x2bc4e055, 0xa64c1db7, + 0x07751a0d, 0x8afde7ef, 0xc715e788, 0x4a9d1a6a, 0x5cc5e746, + 0xd14d1aa4, 0x9ca51ac3, 0x112de721, 0x05a613f6, 0x882eee14, + 0xc5c6ee73, 0x484e1391, 0x5e16eebd, 0xd39e135f, 0x9e761338, + 0x13feeeda, 0xb2c7e960, 0x3f4f1482, 0x72a714e5, 0xff2fe907, + 0xe977142b, 0x64ffe9c9, 0x2917e9ae, 0xa49f144c, 0xbb58c777, + 0x36d03a95, 0x7b383af2, 0xf6b0c710, 0xe0e83a3c, 0x6d60c7de, + 0x2088c7b9, 0xad003a5b, 0x0c393de1, 0x81b1c003, 0xcc59c064, + 0x41d13d86, 0x5789c0aa, 0xda013d48, 0x97e93d2f, 0x1a61c0cd, + 0x0eea341a, 0x8362c9f8, 0xce8ac99f, 0x4302347d, 0x555ac951, + 0xd8d234b3, 0x953a34d4, 0x18b2c936, 0xb98bce8c, 0x3403336e, + 0x79eb3309, 0xf463ceeb, 0xe23b33c7, 0x6fb3ce25, 0x225bce42, + 0xafd333a0, 0x0b4c27ec, 0x86c4da0e, 0xcb2cda69, 0x46a4278b, + 0x50fcdaa7, 0xdd742745, 0x909c2722, 0x1d14dac0, 0xbc2ddd7a, + 0x31a52098, 0x7c4d20ff, 0xf1c5dd1d, 0xe79d2031, 0x6a15ddd3, + 0x27fdddb4, 0xaa752056, 0xbefed481, 0x33762963, 0x7e9e2904, + 0xf316d4e6, 0xe54e29ca, 0x68c6d428, 0x252ed44f, 0xa8a629ad, + 0x099f2e17, 0x8417d3f5, 0xc9ffd392, 0x44772e70, 0x522fd35c, + 0xdfa72ebe, 0x924f2ed9, 0x1fc7d33b, 0xadc088af, 0x2048754d, + 0x6da0752a, 0xe02888c8, 0xf67075e4, 0x7bf88806, 0x36108861, + 0xbb987583, 0x1aa17239, 0x97298fdb, 0xdac18fbc, 0x5749725e, + 0x41118f72, 0xcc997290, 0x817172f7, 0x0cf98f15, 0x18727bc2, + 0x95fa8620, 0xd8128647, 0x559a7ba5, 0x43c28689, 0xce4a7b6b, + 0x83a27b0c, 0x0e2a86ee, 0xaf138154, 0x229b7cb6, 0x6f737cd1, + 0xe2fb8133, 0xf4a37c1f, 0x792b81fd, 0x34c3819a, 0xb94b7c78, + 0x1dd46834, 0x905c95d6, 0xddb495b1, 0x503c6853, 0x4664957f, + 0xcbec689d, 0x860468fa, 0x0b8c9518, 0xaab592a2, 0x273d6f40, + 0x6ad56f27, 0xe75d92c5, 0xf1056fe9, 0x7c8d920b, 0x3165926c, + 0xbced6f8e, 0xa8669b59, 0x25ee66bb, 0x680666dc, 0xe58e9b3e, + 0xf3d66612, 0x7e5e9bf0, 0x33b69b97, 0xbe3e6675, 0x1f0761cf, + 0x928f9c2d, 0xdf679c4a, 0x52ef61a8, 0x44b79c84, 0xc93f6166, + 0x84d76101, 0x095f9ce3, 0x16984fd8, 0x9b10b23a, 0xd6f8b25d, + 0x5b704fbf, 0x4d28b293, 0xc0a04f71, 0x8d484f16, 0x00c0b2f4, + 0xa1f9b54e, 0x2c7148ac, 0x619948cb, 0xec11b529, 0xfa494805, + 0x77c1b5e7, 0x3a29b580, 0xb7a14862, 0xa32abcb5, 0x2ea24157, + 0x634a4130, 0xeec2bcd2, 0xf89a41fe, 0x7512bc1c, 0x38fabc7b, + 0xb5724199, 0x144b4623, 0x99c3bbc1, 0xd42bbba6, 0x59a34644, + 0x4ffbbb68, 0xc273468a, 0x8f9b46ed, 0x0213bb0f, 0xa68caf43, + 0x2b0452a1, 0x66ec52c6, 0xeb64af24, 0xfd3c5208, 0x70b4afea, + 0x3d5caf8d, 0xb0d4526f, 0x11ed55d5, 0x9c65a837, 0xd18da850, + 0x5c0555b2, 0x4a5da89e, 0xc7d5557c, 0x8a3d551b, 0x07b5a8f9, + 0x133e5c2e, 0x9eb6a1cc, 0xd35ea1ab, 0x5ed65c49, 0x488ea165, + 0xc5065c87, 0x88ee5ce0, 0x0566a102, 0xa45fa6b8, 0x29d75b5a, + 0x643f5b3d, 0xe9b7a6df, 0xffef5bf3, 0x7267a611, 0x3f8fa676, + 0xb2075b94}, + {0x00000000, 0x80f0171f, 0xda91287f, 0x5a613f60, 0x6e5356bf, + 0xeea341a0, 0xb4c27ec0, 0x343269df, 0xdca6ad7e, 0x5c56ba61, + 0x06378501, 0x86c7921e, 0xb2f5fbc1, 0x3205ecde, 0x6864d3be, + 0xe894c4a1, 0x623c5cbd, 0xe2cc4ba2, 0xb8ad74c2, 0x385d63dd, + 0x0c6f0a02, 0x8c9f1d1d, 0xd6fe227d, 0x560e3562, 0xbe9af1c3, + 0x3e6ae6dc, 0x640bd9bc, 0xe4fbcea3, 0xd0c9a77c, 0x5039b063, + 0x0a588f03, 0x8aa8981c, 0xc478b97a, 0x4488ae65, 0x1ee99105, + 0x9e19861a, 0xaa2befc5, 0x2adbf8da, 0x70bac7ba, 0xf04ad0a5, + 0x18de1404, 0x982e031b, 0xc24f3c7b, 0x42bf2b64, 0x768d42bb, + 0xf67d55a4, 0xac1c6ac4, 0x2cec7ddb, 0xa644e5c7, 0x26b4f2d8, + 0x7cd5cdb8, 0xfc25daa7, 0xc817b378, 0x48e7a467, 0x12869b07, + 0x92768c18, 0x7ae248b9, 0xfa125fa6, 0xa07360c6, 0x208377d9, + 0x14b11e06, 0x94410919, 0xce203679, 0x4ed02166, 0x538074b5, + 0xd37063aa, 0x89115cca, 0x09e14bd5, 0x3dd3220a, 0xbd233515, + 0xe7420a75, 0x67b21d6a, 0x8f26d9cb, 0x0fd6ced4, 0x55b7f1b4, + 0xd547e6ab, 0xe1758f74, 0x6185986b, 0x3be4a70b, 0xbb14b014, + 0x31bc2808, 0xb14c3f17, 0xeb2d0077, 0x6bdd1768, 0x5fef7eb7, + 0xdf1f69a8, 0x857e56c8, 0x058e41d7, 0xed1a8576, 0x6dea9269, + 0x378bad09, 0xb77bba16, 0x8349d3c9, 0x03b9c4d6, 0x59d8fbb6, + 0xd928eca9, 0x97f8cdcf, 0x1708dad0, 0x4d69e5b0, 0xcd99f2af, + 0xf9ab9b70, 0x795b8c6f, 0x233ab30f, 0xa3caa410, 0x4b5e60b1, + 0xcbae77ae, 0x91cf48ce, 0x113f5fd1, 0x250d360e, 0xa5fd2111, + 0xff9c1e71, 0x7f6c096e, 0xf5c49172, 0x7534866d, 0x2f55b90d, + 0xafa5ae12, 0x9b97c7cd, 0x1b67d0d2, 0x4106efb2, 0xc1f6f8ad, + 0x29623c0c, 0xa9922b13, 0xf3f31473, 0x7303036c, 0x47316ab3, + 0xc7c17dac, 0x9da042cc, 0x1d5055d3, 0xa700e96a, 0x27f0fe75, + 0x7d91c115, 0xfd61d60a, 0xc953bfd5, 0x49a3a8ca, 0x13c297aa, + 0x933280b5, 0x7ba64414, 0xfb56530b, 0xa1376c6b, 0x21c77b74, + 0x15f512ab, 0x950505b4, 0xcf643ad4, 0x4f942dcb, 0xc53cb5d7, + 0x45cca2c8, 0x1fad9da8, 0x9f5d8ab7, 0xab6fe368, 0x2b9ff477, + 0x71fecb17, 0xf10edc08, 0x199a18a9, 0x996a0fb6, 0xc30b30d6, + 0x43fb27c9, 0x77c94e16, 0xf7395909, 0xad586669, 0x2da87176, + 0x63785010, 0xe388470f, 0xb9e9786f, 0x39196f70, 0x0d2b06af, + 0x8ddb11b0, 0xd7ba2ed0, 0x574a39cf, 0xbfdefd6e, 0x3f2eea71, + 0x654fd511, 0xe5bfc20e, 0xd18dabd1, 0x517dbcce, 0x0b1c83ae, + 0x8bec94b1, 0x01440cad, 0x81b41bb2, 0xdbd524d2, 0x5b2533cd, + 0x6f175a12, 0xefe74d0d, 0xb586726d, 0x35766572, 0xdde2a1d3, + 0x5d12b6cc, 0x077389ac, 0x87839eb3, 0xb3b1f76c, 0x3341e073, + 0x6920df13, 0xe9d0c80c, 0xf4809ddf, 0x74708ac0, 0x2e11b5a0, + 0xaee1a2bf, 0x9ad3cb60, 0x1a23dc7f, 0x4042e31f, 0xc0b2f400, + 0x282630a1, 0xa8d627be, 0xf2b718de, 0x72470fc1, 0x4675661e, + 0xc6857101, 0x9ce44e61, 0x1c14597e, 0x96bcc162, 0x164cd67d, + 0x4c2de91d, 0xccddfe02, 0xf8ef97dd, 0x781f80c2, 0x227ebfa2, + 0xa28ea8bd, 0x4a1a6c1c, 0xcaea7b03, 0x908b4463, 0x107b537c, + 0x24493aa3, 0xa4b92dbc, 0xfed812dc, 0x7e2805c3, 0x30f824a5, + 0xb00833ba, 0xea690cda, 0x6a991bc5, 0x5eab721a, 0xde5b6505, + 0x843a5a65, 0x04ca4d7a, 0xec5e89db, 0x6cae9ec4, 0x36cfa1a4, + 0xb63fb6bb, 0x820ddf64, 0x02fdc87b, 0x589cf71b, 0xd86ce004, + 0x52c47818, 0xd2346f07, 0x88555067, 0x08a54778, 0x3c972ea7, + 0xbc6739b8, 0xe60606d8, 0x66f611c7, 0x8e62d566, 0x0e92c279, + 0x54f3fd19, 0xd403ea06, 0xe03183d9, 0x60c194c6, 0x3aa0aba6, + 0xba50bcb9}, + {0x00000000, 0x9570d495, 0xf190af6b, 0x64e07bfe, 0x38505897, + 0xad208c02, 0xc9c0f7fc, 0x5cb02369, 0x70a0b12e, 0xe5d065bb, + 0x81301e45, 0x1440cad0, 0x48f0e9b9, 0xdd803d2c, 0xb96046d2, + 0x2c109247, 0xe141625c, 0x7431b6c9, 0x10d1cd37, 0x85a119a2, + 0xd9113acb, 0x4c61ee5e, 0x288195a0, 0xbdf14135, 0x91e1d372, + 0x049107e7, 0x60717c19, 0xf501a88c, 0xa9b18be5, 0x3cc15f70, + 0x5821248e, 0xcd51f01b, 0x19f3c2f9, 0x8c83166c, 0xe8636d92, + 0x7d13b907, 0x21a39a6e, 0xb4d34efb, 0xd0333505, 0x4543e190, + 0x695373d7, 0xfc23a742, 0x98c3dcbc, 0x0db30829, 0x51032b40, + 0xc473ffd5, 0xa093842b, 0x35e350be, 0xf8b2a0a5, 0x6dc27430, + 0x09220fce, 0x9c52db5b, 0xc0e2f832, 0x55922ca7, 0x31725759, + 0xa40283cc, 0x8812118b, 0x1d62c51e, 0x7982bee0, 0xecf26a75, + 0xb042491c, 0x25329d89, 0x41d2e677, 0xd4a232e2, 0x33e785f2, + 0xa6975167, 0xc2772a99, 0x5707fe0c, 0x0bb7dd65, 0x9ec709f0, + 0xfa27720e, 0x6f57a69b, 0x434734dc, 0xd637e049, 0xb2d79bb7, + 0x27a74f22, 0x7b176c4b, 0xee67b8de, 0x8a87c320, 0x1ff717b5, + 0xd2a6e7ae, 0x47d6333b, 0x233648c5, 0xb6469c50, 0xeaf6bf39, + 0x7f866bac, 0x1b661052, 0x8e16c4c7, 0xa2065680, 0x37768215, + 0x5396f9eb, 0xc6e62d7e, 0x9a560e17, 0x0f26da82, 0x6bc6a17c, + 0xfeb675e9, 0x2a14470b, 0xbf64939e, 0xdb84e860, 0x4ef43cf5, + 0x12441f9c, 0x8734cb09, 0xe3d4b0f7, 0x76a46462, 0x5ab4f625, + 0xcfc422b0, 0xab24594e, 0x3e548ddb, 0x62e4aeb2, 0xf7947a27, + 0x937401d9, 0x0604d54c, 0xcb552557, 0x5e25f1c2, 0x3ac58a3c, + 0xafb55ea9, 0xf3057dc0, 0x6675a955, 0x0295d2ab, 0x97e5063e, + 0xbbf59479, 0x2e8540ec, 0x4a653b12, 0xdf15ef87, 0x83a5ccee, + 0x16d5187b, 0x72356385, 0xe745b710, 0x67cf0be4, 0xf2bfdf71, + 0x965fa48f, 0x032f701a, 0x5f9f5373, 0xcaef87e6, 0xae0ffc18, + 0x3b7f288d, 0x176fbaca, 0x821f6e5f, 0xe6ff15a1, 0x738fc134, + 0x2f3fe25d, 0xba4f36c8, 0xdeaf4d36, 0x4bdf99a3, 0x868e69b8, + 0x13febd2d, 0x771ec6d3, 0xe26e1246, 0xbede312f, 0x2baee5ba, + 0x4f4e9e44, 0xda3e4ad1, 0xf62ed896, 0x635e0c03, 0x07be77fd, + 0x92cea368, 0xce7e8001, 0x5b0e5494, 0x3fee2f6a, 0xaa9efbff, + 0x7e3cc91d, 0xeb4c1d88, 0x8fac6676, 0x1adcb2e3, 0x466c918a, + 0xd31c451f, 0xb7fc3ee1, 0x228cea74, 0x0e9c7833, 0x9becaca6, + 0xff0cd758, 0x6a7c03cd, 0x36cc20a4, 0xa3bcf431, 0xc75c8fcf, + 0x522c5b5a, 0x9f7dab41, 0x0a0d7fd4, 0x6eed042a, 0xfb9dd0bf, + 0xa72df3d6, 0x325d2743, 0x56bd5cbd, 0xc3cd8828, 0xefdd1a6f, + 0x7aadcefa, 0x1e4db504, 0x8b3d6191, 0xd78d42f8, 0x42fd966d, + 0x261ded93, 0xb36d3906, 0x54288e16, 0xc1585a83, 0xa5b8217d, + 0x30c8f5e8, 0x6c78d681, 0xf9080214, 0x9de879ea, 0x0898ad7f, + 0x24883f38, 0xb1f8ebad, 0xd5189053, 0x406844c6, 0x1cd867af, + 0x89a8b33a, 0xed48c8c4, 0x78381c51, 0xb569ec4a, 0x201938df, + 0x44f94321, 0xd18997b4, 0x8d39b4dd, 0x18496048, 0x7ca91bb6, + 0xe9d9cf23, 0xc5c95d64, 0x50b989f1, 0x3459f20f, 0xa129269a, + 0xfd9905f3, 0x68e9d166, 0x0c09aa98, 0x99797e0d, 0x4ddb4cef, + 0xd8ab987a, 0xbc4be384, 0x293b3711, 0x758b1478, 0xe0fbc0ed, + 0x841bbb13, 0x116b6f86, 0x3d7bfdc1, 0xa80b2954, 0xcceb52aa, + 0x599b863f, 0x052ba556, 0x905b71c3, 0xf4bb0a3d, 0x61cbdea8, + 0xac9a2eb3, 0x39eafa26, 0x5d0a81d8, 0xc87a554d, 0x94ca7624, + 0x01baa2b1, 0x655ad94f, 0xf02a0dda, 0xdc3a9f9d, 0x494a4b08, + 0x2daa30f6, 0xb8dae463, 0xe46ac70a, 0x711a139f, 0x15fa6861, + 0x808abcf4}, + {0x00000000, 0xcf9e17c8, 0x444d29d1, 0x8bd33e19, 0x889a53a2, + 0x4704446a, 0xccd77a73, 0x03496dbb, 0xca45a105, 0x05dbb6cd, + 0x8e0888d4, 0x41969f1c, 0x42dff2a7, 0x8d41e56f, 0x0692db76, + 0xc90cccbe, 0x4ffa444b, 0x80645383, 0x0bb76d9a, 0xc4297a52, + 0xc76017e9, 0x08fe0021, 0x832d3e38, 0x4cb329f0, 0x85bfe54e, + 0x4a21f286, 0xc1f2cc9f, 0x0e6cdb57, 0x0d25b6ec, 0xc2bba124, + 0x49689f3d, 0x86f688f5, 0x9ff48896, 0x506a9f5e, 0xdbb9a147, + 0x1427b68f, 0x176edb34, 0xd8f0ccfc, 0x5323f2e5, 0x9cbde52d, + 0x55b12993, 0x9a2f3e5b, 0x11fc0042, 0xde62178a, 0xdd2b7a31, + 0x12b56df9, 0x996653e0, 0x56f84428, 0xd00eccdd, 0x1f90db15, + 0x9443e50c, 0x5bddf2c4, 0x58949f7f, 0x970a88b7, 0x1cd9b6ae, + 0xd347a166, 0x1a4b6dd8, 0xd5d57a10, 0x5e064409, 0x919853c1, + 0x92d13e7a, 0x5d4f29b2, 0xd69c17ab, 0x19020063, 0xe498176d, + 0x2b0600a5, 0xa0d53ebc, 0x6f4b2974, 0x6c0244cf, 0xa39c5307, + 0x284f6d1e, 0xe7d17ad6, 0x2eddb668, 0xe143a1a0, 0x6a909fb9, + 0xa50e8871, 0xa647e5ca, 0x69d9f202, 0xe20acc1b, 0x2d94dbd3, + 0xab625326, 0x64fc44ee, 0xef2f7af7, 0x20b16d3f, 0x23f80084, + 0xec66174c, 0x67b52955, 0xa82b3e9d, 0x6127f223, 0xaeb9e5eb, + 0x256adbf2, 0xeaf4cc3a, 0xe9bda181, 0x2623b649, 0xadf08850, + 0x626e9f98, 0x7b6c9ffb, 0xb4f28833, 0x3f21b62a, 0xf0bfa1e2, + 0xf3f6cc59, 0x3c68db91, 0xb7bbe588, 0x7825f240, 0xb1293efe, + 0x7eb72936, 0xf564172f, 0x3afa00e7, 0x39b36d5c, 0xf62d7a94, + 0x7dfe448d, 0xb2605345, 0x3496dbb0, 0xfb08cc78, 0x70dbf261, + 0xbf45e5a9, 0xbc0c8812, 0x73929fda, 0xf841a1c3, 0x37dfb60b, + 0xfed37ab5, 0x314d6d7d, 0xba9e5364, 0x750044ac, 0x76492917, + 0xb9d73edf, 0x320400c6, 0xfd9a170e, 0x1241289b, 0xdddf3f53, + 0x560c014a, 0x99921682, 0x9adb7b39, 0x55456cf1, 0xde9652e8, + 0x11084520, 0xd804899e, 0x179a9e56, 0x9c49a04f, 0x53d7b787, + 0x509eda3c, 0x9f00cdf4, 0x14d3f3ed, 0xdb4de425, 0x5dbb6cd0, + 0x92257b18, 0x19f64501, 0xd66852c9, 0xd5213f72, 0x1abf28ba, + 0x916c16a3, 0x5ef2016b, 0x97fecdd5, 0x5860da1d, 0xd3b3e404, + 0x1c2df3cc, 0x1f649e77, 0xd0fa89bf, 0x5b29b7a6, 0x94b7a06e, + 0x8db5a00d, 0x422bb7c5, 0xc9f889dc, 0x06669e14, 0x052ff3af, + 0xcab1e467, 0x4162da7e, 0x8efccdb6, 0x47f00108, 0x886e16c0, + 0x03bd28d9, 0xcc233f11, 0xcf6a52aa, 0x00f44562, 0x8b277b7b, + 0x44b96cb3, 0xc24fe446, 0x0dd1f38e, 0x8602cd97, 0x499cda5f, + 0x4ad5b7e4, 0x854ba02c, 0x0e989e35, 0xc10689fd, 0x080a4543, + 0xc794528b, 0x4c476c92, 0x83d97b5a, 0x809016e1, 0x4f0e0129, + 0xc4dd3f30, 0x0b4328f8, 0xf6d93ff6, 0x3947283e, 0xb2941627, + 0x7d0a01ef, 0x7e436c54, 0xb1dd7b9c, 0x3a0e4585, 0xf590524d, + 0x3c9c9ef3, 0xf302893b, 0x78d1b722, 0xb74fa0ea, 0xb406cd51, + 0x7b98da99, 0xf04be480, 0x3fd5f348, 0xb9237bbd, 0x76bd6c75, + 0xfd6e526c, 0x32f045a4, 0x31b9281f, 0xfe273fd7, 0x75f401ce, + 0xba6a1606, 0x7366dab8, 0xbcf8cd70, 0x372bf369, 0xf8b5e4a1, + 0xfbfc891a, 0x34629ed2, 0xbfb1a0cb, 0x702fb703, 0x692db760, + 0xa6b3a0a8, 0x2d609eb1, 0xe2fe8979, 0xe1b7e4c2, 0x2e29f30a, + 0xa5facd13, 0x6a64dadb, 0xa3681665, 0x6cf601ad, 0xe7253fb4, + 0x28bb287c, 0x2bf245c7, 0xe46c520f, 0x6fbf6c16, 0xa0217bde, + 0x26d7f32b, 0xe949e4e3, 0x629adafa, 0xad04cd32, 0xae4da089, + 0x61d3b741, 0xea008958, 0x259e9e90, 0xec92522e, 0x230c45e6, + 0xa8df7bff, 0x67416c37, 0x6408018c, 0xab961644, 0x2045285d, + 0xefdb3f95}, + {0x00000000, 0x24825136, 0x4904a26c, 0x6d86f35a, 0x920944d8, + 0xb68b15ee, 0xdb0de6b4, 0xff8fb782, 0xff638ff1, 0xdbe1dec7, + 0xb6672d9d, 0x92e57cab, 0x6d6acb29, 0x49e89a1f, 0x246e6945, + 0x00ec3873, 0x25b619a3, 0x01344895, 0x6cb2bbcf, 0x4830eaf9, + 0xb7bf5d7b, 0x933d0c4d, 0xfebbff17, 0xda39ae21, 0xdad59652, + 0xfe57c764, 0x93d1343e, 0xb7536508, 0x48dcd28a, 0x6c5e83bc, + 0x01d870e6, 0x255a21d0, 0x4b6c3346, 0x6fee6270, 0x0268912a, + 0x26eac01c, 0xd965779e, 0xfde726a8, 0x9061d5f2, 0xb4e384c4, + 0xb40fbcb7, 0x908ded81, 0xfd0b1edb, 0xd9894fed, 0x2606f86f, + 0x0284a959, 0x6f025a03, 0x4b800b35, 0x6eda2ae5, 0x4a587bd3, + 0x27de8889, 0x035cd9bf, 0xfcd36e3d, 0xd8513f0b, 0xb5d7cc51, + 0x91559d67, 0x91b9a514, 0xb53bf422, 0xd8bd0778, 0xfc3f564e, + 0x03b0e1cc, 0x2732b0fa, 0x4ab443a0, 0x6e361296, 0x96d8668c, + 0xb25a37ba, 0xdfdcc4e0, 0xfb5e95d6, 0x04d12254, 0x20537362, + 0x4dd58038, 0x6957d10e, 0x69bbe97d, 0x4d39b84b, 0x20bf4b11, + 0x043d1a27, 0xfbb2ada5, 0xdf30fc93, 0xb2b60fc9, 0x96345eff, + 0xb36e7f2f, 0x97ec2e19, 0xfa6add43, 0xdee88c75, 0x21673bf7, + 0x05e56ac1, 0x6863999b, 0x4ce1c8ad, 0x4c0df0de, 0x688fa1e8, + 0x050952b2, 0x218b0384, 0xde04b406, 0xfa86e530, 0x9700166a, + 0xb382475c, 0xddb455ca, 0xf93604fc, 0x94b0f7a6, 0xb032a690, + 0x4fbd1112, 0x6b3f4024, 0x06b9b37e, 0x223be248, 0x22d7da3b, + 0x06558b0d, 0x6bd37857, 0x4f512961, 0xb0de9ee3, 0x945ccfd5, + 0xf9da3c8f, 0xdd586db9, 0xf8024c69, 0xdc801d5f, 0xb106ee05, + 0x9584bf33, 0x6a0b08b1, 0x4e895987, 0x230faadd, 0x078dfbeb, + 0x0761c398, 0x23e392ae, 0x4e6561f4, 0x6ae730c2, 0x95688740, + 0xb1ead676, 0xdc6c252c, 0xf8ee741a, 0xf6c1cb59, 0xd2439a6f, + 0xbfc56935, 0x9b473803, 0x64c88f81, 0x404adeb7, 0x2dcc2ded, + 0x094e7cdb, 0x09a244a8, 0x2d20159e, 0x40a6e6c4, 0x6424b7f2, + 0x9bab0070, 0xbf295146, 0xd2afa21c, 0xf62df32a, 0xd377d2fa, + 0xf7f583cc, 0x9a737096, 0xbef121a0, 0x417e9622, 0x65fcc714, + 0x087a344e, 0x2cf86578, 0x2c145d0b, 0x08960c3d, 0x6510ff67, + 0x4192ae51, 0xbe1d19d3, 0x9a9f48e5, 0xf719bbbf, 0xd39bea89, + 0xbdadf81f, 0x992fa929, 0xf4a95a73, 0xd02b0b45, 0x2fa4bcc7, + 0x0b26edf1, 0x66a01eab, 0x42224f9d, 0x42ce77ee, 0x664c26d8, + 0x0bcad582, 0x2f4884b4, 0xd0c73336, 0xf4456200, 0x99c3915a, + 0xbd41c06c, 0x981be1bc, 0xbc99b08a, 0xd11f43d0, 0xf59d12e6, + 0x0a12a564, 0x2e90f452, 0x43160708, 0x6794563e, 0x67786e4d, + 0x43fa3f7b, 0x2e7ccc21, 0x0afe9d17, 0xf5712a95, 0xd1f37ba3, + 0xbc7588f9, 0x98f7d9cf, 0x6019add5, 0x449bfce3, 0x291d0fb9, + 0x0d9f5e8f, 0xf210e90d, 0xd692b83b, 0xbb144b61, 0x9f961a57, + 0x9f7a2224, 0xbbf87312, 0xd67e8048, 0xf2fcd17e, 0x0d7366fc, + 0x29f137ca, 0x4477c490, 0x60f595a6, 0x45afb476, 0x612de540, + 0x0cab161a, 0x2829472c, 0xd7a6f0ae, 0xf324a198, 0x9ea252c2, + 0xba2003f4, 0xbacc3b87, 0x9e4e6ab1, 0xf3c899eb, 0xd74ac8dd, + 0x28c57f5f, 0x0c472e69, 0x61c1dd33, 0x45438c05, 0x2b759e93, + 0x0ff7cfa5, 0x62713cff, 0x46f36dc9, 0xb97cda4b, 0x9dfe8b7d, + 0xf0787827, 0xd4fa2911, 0xd4161162, 0xf0944054, 0x9d12b30e, + 0xb990e238, 0x461f55ba, 0x629d048c, 0x0f1bf7d6, 0x2b99a6e0, + 0x0ec38730, 0x2a41d606, 0x47c7255c, 0x6345746a, 0x9ccac3e8, + 0xb84892de, 0xd5ce6184, 0xf14c30b2, 0xf1a008c1, 0xd52259f7, + 0xb8a4aaad, 0x9c26fb9b, 0x63a94c19, 0x472b1d2f, 0x2aadee75, + 0x0e2fbf43}, + {0x00000000, 0x36f290f3, 0x6de521e6, 0x5b17b115, 0xdbca43cc, + 0xed38d33f, 0xb62f622a, 0x80ddf2d9, 0x6ce581d9, 0x5a17112a, + 0x0100a03f, 0x37f230cc, 0xb72fc215, 0x81dd52e6, 0xdacae3f3, + 0xec387300, 0xd9cb03b2, 0xef399341, 0xb42e2254, 0x82dcb2a7, + 0x0201407e, 0x34f3d08d, 0x6fe46198, 0x5916f16b, 0xb52e826b, + 0x83dc1298, 0xd8cba38d, 0xee39337e, 0x6ee4c1a7, 0x58165154, + 0x0301e041, 0x35f370b2, 0x68e70125, 0x5e1591d6, 0x050220c3, + 0x33f0b030, 0xb32d42e9, 0x85dfd21a, 0xdec8630f, 0xe83af3fc, + 0x040280fc, 0x32f0100f, 0x69e7a11a, 0x5f1531e9, 0xdfc8c330, + 0xe93a53c3, 0xb22de2d6, 0x84df7225, 0xb12c0297, 0x87de9264, + 0xdcc92371, 0xea3bb382, 0x6ae6415b, 0x5c14d1a8, 0x070360bd, + 0x31f1f04e, 0xddc9834e, 0xeb3b13bd, 0xb02ca2a8, 0x86de325b, + 0x0603c082, 0x30f15071, 0x6be6e164, 0x5d147197, 0xd1ce024a, + 0xe73c92b9, 0xbc2b23ac, 0x8ad9b35f, 0x0a044186, 0x3cf6d175, + 0x67e16060, 0x5113f093, 0xbd2b8393, 0x8bd91360, 0xd0cea275, + 0xe63c3286, 0x66e1c05f, 0x501350ac, 0x0b04e1b9, 0x3df6714a, + 0x080501f8, 0x3ef7910b, 0x65e0201e, 0x5312b0ed, 0xd3cf4234, + 0xe53dd2c7, 0xbe2a63d2, 0x88d8f321, 0x64e08021, 0x521210d2, + 0x0905a1c7, 0x3ff73134, 0xbf2ac3ed, 0x89d8531e, 0xd2cfe20b, + 0xe43d72f8, 0xb929036f, 0x8fdb939c, 0xd4cc2289, 0xe23eb27a, + 0x62e340a3, 0x5411d050, 0x0f066145, 0x39f4f1b6, 0xd5cc82b6, + 0xe33e1245, 0xb829a350, 0x8edb33a3, 0x0e06c17a, 0x38f45189, + 0x63e3e09c, 0x5511706f, 0x60e200dd, 0x5610902e, 0x0d07213b, + 0x3bf5b1c8, 0xbb284311, 0x8ddad3e2, 0xd6cd62f7, 0xe03ff204, + 0x0c078104, 0x3af511f7, 0x61e2a0e2, 0x57103011, 0xd7cdc2c8, + 0xe13f523b, 0xba28e32e, 0x8cda73dd, 0x78ed02d5, 0x4e1f9226, + 0x15082333, 0x23fab3c0, 0xa3274119, 0x95d5d1ea, 0xcec260ff, + 0xf830f00c, 0x1408830c, 0x22fa13ff, 0x79eda2ea, 0x4f1f3219, + 0xcfc2c0c0, 0xf9305033, 0xa227e126, 0x94d571d5, 0xa1260167, + 0x97d49194, 0xccc32081, 0xfa31b072, 0x7aec42ab, 0x4c1ed258, + 0x1709634d, 0x21fbf3be, 0xcdc380be, 0xfb31104d, 0xa026a158, + 0x96d431ab, 0x1609c372, 0x20fb5381, 0x7bece294, 0x4d1e7267, + 0x100a03f0, 0x26f89303, 0x7def2216, 0x4b1db2e5, 0xcbc0403c, + 0xfd32d0cf, 0xa62561da, 0x90d7f129, 0x7cef8229, 0x4a1d12da, + 0x110aa3cf, 0x27f8333c, 0xa725c1e5, 0x91d75116, 0xcac0e003, + 0xfc3270f0, 0xc9c10042, 0xff3390b1, 0xa42421a4, 0x92d6b157, + 0x120b438e, 0x24f9d37d, 0x7fee6268, 0x491cf29b, 0xa524819b, + 0x93d61168, 0xc8c1a07d, 0xfe33308e, 0x7eeec257, 0x481c52a4, + 0x130be3b1, 0x25f97342, 0xa923009f, 0x9fd1906c, 0xc4c62179, + 0xf234b18a, 0x72e94353, 0x441bd3a0, 0x1f0c62b5, 0x29fef246, + 0xc5c68146, 0xf33411b5, 0xa823a0a0, 0x9ed13053, 0x1e0cc28a, + 0x28fe5279, 0x73e9e36c, 0x451b739f, 0x70e8032d, 0x461a93de, + 0x1d0d22cb, 0x2bffb238, 0xab2240e1, 0x9dd0d012, 0xc6c76107, + 0xf035f1f4, 0x1c0d82f4, 0x2aff1207, 0x71e8a312, 0x471a33e1, + 0xc7c7c138, 0xf13551cb, 0xaa22e0de, 0x9cd0702d, 0xc1c401ba, + 0xf7369149, 0xac21205c, 0x9ad3b0af, 0x1a0e4276, 0x2cfcd285, + 0x77eb6390, 0x4119f363, 0xad218063, 0x9bd31090, 0xc0c4a185, + 0xf6363176, 0x76ebc3af, 0x4019535c, 0x1b0ee249, 0x2dfc72ba, + 0x180f0208, 0x2efd92fb, 0x75ea23ee, 0x4318b31d, 0xc3c541c4, + 0xf537d137, 0xae206022, 0x98d2f0d1, 0x74ea83d1, 0x42181322, + 0x190fa237, 0x2ffd32c4, 0xaf20c01d, 0x99d250ee, 0xc2c5e1fb, + 0xf4377108}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xf390f23600000000, 0xe621e56d00000000, + 0x15b1175b00000000, 0xcc43cadb00000000, 0x3fd338ed00000000, + 0x2a622fb600000000, 0xd9f2dd8000000000, 0xd981e56c00000000, + 0x2a11175a00000000, 0x3fa0000100000000, 0xcc30f23700000000, + 0x15c22fb700000000, 0xe652dd8100000000, 0xf3e3cada00000000, + 0x007338ec00000000, 0xb203cbd900000000, 0x419339ef00000000, + 0x54222eb400000000, 0xa7b2dc8200000000, 0x7e40010200000000, + 0x8dd0f33400000000, 0x9861e46f00000000, 0x6bf1165900000000, + 0x6b822eb500000000, 0x9812dc8300000000, 0x8da3cbd800000000, + 0x7e3339ee00000000, 0xa7c1e46e00000000, 0x5451165800000000, + 0x41e0010300000000, 0xb270f33500000000, 0x2501e76800000000, + 0xd691155e00000000, 0xc320020500000000, 0x30b0f03300000000, + 0xe9422db300000000, 0x1ad2df8500000000, 0x0f63c8de00000000, + 0xfcf33ae800000000, 0xfc80020400000000, 0x0f10f03200000000, + 0x1aa1e76900000000, 0xe931155f00000000, 0x30c3c8df00000000, + 0xc3533ae900000000, 0xd6e22db200000000, 0x2572df8400000000, + 0x97022cb100000000, 0x6492de8700000000, 0x7123c9dc00000000, + 0x82b33bea00000000, 0x5b41e66a00000000, 0xa8d1145c00000000, + 0xbd60030700000000, 0x4ef0f13100000000, 0x4e83c9dd00000000, + 0xbd133beb00000000, 0xa8a22cb000000000, 0x5b32de8600000000, + 0x82c0030600000000, 0x7150f13000000000, 0x64e1e66b00000000, + 0x9771145d00000000, 0x4a02ced100000000, 0xb9923ce700000000, + 0xac232bbc00000000, 0x5fb3d98a00000000, 0x8641040a00000000, + 0x75d1f63c00000000, 0x6060e16700000000, 0x93f0135100000000, + 0x93832bbd00000000, 0x6013d98b00000000, 0x75a2ced000000000, + 0x86323ce600000000, 0x5fc0e16600000000, 0xac50135000000000, + 0xb9e1040b00000000, 0x4a71f63d00000000, 0xf801050800000000, + 0x0b91f73e00000000, 0x1e20e06500000000, 0xedb0125300000000, + 0x3442cfd300000000, 0xc7d23de500000000, 0xd2632abe00000000, + 0x21f3d88800000000, 0x2180e06400000000, 0xd210125200000000, + 0xc7a1050900000000, 0x3431f73f00000000, 0xedc32abf00000000, + 0x1e53d88900000000, 0x0be2cfd200000000, 0xf8723de400000000, + 0x6f0329b900000000, 0x9c93db8f00000000, 0x8922ccd400000000, + 0x7ab23ee200000000, 0xa340e36200000000, 0x50d0115400000000, + 0x4561060f00000000, 0xb6f1f43900000000, 0xb682ccd500000000, + 0x45123ee300000000, 0x50a329b800000000, 0xa333db8e00000000, + 0x7ac1060e00000000, 0x8951f43800000000, 0x9ce0e36300000000, + 0x6f70115500000000, 0xdd00e26000000000, 0x2e90105600000000, + 0x3b21070d00000000, 0xc8b1f53b00000000, 0x114328bb00000000, + 0xe2d3da8d00000000, 0xf762cdd600000000, 0x04f23fe000000000, + 0x0481070c00000000, 0xf711f53a00000000, 0xe2a0e26100000000, + 0x1130105700000000, 0xc8c2cdd700000000, 0x3b523fe100000000, + 0x2ee328ba00000000, 0xdd73da8c00000000, 0xd502ed7800000000, + 0x26921f4e00000000, 0x3323081500000000, 0xc0b3fa2300000000, + 0x194127a300000000, 0xead1d59500000000, 0xff60c2ce00000000, + 0x0cf030f800000000, 0x0c83081400000000, 0xff13fa2200000000, + 0xeaa2ed7900000000, 0x19321f4f00000000, 0xc0c0c2cf00000000, + 0x335030f900000000, 0x26e127a200000000, 0xd571d59400000000, + 0x670126a100000000, 0x9491d49700000000, 0x8120c3cc00000000, + 0x72b031fa00000000, 0xab42ec7a00000000, 0x58d21e4c00000000, + 0x4d63091700000000, 0xbef3fb2100000000, 0xbe80c3cd00000000, + 0x4d1031fb00000000, 0x58a126a000000000, 0xab31d49600000000, + 0x72c3091600000000, 0x8153fb2000000000, 0x94e2ec7b00000000, + 0x67721e4d00000000, 0xf0030a1000000000, 0x0393f82600000000, + 0x1622ef7d00000000, 0xe5b21d4b00000000, 0x3c40c0cb00000000, + 0xcfd032fd00000000, 0xda6125a600000000, 0x29f1d79000000000, + 0x2982ef7c00000000, 0xda121d4a00000000, 0xcfa30a1100000000, + 0x3c33f82700000000, 0xe5c125a700000000, 0x1651d79100000000, + 0x03e0c0ca00000000, 0xf07032fc00000000, 0x4200c1c900000000, + 0xb19033ff00000000, 0xa42124a400000000, 0x57b1d69200000000, + 0x8e430b1200000000, 0x7dd3f92400000000, 0x6862ee7f00000000, + 0x9bf21c4900000000, 0x9b8124a500000000, 0x6811d69300000000, + 0x7da0c1c800000000, 0x8e3033fe00000000, 0x57c2ee7e00000000, + 0xa4521c4800000000, 0xb1e30b1300000000, 0x4273f92500000000, + 0x9f0023a900000000, 0x6c90d19f00000000, 0x7921c6c400000000, + 0x8ab134f200000000, 0x5343e97200000000, 0xa0d31b4400000000, + 0xb5620c1f00000000, 0x46f2fe2900000000, 0x4681c6c500000000, + 0xb51134f300000000, 0xa0a023a800000000, 0x5330d19e00000000, + 0x8ac20c1e00000000, 0x7952fe2800000000, 0x6ce3e97300000000, + 0x9f731b4500000000, 0x2d03e87000000000, 0xde931a4600000000, + 0xcb220d1d00000000, 0x38b2ff2b00000000, 0xe14022ab00000000, + 0x12d0d09d00000000, 0x0761c7c600000000, 0xf4f135f000000000, + 0xf4820d1c00000000, 0x0712ff2a00000000, 0x12a3e87100000000, + 0xe1331a4700000000, 0x38c1c7c700000000, 0xcb5135f100000000, + 0xdee022aa00000000, 0x2d70d09c00000000, 0xba01c4c100000000, + 0x499136f700000000, 0x5c2021ac00000000, 0xafb0d39a00000000, + 0x76420e1a00000000, 0x85d2fc2c00000000, 0x9063eb7700000000, + 0x63f3194100000000, 0x638021ad00000000, 0x9010d39b00000000, + 0x85a1c4c000000000, 0x763136f600000000, 0xafc3eb7600000000, + 0x5c53194000000000, 0x49e20e1b00000000, 0xba72fc2d00000000, + 0x08020f1800000000, 0xfb92fd2e00000000, 0xee23ea7500000000, + 0x1db3184300000000, 0xc441c5c300000000, 0x37d137f500000000, + 0x226020ae00000000, 0xd1f0d29800000000, 0xd183ea7400000000, + 0x2213184200000000, 0x37a20f1900000000, 0xc432fd2f00000000, + 0x1dc020af00000000, 0xee50d29900000000, 0xfbe1c5c200000000, + 0x087137f400000000}, + {0x0000000000000000, 0x3651822400000000, 0x6ca2044900000000, + 0x5af3866d00000000, 0xd844099200000000, 0xee158bb600000000, + 0xb4e60ddb00000000, 0x82b78fff00000000, 0xf18f63ff00000000, + 0xc7dee1db00000000, 0x9d2d67b600000000, 0xab7ce59200000000, + 0x29cb6a6d00000000, 0x1f9ae84900000000, 0x45696e2400000000, + 0x7338ec0000000000, 0xa319b62500000000, 0x9548340100000000, + 0xcfbbb26c00000000, 0xf9ea304800000000, 0x7b5dbfb700000000, + 0x4d0c3d9300000000, 0x17ffbbfe00000000, 0x21ae39da00000000, + 0x5296d5da00000000, 0x64c757fe00000000, 0x3e34d19300000000, + 0x086553b700000000, 0x8ad2dc4800000000, 0xbc835e6c00000000, + 0xe670d80100000000, 0xd0215a2500000000, 0x46336c4b00000000, + 0x7062ee6f00000000, 0x2a91680200000000, 0x1cc0ea2600000000, + 0x9e7765d900000000, 0xa826e7fd00000000, 0xf2d5619000000000, + 0xc484e3b400000000, 0xb7bc0fb400000000, 0x81ed8d9000000000, + 0xdb1e0bfd00000000, 0xed4f89d900000000, 0x6ff8062600000000, + 0x59a9840200000000, 0x035a026f00000000, 0x350b804b00000000, + 0xe52ada6e00000000, 0xd37b584a00000000, 0x8988de2700000000, + 0xbfd95c0300000000, 0x3d6ed3fc00000000, 0x0b3f51d800000000, + 0x51ccd7b500000000, 0x679d559100000000, 0x14a5b99100000000, + 0x22f43bb500000000, 0x7807bdd800000000, 0x4e563ffc00000000, + 0xcce1b00300000000, 0xfab0322700000000, 0xa043b44a00000000, + 0x9612366e00000000, 0x8c66d89600000000, 0xba375ab200000000, + 0xe0c4dcdf00000000, 0xd6955efb00000000, 0x5422d10400000000, + 0x6273532000000000, 0x3880d54d00000000, 0x0ed1576900000000, + 0x7de9bb6900000000, 0x4bb8394d00000000, 0x114bbf2000000000, + 0x271a3d0400000000, 0xa5adb2fb00000000, 0x93fc30df00000000, + 0xc90fb6b200000000, 0xff5e349600000000, 0x2f7f6eb300000000, + 0x192eec9700000000, 0x43dd6afa00000000, 0x758ce8de00000000, + 0xf73b672100000000, 0xc16ae50500000000, 0x9b99636800000000, + 0xadc8e14c00000000, 0xdef00d4c00000000, 0xe8a18f6800000000, + 0xb252090500000000, 0x84038b2100000000, 0x06b404de00000000, + 0x30e586fa00000000, 0x6a16009700000000, 0x5c4782b300000000, + 0xca55b4dd00000000, 0xfc0436f900000000, 0xa6f7b09400000000, + 0x90a632b000000000, 0x1211bd4f00000000, 0x24403f6b00000000, + 0x7eb3b90600000000, 0x48e23b2200000000, 0x3bdad72200000000, + 0x0d8b550600000000, 0x5778d36b00000000, 0x6129514f00000000, + 0xe39edeb000000000, 0xd5cf5c9400000000, 0x8f3cdaf900000000, + 0xb96d58dd00000000, 0x694c02f800000000, 0x5f1d80dc00000000, + 0x05ee06b100000000, 0x33bf849500000000, 0xb1080b6a00000000, + 0x8759894e00000000, 0xddaa0f2300000000, 0xebfb8d0700000000, + 0x98c3610700000000, 0xae92e32300000000, 0xf461654e00000000, + 0xc230e76a00000000, 0x4087689500000000, 0x76d6eab100000000, + 0x2c256cdc00000000, 0x1a74eef800000000, 0x59cbc1f600000000, + 0x6f9a43d200000000, 0x3569c5bf00000000, 0x0338479b00000000, + 0x818fc86400000000, 0xb7de4a4000000000, 0xed2dcc2d00000000, + 0xdb7c4e0900000000, 0xa844a20900000000, 0x9e15202d00000000, + 0xc4e6a64000000000, 0xf2b7246400000000, 0x7000ab9b00000000, + 0x465129bf00000000, 0x1ca2afd200000000, 0x2af32df600000000, + 0xfad277d300000000, 0xcc83f5f700000000, 0x9670739a00000000, + 0xa021f1be00000000, 0x22967e4100000000, 0x14c7fc6500000000, + 0x4e347a0800000000, 0x7865f82c00000000, 0x0b5d142c00000000, + 0x3d0c960800000000, 0x67ff106500000000, 0x51ae924100000000, + 0xd3191dbe00000000, 0xe5489f9a00000000, 0xbfbb19f700000000, + 0x89ea9bd300000000, 0x1ff8adbd00000000, 0x29a92f9900000000, + 0x735aa9f400000000, 0x450b2bd000000000, 0xc7bca42f00000000, + 0xf1ed260b00000000, 0xab1ea06600000000, 0x9d4f224200000000, + 0xee77ce4200000000, 0xd8264c6600000000, 0x82d5ca0b00000000, + 0xb484482f00000000, 0x3633c7d000000000, 0x006245f400000000, + 0x5a91c39900000000, 0x6cc041bd00000000, 0xbce11b9800000000, + 0x8ab099bc00000000, 0xd0431fd100000000, 0xe6129df500000000, + 0x64a5120a00000000, 0x52f4902e00000000, 0x0807164300000000, + 0x3e56946700000000, 0x4d6e786700000000, 0x7b3ffa4300000000, + 0x21cc7c2e00000000, 0x179dfe0a00000000, 0x952a71f500000000, + 0xa37bf3d100000000, 0xf98875bc00000000, 0xcfd9f79800000000, + 0xd5ad196000000000, 0xe3fc9b4400000000, 0xb90f1d2900000000, + 0x8f5e9f0d00000000, 0x0de910f200000000, 0x3bb892d600000000, + 0x614b14bb00000000, 0x571a969f00000000, 0x24227a9f00000000, + 0x1273f8bb00000000, 0x48807ed600000000, 0x7ed1fcf200000000, + 0xfc66730d00000000, 0xca37f12900000000, 0x90c4774400000000, + 0xa695f56000000000, 0x76b4af4500000000, 0x40e52d6100000000, + 0x1a16ab0c00000000, 0x2c47292800000000, 0xaef0a6d700000000, + 0x98a124f300000000, 0xc252a29e00000000, 0xf40320ba00000000, + 0x873bccba00000000, 0xb16a4e9e00000000, 0xeb99c8f300000000, + 0xddc84ad700000000, 0x5f7fc52800000000, 0x692e470c00000000, + 0x33ddc16100000000, 0x058c434500000000, 0x939e752b00000000, + 0xa5cff70f00000000, 0xff3c716200000000, 0xc96df34600000000, + 0x4bda7cb900000000, 0x7d8bfe9d00000000, 0x277878f000000000, + 0x1129fad400000000, 0x621116d400000000, 0x544094f000000000, + 0x0eb3129d00000000, 0x38e290b900000000, 0xba551f4600000000, + 0x8c049d6200000000, 0xd6f71b0f00000000, 0xe0a6992b00000000, + 0x3087c30e00000000, 0x06d6412a00000000, 0x5c25c74700000000, + 0x6a74456300000000, 0xe8c3ca9c00000000, 0xde9248b800000000, + 0x8461ced500000000, 0xb2304cf100000000, 0xc108a0f100000000, + 0xf75922d500000000, 0xadaaa4b800000000, 0x9bfb269c00000000, + 0x194ca96300000000, 0x2f1d2b4700000000, 0x75eead2a00000000, + 0x43bf2f0e00000000}, + {0x0000000000000000, 0xc8179ecf00000000, 0xd1294d4400000000, + 0x193ed38b00000000, 0xa2539a8800000000, 0x6a44044700000000, + 0x737ad7cc00000000, 0xbb6d490300000000, 0x05a145ca00000000, + 0xcdb6db0500000000, 0xd488088e00000000, 0x1c9f964100000000, + 0xa7f2df4200000000, 0x6fe5418d00000000, 0x76db920600000000, + 0xbecc0cc900000000, 0x4b44fa4f00000000, 0x8353648000000000, + 0x9a6db70b00000000, 0x527a29c400000000, 0xe91760c700000000, + 0x2100fe0800000000, 0x383e2d8300000000, 0xf029b34c00000000, + 0x4ee5bf8500000000, 0x86f2214a00000000, 0x9fccf2c100000000, + 0x57db6c0e00000000, 0xecb6250d00000000, 0x24a1bbc200000000, + 0x3d9f684900000000, 0xf588f68600000000, 0x9688f49f00000000, + 0x5e9f6a5000000000, 0x47a1b9db00000000, 0x8fb6271400000000, + 0x34db6e1700000000, 0xfcccf0d800000000, 0xe5f2235300000000, + 0x2de5bd9c00000000, 0x9329b15500000000, 0x5b3e2f9a00000000, + 0x4200fc1100000000, 0x8a1762de00000000, 0x317a2bdd00000000, + 0xf96db51200000000, 0xe053669900000000, 0x2844f85600000000, + 0xddcc0ed000000000, 0x15db901f00000000, 0x0ce5439400000000, + 0xc4f2dd5b00000000, 0x7f9f945800000000, 0xb7880a9700000000, + 0xaeb6d91c00000000, 0x66a147d300000000, 0xd86d4b1a00000000, + 0x107ad5d500000000, 0x0944065e00000000, 0xc153989100000000, + 0x7a3ed19200000000, 0xb2294f5d00000000, 0xab179cd600000000, + 0x6300021900000000, 0x6d1798e400000000, 0xa500062b00000000, + 0xbc3ed5a000000000, 0x74294b6f00000000, 0xcf44026c00000000, + 0x07539ca300000000, 0x1e6d4f2800000000, 0xd67ad1e700000000, + 0x68b6dd2e00000000, 0xa0a143e100000000, 0xb99f906a00000000, + 0x71880ea500000000, 0xcae547a600000000, 0x02f2d96900000000, + 0x1bcc0ae200000000, 0xd3db942d00000000, 0x265362ab00000000, + 0xee44fc6400000000, 0xf77a2fef00000000, 0x3f6db12000000000, + 0x8400f82300000000, 0x4c1766ec00000000, 0x5529b56700000000, + 0x9d3e2ba800000000, 0x23f2276100000000, 0xebe5b9ae00000000, + 0xf2db6a2500000000, 0x3accf4ea00000000, 0x81a1bde900000000, + 0x49b6232600000000, 0x5088f0ad00000000, 0x989f6e6200000000, + 0xfb9f6c7b00000000, 0x3388f2b400000000, 0x2ab6213f00000000, + 0xe2a1bff000000000, 0x59ccf6f300000000, 0x91db683c00000000, + 0x88e5bbb700000000, 0x40f2257800000000, 0xfe3e29b100000000, + 0x3629b77e00000000, 0x2f1764f500000000, 0xe700fa3a00000000, + 0x5c6db33900000000, 0x947a2df600000000, 0x8d44fe7d00000000, + 0x455360b200000000, 0xb0db963400000000, 0x78cc08fb00000000, + 0x61f2db7000000000, 0xa9e545bf00000000, 0x12880cbc00000000, + 0xda9f927300000000, 0xc3a141f800000000, 0x0bb6df3700000000, + 0xb57ad3fe00000000, 0x7d6d4d3100000000, 0x64539eba00000000, + 0xac44007500000000, 0x1729497600000000, 0xdf3ed7b900000000, + 0xc600043200000000, 0x0e179afd00000000, 0x9b28411200000000, + 0x533fdfdd00000000, 0x4a010c5600000000, 0x8216929900000000, + 0x397bdb9a00000000, 0xf16c455500000000, 0xe85296de00000000, + 0x2045081100000000, 0x9e8904d800000000, 0x569e9a1700000000, + 0x4fa0499c00000000, 0x87b7d75300000000, 0x3cda9e5000000000, + 0xf4cd009f00000000, 0xedf3d31400000000, 0x25e44ddb00000000, + 0xd06cbb5d00000000, 0x187b259200000000, 0x0145f61900000000, + 0xc95268d600000000, 0x723f21d500000000, 0xba28bf1a00000000, + 0xa3166c9100000000, 0x6b01f25e00000000, 0xd5cdfe9700000000, + 0x1dda605800000000, 0x04e4b3d300000000, 0xccf32d1c00000000, + 0x779e641f00000000, 0xbf89fad000000000, 0xa6b7295b00000000, + 0x6ea0b79400000000, 0x0da0b58d00000000, 0xc5b72b4200000000, + 0xdc89f8c900000000, 0x149e660600000000, 0xaff32f0500000000, + 0x67e4b1ca00000000, 0x7eda624100000000, 0xb6cdfc8e00000000, + 0x0801f04700000000, 0xc0166e8800000000, 0xd928bd0300000000, + 0x113f23cc00000000, 0xaa526acf00000000, 0x6245f40000000000, + 0x7b7b278b00000000, 0xb36cb94400000000, 0x46e44fc200000000, + 0x8ef3d10d00000000, 0x97cd028600000000, 0x5fda9c4900000000, + 0xe4b7d54a00000000, 0x2ca04b8500000000, 0x359e980e00000000, + 0xfd8906c100000000, 0x43450a0800000000, 0x8b5294c700000000, + 0x926c474c00000000, 0x5a7bd98300000000, 0xe116908000000000, + 0x29010e4f00000000, 0x303fddc400000000, 0xf828430b00000000, + 0xf63fd9f600000000, 0x3e28473900000000, 0x271694b200000000, + 0xef010a7d00000000, 0x546c437e00000000, 0x9c7bddb100000000, + 0x85450e3a00000000, 0x4d5290f500000000, 0xf39e9c3c00000000, + 0x3b8902f300000000, 0x22b7d17800000000, 0xeaa04fb700000000, + 0x51cd06b400000000, 0x99da987b00000000, 0x80e44bf000000000, + 0x48f3d53f00000000, 0xbd7b23b900000000, 0x756cbd7600000000, + 0x6c526efd00000000, 0xa445f03200000000, 0x1f28b93100000000, + 0xd73f27fe00000000, 0xce01f47500000000, 0x06166aba00000000, + 0xb8da667300000000, 0x70cdf8bc00000000, 0x69f32b3700000000, + 0xa1e4b5f800000000, 0x1a89fcfb00000000, 0xd29e623400000000, + 0xcba0b1bf00000000, 0x03b72f7000000000, 0x60b72d6900000000, + 0xa8a0b3a600000000, 0xb19e602d00000000, 0x7989fee200000000, + 0xc2e4b7e100000000, 0x0af3292e00000000, 0x13cdfaa500000000, + 0xdbda646a00000000, 0x651668a300000000, 0xad01f66c00000000, + 0xb43f25e700000000, 0x7c28bb2800000000, 0xc745f22b00000000, + 0x0f526ce400000000, 0x166cbf6f00000000, 0xde7b21a000000000, + 0x2bf3d72600000000, 0xe3e449e900000000, 0xfada9a6200000000, + 0x32cd04ad00000000, 0x89a04dae00000000, 0x41b7d36100000000, + 0x588900ea00000000, 0x909e9e2500000000, 0x2e5292ec00000000, + 0xe6450c2300000000, 0xff7bdfa800000000, 0x376c416700000000, + 0x8c01086400000000, 0x441696ab00000000, 0x5d28452000000000, + 0x953fdbef00000000}, + {0x0000000000000000, 0x95d4709500000000, 0x6baf90f100000000, + 0xfe7be06400000000, 0x9758503800000000, 0x028c20ad00000000, + 0xfcf7c0c900000000, 0x6923b05c00000000, 0x2eb1a07000000000, + 0xbb65d0e500000000, 0x451e308100000000, 0xd0ca401400000000, + 0xb9e9f04800000000, 0x2c3d80dd00000000, 0xd24660b900000000, + 0x4792102c00000000, 0x5c6241e100000000, 0xc9b6317400000000, + 0x37cdd11000000000, 0xa219a18500000000, 0xcb3a11d900000000, + 0x5eee614c00000000, 0xa095812800000000, 0x3541f1bd00000000, + 0x72d3e19100000000, 0xe707910400000000, 0x197c716000000000, + 0x8ca801f500000000, 0xe58bb1a900000000, 0x705fc13c00000000, + 0x8e24215800000000, 0x1bf051cd00000000, 0xf9c2f31900000000, + 0x6c16838c00000000, 0x926d63e800000000, 0x07b9137d00000000, + 0x6e9aa32100000000, 0xfb4ed3b400000000, 0x053533d000000000, + 0x90e1434500000000, 0xd773536900000000, 0x42a723fc00000000, + 0xbcdcc39800000000, 0x2908b30d00000000, 0x402b035100000000, + 0xd5ff73c400000000, 0x2b8493a000000000, 0xbe50e33500000000, + 0xa5a0b2f800000000, 0x3074c26d00000000, 0xce0f220900000000, + 0x5bdb529c00000000, 0x32f8e2c000000000, 0xa72c925500000000, + 0x5957723100000000, 0xcc8302a400000000, 0x8b11128800000000, + 0x1ec5621d00000000, 0xe0be827900000000, 0x756af2ec00000000, + 0x1c4942b000000000, 0x899d322500000000, 0x77e6d24100000000, + 0xe232a2d400000000, 0xf285e73300000000, 0x675197a600000000, + 0x992a77c200000000, 0x0cfe075700000000, 0x65ddb70b00000000, + 0xf009c79e00000000, 0x0e7227fa00000000, 0x9ba6576f00000000, + 0xdc34474300000000, 0x49e037d600000000, 0xb79bd7b200000000, + 0x224fa72700000000, 0x4b6c177b00000000, 0xdeb867ee00000000, + 0x20c3878a00000000, 0xb517f71f00000000, 0xaee7a6d200000000, + 0x3b33d64700000000, 0xc548362300000000, 0x509c46b600000000, + 0x39bff6ea00000000, 0xac6b867f00000000, 0x5210661b00000000, + 0xc7c4168e00000000, 0x805606a200000000, 0x1582763700000000, + 0xebf9965300000000, 0x7e2de6c600000000, 0x170e569a00000000, + 0x82da260f00000000, 0x7ca1c66b00000000, 0xe975b6fe00000000, + 0x0b47142a00000000, 0x9e9364bf00000000, 0x60e884db00000000, + 0xf53cf44e00000000, 0x9c1f441200000000, 0x09cb348700000000, + 0xf7b0d4e300000000, 0x6264a47600000000, 0x25f6b45a00000000, + 0xb022c4cf00000000, 0x4e5924ab00000000, 0xdb8d543e00000000, + 0xb2aee46200000000, 0x277a94f700000000, 0xd901749300000000, + 0x4cd5040600000000, 0x572555cb00000000, 0xc2f1255e00000000, + 0x3c8ac53a00000000, 0xa95eb5af00000000, 0xc07d05f300000000, + 0x55a9756600000000, 0xabd2950200000000, 0x3e06e59700000000, + 0x7994f5bb00000000, 0xec40852e00000000, 0x123b654a00000000, + 0x87ef15df00000000, 0xeecca58300000000, 0x7b18d51600000000, + 0x8563357200000000, 0x10b745e700000000, 0xe40bcf6700000000, + 0x71dfbff200000000, 0x8fa45f9600000000, 0x1a702f0300000000, + 0x73539f5f00000000, 0xe687efca00000000, 0x18fc0fae00000000, + 0x8d287f3b00000000, 0xcaba6f1700000000, 0x5f6e1f8200000000, + 0xa115ffe600000000, 0x34c18f7300000000, 0x5de23f2f00000000, + 0xc8364fba00000000, 0x364dafde00000000, 0xa399df4b00000000, + 0xb8698e8600000000, 0x2dbdfe1300000000, 0xd3c61e7700000000, + 0x46126ee200000000, 0x2f31debe00000000, 0xbae5ae2b00000000, + 0x449e4e4f00000000, 0xd14a3eda00000000, 0x96d82ef600000000, + 0x030c5e6300000000, 0xfd77be0700000000, 0x68a3ce9200000000, + 0x01807ece00000000, 0x94540e5b00000000, 0x6a2fee3f00000000, + 0xfffb9eaa00000000, 0x1dc93c7e00000000, 0x881d4ceb00000000, + 0x7666ac8f00000000, 0xe3b2dc1a00000000, 0x8a916c4600000000, + 0x1f451cd300000000, 0xe13efcb700000000, 0x74ea8c2200000000, + 0x33789c0e00000000, 0xa6acec9b00000000, 0x58d70cff00000000, + 0xcd037c6a00000000, 0xa420cc3600000000, 0x31f4bca300000000, + 0xcf8f5cc700000000, 0x5a5b2c5200000000, 0x41ab7d9f00000000, + 0xd47f0d0a00000000, 0x2a04ed6e00000000, 0xbfd09dfb00000000, + 0xd6f32da700000000, 0x43275d3200000000, 0xbd5cbd5600000000, + 0x2888cdc300000000, 0x6f1addef00000000, 0xfacead7a00000000, + 0x04b54d1e00000000, 0x91613d8b00000000, 0xf8428dd700000000, + 0x6d96fd4200000000, 0x93ed1d2600000000, 0x06396db300000000, + 0x168e285400000000, 0x835a58c100000000, 0x7d21b8a500000000, + 0xe8f5c83000000000, 0x81d6786c00000000, 0x140208f900000000, + 0xea79e89d00000000, 0x7fad980800000000, 0x383f882400000000, + 0xadebf8b100000000, 0x539018d500000000, 0xc644684000000000, + 0xaf67d81c00000000, 0x3ab3a88900000000, 0xc4c848ed00000000, + 0x511c387800000000, 0x4aec69b500000000, 0xdf38192000000000, + 0x2143f94400000000, 0xb49789d100000000, 0xddb4398d00000000, + 0x4860491800000000, 0xb61ba97c00000000, 0x23cfd9e900000000, + 0x645dc9c500000000, 0xf189b95000000000, 0x0ff2593400000000, + 0x9a2629a100000000, 0xf30599fd00000000, 0x66d1e96800000000, + 0x98aa090c00000000, 0x0d7e799900000000, 0xef4cdb4d00000000, + 0x7a98abd800000000, 0x84e34bbc00000000, 0x11373b2900000000, + 0x78148b7500000000, 0xedc0fbe000000000, 0x13bb1b8400000000, + 0x866f6b1100000000, 0xc1fd7b3d00000000, 0x54290ba800000000, + 0xaa52ebcc00000000, 0x3f869b5900000000, 0x56a52b0500000000, + 0xc3715b9000000000, 0x3d0abbf400000000, 0xa8decb6100000000, + 0xb32e9aac00000000, 0x26faea3900000000, 0xd8810a5d00000000, + 0x4d557ac800000000, 0x2476ca9400000000, 0xb1a2ba0100000000, + 0x4fd95a6500000000, 0xda0d2af000000000, 0x9d9f3adc00000000, + 0x084b4a4900000000, 0xf630aa2d00000000, 0x63e4dab800000000, + 0x0ac76ae400000000, 0x9f131a7100000000, 0x6168fa1500000000, + 0xf4bc8a8000000000}, + {0x0000000000000000, 0x1f17f08000000000, 0x7f2891da00000000, + 0x603f615a00000000, 0xbf56536e00000000, 0xa041a3ee00000000, + 0xc07ec2b400000000, 0xdf69323400000000, 0x7eada6dc00000000, + 0x61ba565c00000000, 0x0185370600000000, 0x1e92c78600000000, + 0xc1fbf5b200000000, 0xdeec053200000000, 0xbed3646800000000, + 0xa1c494e800000000, 0xbd5c3c6200000000, 0xa24bcce200000000, + 0xc274adb800000000, 0xdd635d3800000000, 0x020a6f0c00000000, + 0x1d1d9f8c00000000, 0x7d22fed600000000, 0x62350e5600000000, + 0xc3f19abe00000000, 0xdce66a3e00000000, 0xbcd90b6400000000, + 0xa3cefbe400000000, 0x7ca7c9d000000000, 0x63b0395000000000, + 0x038f580a00000000, 0x1c98a88a00000000, 0x7ab978c400000000, + 0x65ae884400000000, 0x0591e91e00000000, 0x1a86199e00000000, + 0xc5ef2baa00000000, 0xdaf8db2a00000000, 0xbac7ba7000000000, + 0xa5d04af000000000, 0x0414de1800000000, 0x1b032e9800000000, + 0x7b3c4fc200000000, 0x642bbf4200000000, 0xbb428d7600000000, + 0xa4557df600000000, 0xc46a1cac00000000, 0xdb7dec2c00000000, + 0xc7e544a600000000, 0xd8f2b42600000000, 0xb8cdd57c00000000, + 0xa7da25fc00000000, 0x78b317c800000000, 0x67a4e74800000000, + 0x079b861200000000, 0x188c769200000000, 0xb948e27a00000000, + 0xa65f12fa00000000, 0xc66073a000000000, 0xd977832000000000, + 0x061eb11400000000, 0x1909419400000000, 0x793620ce00000000, + 0x6621d04e00000000, 0xb574805300000000, 0xaa6370d300000000, + 0xca5c118900000000, 0xd54be10900000000, 0x0a22d33d00000000, + 0x153523bd00000000, 0x750a42e700000000, 0x6a1db26700000000, + 0xcbd9268f00000000, 0xd4ced60f00000000, 0xb4f1b75500000000, + 0xabe647d500000000, 0x748f75e100000000, 0x6b98856100000000, + 0x0ba7e43b00000000, 0x14b014bb00000000, 0x0828bc3100000000, + 0x173f4cb100000000, 0x77002deb00000000, 0x6817dd6b00000000, + 0xb77eef5f00000000, 0xa8691fdf00000000, 0xc8567e8500000000, + 0xd7418e0500000000, 0x76851aed00000000, 0x6992ea6d00000000, + 0x09ad8b3700000000, 0x16ba7bb700000000, 0xc9d3498300000000, + 0xd6c4b90300000000, 0xb6fbd85900000000, 0xa9ec28d900000000, + 0xcfcdf89700000000, 0xd0da081700000000, 0xb0e5694d00000000, + 0xaff299cd00000000, 0x709babf900000000, 0x6f8c5b7900000000, + 0x0fb33a2300000000, 0x10a4caa300000000, 0xb1605e4b00000000, + 0xae77aecb00000000, 0xce48cf9100000000, 0xd15f3f1100000000, + 0x0e360d2500000000, 0x1121fda500000000, 0x711e9cff00000000, + 0x6e096c7f00000000, 0x7291c4f500000000, 0x6d86347500000000, + 0x0db9552f00000000, 0x12aea5af00000000, 0xcdc7979b00000000, + 0xd2d0671b00000000, 0xb2ef064100000000, 0xadf8f6c100000000, + 0x0c3c622900000000, 0x132b92a900000000, 0x7314f3f300000000, + 0x6c03037300000000, 0xb36a314700000000, 0xac7dc1c700000000, + 0xcc42a09d00000000, 0xd355501d00000000, 0x6ae900a700000000, + 0x75fef02700000000, 0x15c1917d00000000, 0x0ad661fd00000000, + 0xd5bf53c900000000, 0xcaa8a34900000000, 0xaa97c21300000000, + 0xb580329300000000, 0x1444a67b00000000, 0x0b5356fb00000000, + 0x6b6c37a100000000, 0x747bc72100000000, 0xab12f51500000000, + 0xb405059500000000, 0xd43a64cf00000000, 0xcb2d944f00000000, + 0xd7b53cc500000000, 0xc8a2cc4500000000, 0xa89dad1f00000000, + 0xb78a5d9f00000000, 0x68e36fab00000000, 0x77f49f2b00000000, + 0x17cbfe7100000000, 0x08dc0ef100000000, 0xa9189a1900000000, + 0xb60f6a9900000000, 0xd6300bc300000000, 0xc927fb4300000000, + 0x164ec97700000000, 0x095939f700000000, 0x696658ad00000000, + 0x7671a82d00000000, 0x1050786300000000, 0x0f4788e300000000, + 0x6f78e9b900000000, 0x706f193900000000, 0xaf062b0d00000000, + 0xb011db8d00000000, 0xd02ebad700000000, 0xcf394a5700000000, + 0x6efddebf00000000, 0x71ea2e3f00000000, 0x11d54f6500000000, + 0x0ec2bfe500000000, 0xd1ab8dd100000000, 0xcebc7d5100000000, + 0xae831c0b00000000, 0xb194ec8b00000000, 0xad0c440100000000, + 0xb21bb48100000000, 0xd224d5db00000000, 0xcd33255b00000000, + 0x125a176f00000000, 0x0d4de7ef00000000, 0x6d7286b500000000, + 0x7265763500000000, 0xd3a1e2dd00000000, 0xccb6125d00000000, + 0xac89730700000000, 0xb39e838700000000, 0x6cf7b1b300000000, + 0x73e0413300000000, 0x13df206900000000, 0x0cc8d0e900000000, + 0xdf9d80f400000000, 0xc08a707400000000, 0xa0b5112e00000000, + 0xbfa2e1ae00000000, 0x60cbd39a00000000, 0x7fdc231a00000000, + 0x1fe3424000000000, 0x00f4b2c000000000, 0xa130262800000000, + 0xbe27d6a800000000, 0xde18b7f200000000, 0xc10f477200000000, + 0x1e66754600000000, 0x017185c600000000, 0x614ee49c00000000, + 0x7e59141c00000000, 0x62c1bc9600000000, 0x7dd64c1600000000, + 0x1de92d4c00000000, 0x02feddcc00000000, 0xdd97eff800000000, + 0xc2801f7800000000, 0xa2bf7e2200000000, 0xbda88ea200000000, + 0x1c6c1a4a00000000, 0x037beaca00000000, 0x63448b9000000000, + 0x7c537b1000000000, 0xa33a492400000000, 0xbc2db9a400000000, + 0xdc12d8fe00000000, 0xc305287e00000000, 0xa524f83000000000, + 0xba3308b000000000, 0xda0c69ea00000000, 0xc51b996a00000000, + 0x1a72ab5e00000000, 0x05655bde00000000, 0x655a3a8400000000, + 0x7a4dca0400000000, 0xdb895eec00000000, 0xc49eae6c00000000, + 0xa4a1cf3600000000, 0xbbb63fb600000000, 0x64df0d8200000000, + 0x7bc8fd0200000000, 0x1bf79c5800000000, 0x04e06cd800000000, + 0x1878c45200000000, 0x076f34d200000000, 0x6750558800000000, + 0x7847a50800000000, 0xa72e973c00000000, 0xb83967bc00000000, + 0xd80606e600000000, 0xc711f66600000000, 0x66d5628e00000000, + 0x79c2920e00000000, 0x19fdf35400000000, 0x06ea03d400000000, + 0xd98331e000000000, 0xc694c16000000000, 0xa6aba03a00000000, + 0xb9bc50ba00000000}, + {0x0000000000000000, 0xe2fd888d00000000, 0x85fd60c000000000, + 0x6700e84d00000000, 0x4bfdb05b00000000, 0xa90038d600000000, + 0xce00d09b00000000, 0x2cfd581600000000, 0x96fa61b700000000, + 0x7407e93a00000000, 0x1307017700000000, 0xf1fa89fa00000000, + 0xdd07d1ec00000000, 0x3ffa596100000000, 0x58fab12c00000000, + 0xba0739a100000000, 0x6df3b2b500000000, 0x8f0e3a3800000000, + 0xe80ed27500000000, 0x0af35af800000000, 0x260e02ee00000000, + 0xc4f38a6300000000, 0xa3f3622e00000000, 0x410eeaa300000000, + 0xfb09d30200000000, 0x19f45b8f00000000, 0x7ef4b3c200000000, + 0x9c093b4f00000000, 0xb0f4635900000000, 0x5209ebd400000000, + 0x3509039900000000, 0xd7f48b1400000000, 0x9be014b000000000, + 0x791d9c3d00000000, 0x1e1d747000000000, 0xfce0fcfd00000000, + 0xd01da4eb00000000, 0x32e02c6600000000, 0x55e0c42b00000000, + 0xb71d4ca600000000, 0x0d1a750700000000, 0xefe7fd8a00000000, + 0x88e715c700000000, 0x6a1a9d4a00000000, 0x46e7c55c00000000, + 0xa41a4dd100000000, 0xc31aa59c00000000, 0x21e72d1100000000, + 0xf613a60500000000, 0x14ee2e8800000000, 0x73eec6c500000000, + 0x91134e4800000000, 0xbdee165e00000000, 0x5f139ed300000000, + 0x3813769e00000000, 0xdaeefe1300000000, 0x60e9c7b200000000, + 0x82144f3f00000000, 0xe514a77200000000, 0x07e92fff00000000, + 0x2b1477e900000000, 0xc9e9ff6400000000, 0xaee9172900000000, + 0x4c149fa400000000, 0x77c758bb00000000, 0x953ad03600000000, + 0xf23a387b00000000, 0x10c7b0f600000000, 0x3c3ae8e000000000, + 0xdec7606d00000000, 0xb9c7882000000000, 0x5b3a00ad00000000, + 0xe13d390c00000000, 0x03c0b18100000000, 0x64c059cc00000000, + 0x863dd14100000000, 0xaac0895700000000, 0x483d01da00000000, + 0x2f3de99700000000, 0xcdc0611a00000000, 0x1a34ea0e00000000, + 0xf8c9628300000000, 0x9fc98ace00000000, 0x7d34024300000000, + 0x51c95a5500000000, 0xb334d2d800000000, 0xd4343a9500000000, + 0x36c9b21800000000, 0x8cce8bb900000000, 0x6e33033400000000, + 0x0933eb7900000000, 0xebce63f400000000, 0xc7333be200000000, + 0x25ceb36f00000000, 0x42ce5b2200000000, 0xa033d3af00000000, + 0xec274c0b00000000, 0x0edac48600000000, 0x69da2ccb00000000, + 0x8b27a44600000000, 0xa7dafc5000000000, 0x452774dd00000000, + 0x22279c9000000000, 0xc0da141d00000000, 0x7add2dbc00000000, + 0x9820a53100000000, 0xff204d7c00000000, 0x1dddc5f100000000, + 0x31209de700000000, 0xd3dd156a00000000, 0xb4ddfd2700000000, + 0x562075aa00000000, 0x81d4febe00000000, 0x6329763300000000, + 0x04299e7e00000000, 0xe6d416f300000000, 0xca294ee500000000, + 0x28d4c66800000000, 0x4fd42e2500000000, 0xad29a6a800000000, + 0x172e9f0900000000, 0xf5d3178400000000, 0x92d3ffc900000000, + 0x702e774400000000, 0x5cd32f5200000000, 0xbe2ea7df00000000, + 0xd92e4f9200000000, 0x3bd3c71f00000000, 0xaf88c0ad00000000, + 0x4d75482000000000, 0x2a75a06d00000000, 0xc88828e000000000, + 0xe47570f600000000, 0x0688f87b00000000, 0x6188103600000000, + 0x837598bb00000000, 0x3972a11a00000000, 0xdb8f299700000000, + 0xbc8fc1da00000000, 0x5e72495700000000, 0x728f114100000000, + 0x907299cc00000000, 0xf772718100000000, 0x158ff90c00000000, + 0xc27b721800000000, 0x2086fa9500000000, 0x478612d800000000, + 0xa57b9a5500000000, 0x8986c24300000000, 0x6b7b4ace00000000, + 0x0c7ba28300000000, 0xee862a0e00000000, 0x548113af00000000, + 0xb67c9b2200000000, 0xd17c736f00000000, 0x3381fbe200000000, + 0x1f7ca3f400000000, 0xfd812b7900000000, 0x9a81c33400000000, + 0x787c4bb900000000, 0x3468d41d00000000, 0xd6955c9000000000, + 0xb195b4dd00000000, 0x53683c5000000000, 0x7f95644600000000, + 0x9d68eccb00000000, 0xfa68048600000000, 0x18958c0b00000000, + 0xa292b5aa00000000, 0x406f3d2700000000, 0x276fd56a00000000, + 0xc5925de700000000, 0xe96f05f100000000, 0x0b928d7c00000000, + 0x6c92653100000000, 0x8e6fedbc00000000, 0x599b66a800000000, + 0xbb66ee2500000000, 0xdc66066800000000, 0x3e9b8ee500000000, + 0x1266d6f300000000, 0xf09b5e7e00000000, 0x979bb63300000000, + 0x75663ebe00000000, 0xcf61071f00000000, 0x2d9c8f9200000000, + 0x4a9c67df00000000, 0xa861ef5200000000, 0x849cb74400000000, + 0x66613fc900000000, 0x0161d78400000000, 0xe39c5f0900000000, + 0xd84f981600000000, 0x3ab2109b00000000, 0x5db2f8d600000000, + 0xbf4f705b00000000, 0x93b2284d00000000, 0x714fa0c000000000, + 0x164f488d00000000, 0xf4b2c00000000000, 0x4eb5f9a100000000, + 0xac48712c00000000, 0xcb48996100000000, 0x29b511ec00000000, + 0x054849fa00000000, 0xe7b5c17700000000, 0x80b5293a00000000, + 0x6248a1b700000000, 0xb5bc2aa300000000, 0x5741a22e00000000, + 0x30414a6300000000, 0xd2bcc2ee00000000, 0xfe419af800000000, + 0x1cbc127500000000, 0x7bbcfa3800000000, 0x994172b500000000, + 0x23464b1400000000, 0xc1bbc39900000000, 0xa6bb2bd400000000, + 0x4446a35900000000, 0x68bbfb4f00000000, 0x8a4673c200000000, + 0xed469b8f00000000, 0x0fbb130200000000, 0x43af8ca600000000, + 0xa152042b00000000, 0xc652ec6600000000, 0x24af64eb00000000, + 0x08523cfd00000000, 0xeaafb47000000000, 0x8daf5c3d00000000, + 0x6f52d4b000000000, 0xd555ed1100000000, 0x37a8659c00000000, + 0x50a88dd100000000, 0xb255055c00000000, 0x9ea85d4a00000000, + 0x7c55d5c700000000, 0x1b553d8a00000000, 0xf9a8b50700000000, + 0x2e5c3e1300000000, 0xcca1b69e00000000, 0xaba15ed300000000, + 0x495cd65e00000000, 0x65a18e4800000000, 0x875c06c500000000, + 0xe05cee8800000000, 0x02a1660500000000, 0xb8a65fa400000000, + 0x5a5bd72900000000, 0x3d5b3f6400000000, 0xdfa6b7e900000000, + 0xf35befff00000000, 0x11a6677200000000, 0x76a68f3f00000000, + 0x945b07b200000000}, + {0x0000000000000000, 0xa90b894e00000000, 0x5217129d00000000, + 0xfb1c9bd300000000, 0xe52855e100000000, 0x4c23dcaf00000000, + 0xb73f477c00000000, 0x1e34ce3200000000, 0x8b57db1900000000, + 0x225c525700000000, 0xd940c98400000000, 0x704b40ca00000000, + 0x6e7f8ef800000000, 0xc77407b600000000, 0x3c689c6500000000, + 0x9563152b00000000, 0x16afb63300000000, 0xbfa43f7d00000000, + 0x44b8a4ae00000000, 0xedb32de000000000, 0xf387e3d200000000, + 0x5a8c6a9c00000000, 0xa190f14f00000000, 0x089b780100000000, + 0x9df86d2a00000000, 0x34f3e46400000000, 0xcfef7fb700000000, + 0x66e4f6f900000000, 0x78d038cb00000000, 0xd1dbb18500000000, + 0x2ac72a5600000000, 0x83cca31800000000, 0x2c5e6d6700000000, + 0x8555e42900000000, 0x7e497ffa00000000, 0xd742f6b400000000, + 0xc976388600000000, 0x607db1c800000000, 0x9b612a1b00000000, + 0x326aa35500000000, 0xa709b67e00000000, 0x0e023f3000000000, + 0xf51ea4e300000000, 0x5c152dad00000000, 0x4221e39f00000000, + 0xeb2a6ad100000000, 0x1036f10200000000, 0xb93d784c00000000, + 0x3af1db5400000000, 0x93fa521a00000000, 0x68e6c9c900000000, + 0xc1ed408700000000, 0xdfd98eb500000000, 0x76d207fb00000000, + 0x8dce9c2800000000, 0x24c5156600000000, 0xb1a6004d00000000, + 0x18ad890300000000, 0xe3b112d000000000, 0x4aba9b9e00000000, + 0x548e55ac00000000, 0xfd85dce200000000, 0x0699473100000000, + 0xaf92ce7f00000000, 0x58bcdace00000000, 0xf1b7538000000000, + 0x0aabc85300000000, 0xa3a0411d00000000, 0xbd948f2f00000000, + 0x149f066100000000, 0xef839db200000000, 0x468814fc00000000, + 0xd3eb01d700000000, 0x7ae0889900000000, 0x81fc134a00000000, + 0x28f79a0400000000, 0x36c3543600000000, 0x9fc8dd7800000000, + 0x64d446ab00000000, 0xcddfcfe500000000, 0x4e136cfd00000000, + 0xe718e5b300000000, 0x1c047e6000000000, 0xb50ff72e00000000, + 0xab3b391c00000000, 0x0230b05200000000, 0xf92c2b8100000000, + 0x5027a2cf00000000, 0xc544b7e400000000, 0x6c4f3eaa00000000, + 0x9753a57900000000, 0x3e582c3700000000, 0x206ce20500000000, + 0x89676b4b00000000, 0x727bf09800000000, 0xdb7079d600000000, + 0x74e2b7a900000000, 0xdde93ee700000000, 0x26f5a53400000000, + 0x8ffe2c7a00000000, 0x91cae24800000000, 0x38c16b0600000000, + 0xc3ddf0d500000000, 0x6ad6799b00000000, 0xffb56cb000000000, + 0x56bee5fe00000000, 0xada27e2d00000000, 0x04a9f76300000000, + 0x1a9d395100000000, 0xb396b01f00000000, 0x488a2bcc00000000, + 0xe181a28200000000, 0x624d019a00000000, 0xcb4688d400000000, + 0x305a130700000000, 0x99519a4900000000, 0x8765547b00000000, + 0x2e6edd3500000000, 0xd57246e600000000, 0x7c79cfa800000000, + 0xe91ada8300000000, 0x401153cd00000000, 0xbb0dc81e00000000, + 0x1206415000000000, 0x0c328f6200000000, 0xa539062c00000000, + 0x5e259dff00000000, 0xf72e14b100000000, 0xf17ec44600000000, + 0x58754d0800000000, 0xa369d6db00000000, 0x0a625f9500000000, + 0x145691a700000000, 0xbd5d18e900000000, 0x4641833a00000000, + 0xef4a0a7400000000, 0x7a291f5f00000000, 0xd322961100000000, + 0x283e0dc200000000, 0x8135848c00000000, 0x9f014abe00000000, + 0x360ac3f000000000, 0xcd16582300000000, 0x641dd16d00000000, + 0xe7d1727500000000, 0x4edafb3b00000000, 0xb5c660e800000000, + 0x1ccde9a600000000, 0x02f9279400000000, 0xabf2aeda00000000, + 0x50ee350900000000, 0xf9e5bc4700000000, 0x6c86a96c00000000, + 0xc58d202200000000, 0x3e91bbf100000000, 0x979a32bf00000000, + 0x89aefc8d00000000, 0x20a575c300000000, 0xdbb9ee1000000000, + 0x72b2675e00000000, 0xdd20a92100000000, 0x742b206f00000000, + 0x8f37bbbc00000000, 0x263c32f200000000, 0x3808fcc000000000, + 0x9103758e00000000, 0x6a1fee5d00000000, 0xc314671300000000, + 0x5677723800000000, 0xff7cfb7600000000, 0x046060a500000000, + 0xad6be9eb00000000, 0xb35f27d900000000, 0x1a54ae9700000000, + 0xe148354400000000, 0x4843bc0a00000000, 0xcb8f1f1200000000, + 0x6284965c00000000, 0x99980d8f00000000, 0x309384c100000000, + 0x2ea74af300000000, 0x87acc3bd00000000, 0x7cb0586e00000000, + 0xd5bbd12000000000, 0x40d8c40b00000000, 0xe9d34d4500000000, + 0x12cfd69600000000, 0xbbc45fd800000000, 0xa5f091ea00000000, + 0x0cfb18a400000000, 0xf7e7837700000000, 0x5eec0a3900000000, + 0xa9c21e8800000000, 0x00c997c600000000, 0xfbd50c1500000000, + 0x52de855b00000000, 0x4cea4b6900000000, 0xe5e1c22700000000, + 0x1efd59f400000000, 0xb7f6d0ba00000000, 0x2295c59100000000, + 0x8b9e4cdf00000000, 0x7082d70c00000000, 0xd9895e4200000000, + 0xc7bd907000000000, 0x6eb6193e00000000, 0x95aa82ed00000000, + 0x3ca10ba300000000, 0xbf6da8bb00000000, 0x166621f500000000, + 0xed7aba2600000000, 0x4471336800000000, 0x5a45fd5a00000000, + 0xf34e741400000000, 0x0852efc700000000, 0xa159668900000000, + 0x343a73a200000000, 0x9d31faec00000000, 0x662d613f00000000, + 0xcf26e87100000000, 0xd112264300000000, 0x7819af0d00000000, + 0x830534de00000000, 0x2a0ebd9000000000, 0x859c73ef00000000, + 0x2c97faa100000000, 0xd78b617200000000, 0x7e80e83c00000000, + 0x60b4260e00000000, 0xc9bfaf4000000000, 0x32a3349300000000, + 0x9ba8bddd00000000, 0x0ecba8f600000000, 0xa7c021b800000000, + 0x5cdcba6b00000000, 0xf5d7332500000000, 0xebe3fd1700000000, + 0x42e8745900000000, 0xb9f4ef8a00000000, 0x10ff66c400000000, + 0x9333c5dc00000000, 0x3a384c9200000000, 0xc124d74100000000, + 0x682f5e0f00000000, 0x761b903d00000000, 0xdf10197300000000, + 0x240c82a000000000, 0x8d070bee00000000, 0x18641ec500000000, + 0xb16f978b00000000, 0x4a730c5800000000, 0xe378851600000000, + 0xfd4c4b2400000000, 0x5447c26a00000000, 0xaf5b59b900000000, + 0x0650d0f700000000}, + {0x0000000000000000, 0x479244af00000000, 0xcf22f88500000000, + 0x88b0bc2a00000000, 0xdf4381d000000000, 0x98d1c57f00000000, + 0x1061795500000000, 0x57f33dfa00000000, 0xff81737a00000000, + 0xb81337d500000000, 0x30a38bff00000000, 0x7731cf5000000000, + 0x20c2f2aa00000000, 0x6750b60500000000, 0xefe00a2f00000000, + 0xa8724e8000000000, 0xfe03e7f400000000, 0xb991a35b00000000, + 0x31211f7100000000, 0x76b35bde00000000, 0x2140662400000000, + 0x66d2228b00000000, 0xee629ea100000000, 0xa9f0da0e00000000, + 0x0182948e00000000, 0x4610d02100000000, 0xcea06c0b00000000, + 0x893228a400000000, 0xdec1155e00000000, 0x995351f100000000, + 0x11e3eddb00000000, 0x5671a97400000000, 0xbd01bf3200000000, + 0xfa93fb9d00000000, 0x722347b700000000, 0x35b1031800000000, + 0x62423ee200000000, 0x25d07a4d00000000, 0xad60c66700000000, + 0xeaf282c800000000, 0x4280cc4800000000, 0x051288e700000000, + 0x8da234cd00000000, 0xca30706200000000, 0x9dc34d9800000000, + 0xda51093700000000, 0x52e1b51d00000000, 0x1573f1b200000000, + 0x430258c600000000, 0x04901c6900000000, 0x8c20a04300000000, + 0xcbb2e4ec00000000, 0x9c41d91600000000, 0xdbd39db900000000, + 0x5363219300000000, 0x14f1653c00000000, 0xbc832bbc00000000, + 0xfb116f1300000000, 0x73a1d33900000000, 0x3433979600000000, + 0x63c0aa6c00000000, 0x2452eec300000000, 0xace252e900000000, + 0xeb70164600000000, 0x7a037e6500000000, 0x3d913aca00000000, + 0xb52186e000000000, 0xf2b3c24f00000000, 0xa540ffb500000000, + 0xe2d2bb1a00000000, 0x6a62073000000000, 0x2df0439f00000000, + 0x85820d1f00000000, 0xc21049b000000000, 0x4aa0f59a00000000, + 0x0d32b13500000000, 0x5ac18ccf00000000, 0x1d53c86000000000, + 0x95e3744a00000000, 0xd27130e500000000, 0x8400999100000000, + 0xc392dd3e00000000, 0x4b22611400000000, 0x0cb025bb00000000, + 0x5b43184100000000, 0x1cd15cee00000000, 0x9461e0c400000000, + 0xd3f3a46b00000000, 0x7b81eaeb00000000, 0x3c13ae4400000000, + 0xb4a3126e00000000, 0xf33156c100000000, 0xa4c26b3b00000000, + 0xe3502f9400000000, 0x6be093be00000000, 0x2c72d71100000000, + 0xc702c15700000000, 0x809085f800000000, 0x082039d200000000, + 0x4fb27d7d00000000, 0x1841408700000000, 0x5fd3042800000000, + 0xd763b80200000000, 0x90f1fcad00000000, 0x3883b22d00000000, + 0x7f11f68200000000, 0xf7a14aa800000000, 0xb0330e0700000000, + 0xe7c033fd00000000, 0xa052775200000000, 0x28e2cb7800000000, + 0x6f708fd700000000, 0x390126a300000000, 0x7e93620c00000000, + 0xf623de2600000000, 0xb1b19a8900000000, 0xe642a77300000000, + 0xa1d0e3dc00000000, 0x29605ff600000000, 0x6ef21b5900000000, + 0xc68055d900000000, 0x8112117600000000, 0x09a2ad5c00000000, + 0x4e30e9f300000000, 0x19c3d40900000000, 0x5e5190a600000000, + 0xd6e12c8c00000000, 0x9173682300000000, 0xf406fcca00000000, + 0xb394b86500000000, 0x3b24044f00000000, 0x7cb640e000000000, + 0x2b457d1a00000000, 0x6cd739b500000000, 0xe467859f00000000, + 0xa3f5c13000000000, 0x0b878fb000000000, 0x4c15cb1f00000000, + 0xc4a5773500000000, 0x8337339a00000000, 0xd4c40e6000000000, + 0x93564acf00000000, 0x1be6f6e500000000, 0x5c74b24a00000000, + 0x0a051b3e00000000, 0x4d975f9100000000, 0xc527e3bb00000000, + 0x82b5a71400000000, 0xd5469aee00000000, 0x92d4de4100000000, + 0x1a64626b00000000, 0x5df626c400000000, 0xf584684400000000, + 0xb2162ceb00000000, 0x3aa690c100000000, 0x7d34d46e00000000, + 0x2ac7e99400000000, 0x6d55ad3b00000000, 0xe5e5111100000000, + 0xa27755be00000000, 0x490743f800000000, 0x0e95075700000000, + 0x8625bb7d00000000, 0xc1b7ffd200000000, 0x9644c22800000000, + 0xd1d6868700000000, 0x59663aad00000000, 0x1ef47e0200000000, + 0xb686308200000000, 0xf114742d00000000, 0x79a4c80700000000, + 0x3e368ca800000000, 0x69c5b15200000000, 0x2e57f5fd00000000, + 0xa6e749d700000000, 0xe1750d7800000000, 0xb704a40c00000000, + 0xf096e0a300000000, 0x78265c8900000000, 0x3fb4182600000000, + 0x684725dc00000000, 0x2fd5617300000000, 0xa765dd5900000000, + 0xe0f799f600000000, 0x4885d77600000000, 0x0f1793d900000000, + 0x87a72ff300000000, 0xc0356b5c00000000, 0x97c656a600000000, + 0xd054120900000000, 0x58e4ae2300000000, 0x1f76ea8c00000000, + 0x8e0582af00000000, 0xc997c60000000000, 0x41277a2a00000000, + 0x06b53e8500000000, 0x5146037f00000000, 0x16d447d000000000, + 0x9e64fbfa00000000, 0xd9f6bf5500000000, 0x7184f1d500000000, + 0x3616b57a00000000, 0xbea6095000000000, 0xf9344dff00000000, + 0xaec7700500000000, 0xe95534aa00000000, 0x61e5888000000000, + 0x2677cc2f00000000, 0x7006655b00000000, 0x379421f400000000, + 0xbf249dde00000000, 0xf8b6d97100000000, 0xaf45e48b00000000, + 0xe8d7a02400000000, 0x60671c0e00000000, 0x27f558a100000000, + 0x8f87162100000000, 0xc815528e00000000, 0x40a5eea400000000, + 0x0737aa0b00000000, 0x50c497f100000000, 0x1756d35e00000000, + 0x9fe66f7400000000, 0xd8742bdb00000000, 0x33043d9d00000000, + 0x7496793200000000, 0xfc26c51800000000, 0xbbb481b700000000, + 0xec47bc4d00000000, 0xabd5f8e200000000, 0x236544c800000000, + 0x64f7006700000000, 0xcc854ee700000000, 0x8b170a4800000000, + 0x03a7b66200000000, 0x4435f2cd00000000, 0x13c6cf3700000000, + 0x54548b9800000000, 0xdce437b200000000, 0x9b76731d00000000, + 0xcd07da6900000000, 0x8a959ec600000000, 0x022522ec00000000, + 0x45b7664300000000, 0x12445bb900000000, 0x55d61f1600000000, + 0xdd66a33c00000000, 0x9af4e79300000000, 0x3286a91300000000, + 0x7514edbc00000000, 0xfda4519600000000, 0xba36153900000000, + 0xedc528c300000000, 0xaa576c6c00000000, 0x22e7d04600000000, + 0x657594e900000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x65673b46, 0xcace768c, 0xafa94dca, 0x4eedeb59, + 0x2b8ad01f, 0x84239dd5, 0xe144a693, 0x9ddbd6b2, 0xf8bcedf4, + 0x5715a03e, 0x32729b78, 0xd3363deb, 0xb65106ad, 0x19f84b67, + 0x7c9f7021, 0xe0c6ab25, 0x85a19063, 0x2a08dda9, 0x4f6fe6ef, + 0xae2b407c, 0xcb4c7b3a, 0x64e536f0, 0x01820db6, 0x7d1d7d97, + 0x187a46d1, 0xb7d30b1b, 0xd2b4305d, 0x33f096ce, 0x5697ad88, + 0xf93ee042, 0x9c59db04, 0x1afc500b, 0x7f9b6b4d, 0xd0322687, + 0xb5551dc1, 0x5411bb52, 0x31768014, 0x9edfcdde, 0xfbb8f698, + 0x872786b9, 0xe240bdff, 0x4de9f035, 0x288ecb73, 0xc9ca6de0, + 0xacad56a6, 0x03041b6c, 0x6663202a, 0xfa3afb2e, 0x9f5dc068, + 0x30f48da2, 0x5593b6e4, 0xb4d71077, 0xd1b02b31, 0x7e1966fb, + 0x1b7e5dbd, 0x67e12d9c, 0x028616da, 0xad2f5b10, 0xc8486056, + 0x290cc6c5, 0x4c6bfd83, 0xe3c2b049, 0x86a58b0f, 0x35f8a016, + 0x509f9b50, 0xff36d69a, 0x9a51eddc, 0x7b154b4f, 0x1e727009, + 0xb1db3dc3, 0xd4bc0685, 0xa82376a4, 0xcd444de2, 0x62ed0028, + 0x078a3b6e, 0xe6ce9dfd, 0x83a9a6bb, 0x2c00eb71, 0x4967d037, + 0xd53e0b33, 0xb0593075, 0x1ff07dbf, 0x7a9746f9, 0x9bd3e06a, + 0xfeb4db2c, 0x511d96e6, 0x347aada0, 0x48e5dd81, 0x2d82e6c7, + 0x822bab0d, 0xe74c904b, 0x060836d8, 0x636f0d9e, 0xccc64054, + 0xa9a17b12, 0x2f04f01d, 0x4a63cb5b, 0xe5ca8691, 0x80adbdd7, + 0x61e91b44, 0x048e2002, 0xab276dc8, 0xce40568e, 0xb2df26af, + 0xd7b81de9, 0x78115023, 0x1d766b65, 0xfc32cdf6, 0x9955f6b0, + 0x36fcbb7a, 0x539b803c, 0xcfc25b38, 0xaaa5607e, 0x050c2db4, + 0x606b16f2, 0x812fb061, 0xe4488b27, 0x4be1c6ed, 0x2e86fdab, + 0x52198d8a, 0x377eb6cc, 0x98d7fb06, 0xfdb0c040, 0x1cf466d3, + 0x79935d95, 0xd63a105f, 0xb35d2b19, 0x6bf1402c, 0x0e967b6a, + 0xa13f36a0, 0xc4580de6, 0x251cab75, 0x407b9033, 0xefd2ddf9, + 0x8ab5e6bf, 0xf62a969e, 0x934dadd8, 0x3ce4e012, 0x5983db54, + 0xb8c77dc7, 0xdda04681, 0x72090b4b, 0x176e300d, 0x8b37eb09, + 0xee50d04f, 0x41f99d85, 0x249ea6c3, 0xc5da0050, 0xa0bd3b16, + 0x0f1476dc, 0x6a734d9a, 0x16ec3dbb, 0x738b06fd, 0xdc224b37, + 0xb9457071, 0x5801d6e2, 0x3d66eda4, 0x92cfa06e, 0xf7a89b28, + 0x710d1027, 0x146a2b61, 0xbbc366ab, 0xdea45ded, 0x3fe0fb7e, + 0x5a87c038, 0xf52e8df2, 0x9049b6b4, 0xecd6c695, 0x89b1fdd3, + 0x2618b019, 0x437f8b5f, 0xa23b2dcc, 0xc75c168a, 0x68f55b40, + 0x0d926006, 0x91cbbb02, 0xf4ac8044, 0x5b05cd8e, 0x3e62f6c8, + 0xdf26505b, 0xba416b1d, 0x15e826d7, 0x708f1d91, 0x0c106db0, + 0x697756f6, 0xc6de1b3c, 0xa3b9207a, 0x42fd86e9, 0x279abdaf, + 0x8833f065, 0xed54cb23, 0x5e09e03a, 0x3b6edb7c, 0x94c796b6, + 0xf1a0adf0, 0x10e40b63, 0x75833025, 0xda2a7def, 0xbf4d46a9, + 0xc3d23688, 0xa6b50dce, 0x091c4004, 0x6c7b7b42, 0x8d3fddd1, + 0xe858e697, 0x47f1ab5d, 0x2296901b, 0xbecf4b1f, 0xdba87059, + 0x74013d93, 0x116606d5, 0xf022a046, 0x95459b00, 0x3aecd6ca, + 0x5f8bed8c, 0x23149dad, 0x4673a6eb, 0xe9daeb21, 0x8cbdd067, + 0x6df976f4, 0x089e4db2, 0xa7370078, 0xc2503b3e, 0x44f5b031, + 0x21928b77, 0x8e3bc6bd, 0xeb5cfdfb, 0x0a185b68, 0x6f7f602e, + 0xc0d62de4, 0xa5b116a2, 0xd92e6683, 0xbc495dc5, 0x13e0100f, + 0x76872b49, 0x97c38dda, 0xf2a4b69c, 0x5d0dfb56, 0x386ac010, + 0xa4331b14, 0xc1542052, 0x6efd6d98, 0x0b9a56de, 0xeadef04d, + 0x8fb9cb0b, 0x201086c1, 0x4577bd87, 0x39e8cda6, 0x5c8ff6e0, + 0xf326bb2a, 0x9641806c, 0x770526ff, 0x12621db9, 0xbdcb5073, + 0xd8ac6b35}, + {0x00000000, 0xd7e28058, 0x74b406f1, 0xa35686a9, 0xe9680de2, + 0x3e8a8dba, 0x9ddc0b13, 0x4a3e8b4b, 0x09a11d85, 0xde439ddd, + 0x7d151b74, 0xaaf79b2c, 0xe0c91067, 0x372b903f, 0x947d1696, + 0x439f96ce, 0x13423b0a, 0xc4a0bb52, 0x67f63dfb, 0xb014bda3, + 0xfa2a36e8, 0x2dc8b6b0, 0x8e9e3019, 0x597cb041, 0x1ae3268f, + 0xcd01a6d7, 0x6e57207e, 0xb9b5a026, 0xf38b2b6d, 0x2469ab35, + 0x873f2d9c, 0x50ddadc4, 0x26847614, 0xf166f64c, 0x523070e5, + 0x85d2f0bd, 0xcfec7bf6, 0x180efbae, 0xbb587d07, 0x6cbafd5f, + 0x2f256b91, 0xf8c7ebc9, 0x5b916d60, 0x8c73ed38, 0xc64d6673, + 0x11afe62b, 0xb2f96082, 0x651be0da, 0x35c64d1e, 0xe224cd46, + 0x41724bef, 0x9690cbb7, 0xdcae40fc, 0x0b4cc0a4, 0xa81a460d, + 0x7ff8c655, 0x3c67509b, 0xeb85d0c3, 0x48d3566a, 0x9f31d632, + 0xd50f5d79, 0x02eddd21, 0xa1bb5b88, 0x7659dbd0, 0x4d08ec28, + 0x9aea6c70, 0x39bcead9, 0xee5e6a81, 0xa460e1ca, 0x73826192, + 0xd0d4e73b, 0x07366763, 0x44a9f1ad, 0x934b71f5, 0x301df75c, + 0xe7ff7704, 0xadc1fc4f, 0x7a237c17, 0xd975fabe, 0x0e977ae6, + 0x5e4ad722, 0x89a8577a, 0x2afed1d3, 0xfd1c518b, 0xb722dac0, + 0x60c05a98, 0xc396dc31, 0x14745c69, 0x57ebcaa7, 0x80094aff, + 0x235fcc56, 0xf4bd4c0e, 0xbe83c745, 0x6961471d, 0xca37c1b4, + 0x1dd541ec, 0x6b8c9a3c, 0xbc6e1a64, 0x1f389ccd, 0xc8da1c95, + 0x82e497de, 0x55061786, 0xf650912f, 0x21b21177, 0x622d87b9, + 0xb5cf07e1, 0x16998148, 0xc17b0110, 0x8b458a5b, 0x5ca70a03, + 0xfff18caa, 0x28130cf2, 0x78cea136, 0xaf2c216e, 0x0c7aa7c7, + 0xdb98279f, 0x91a6acd4, 0x46442c8c, 0xe512aa25, 0x32f02a7d, + 0x716fbcb3, 0xa68d3ceb, 0x05dbba42, 0xd2393a1a, 0x9807b151, + 0x4fe53109, 0xecb3b7a0, 0x3b5137f8, 0x9a11d850, 0x4df35808, + 0xeea5dea1, 0x39475ef9, 0x7379d5b2, 0xa49b55ea, 0x07cdd343, + 0xd02f531b, 0x93b0c5d5, 0x4452458d, 0xe704c324, 0x30e6437c, + 0x7ad8c837, 0xad3a486f, 0x0e6ccec6, 0xd98e4e9e, 0x8953e35a, + 0x5eb16302, 0xfde7e5ab, 0x2a0565f3, 0x603beeb8, 0xb7d96ee0, + 0x148fe849, 0xc36d6811, 0x80f2fedf, 0x57107e87, 0xf446f82e, + 0x23a47876, 0x699af33d, 0xbe787365, 0x1d2ef5cc, 0xcacc7594, + 0xbc95ae44, 0x6b772e1c, 0xc821a8b5, 0x1fc328ed, 0x55fda3a6, + 0x821f23fe, 0x2149a557, 0xf6ab250f, 0xb534b3c1, 0x62d63399, + 0xc180b530, 0x16623568, 0x5c5cbe23, 0x8bbe3e7b, 0x28e8b8d2, + 0xff0a388a, 0xafd7954e, 0x78351516, 0xdb6393bf, 0x0c8113e7, + 0x46bf98ac, 0x915d18f4, 0x320b9e5d, 0xe5e91e05, 0xa67688cb, + 0x71940893, 0xd2c28e3a, 0x05200e62, 0x4f1e8529, 0x98fc0571, + 0x3baa83d8, 0xec480380, 0xd7193478, 0x00fbb420, 0xa3ad3289, + 0x744fb2d1, 0x3e71399a, 0xe993b9c2, 0x4ac53f6b, 0x9d27bf33, + 0xdeb829fd, 0x095aa9a5, 0xaa0c2f0c, 0x7deeaf54, 0x37d0241f, + 0xe032a447, 0x436422ee, 0x9486a2b6, 0xc45b0f72, 0x13b98f2a, + 0xb0ef0983, 0x670d89db, 0x2d330290, 0xfad182c8, 0x59870461, + 0x8e658439, 0xcdfa12f7, 0x1a1892af, 0xb94e1406, 0x6eac945e, + 0x24921f15, 0xf3709f4d, 0x502619e4, 0x87c499bc, 0xf19d426c, + 0x267fc234, 0x8529449d, 0x52cbc4c5, 0x18f54f8e, 0xcf17cfd6, + 0x6c41497f, 0xbba3c927, 0xf83c5fe9, 0x2fdedfb1, 0x8c885918, + 0x5b6ad940, 0x1154520b, 0xc6b6d253, 0x65e054fa, 0xb202d4a2, + 0xe2df7966, 0x353df93e, 0x966b7f97, 0x4189ffcf, 0x0bb77484, + 0xdc55f4dc, 0x7f037275, 0xa8e1f22d, 0xeb7e64e3, 0x3c9ce4bb, + 0x9fca6212, 0x4828e24a, 0x02166901, 0xd5f4e959, 0x76a26ff0, + 0xa140efa8}, + {0x00000000, 0xef52b6e1, 0x05d46b83, 0xea86dd62, 0x0ba8d706, + 0xe4fa61e7, 0x0e7cbc85, 0xe12e0a64, 0x1751ae0c, 0xf80318ed, + 0x1285c58f, 0xfdd7736e, 0x1cf9790a, 0xf3abcfeb, 0x192d1289, + 0xf67fa468, 0x2ea35c18, 0xc1f1eaf9, 0x2b77379b, 0xc425817a, + 0x250b8b1e, 0xca593dff, 0x20dfe09d, 0xcf8d567c, 0x39f2f214, + 0xd6a044f5, 0x3c269997, 0xd3742f76, 0x325a2512, 0xdd0893f3, + 0x378e4e91, 0xd8dcf870, 0x5d46b830, 0xb2140ed1, 0x5892d3b3, + 0xb7c06552, 0x56ee6f36, 0xb9bcd9d7, 0x533a04b5, 0xbc68b254, + 0x4a17163c, 0xa545a0dd, 0x4fc37dbf, 0xa091cb5e, 0x41bfc13a, + 0xaeed77db, 0x446baab9, 0xab391c58, 0x73e5e428, 0x9cb752c9, + 0x76318fab, 0x9963394a, 0x784d332e, 0x971f85cf, 0x7d9958ad, + 0x92cbee4c, 0x64b44a24, 0x8be6fcc5, 0x616021a7, 0x8e329746, + 0x6f1c9d22, 0x804e2bc3, 0x6ac8f6a1, 0x859a4040, 0xba8d7060, + 0x55dfc681, 0xbf591be3, 0x500bad02, 0xb125a766, 0x5e771187, + 0xb4f1cce5, 0x5ba37a04, 0xaddcde6c, 0x428e688d, 0xa808b5ef, + 0x475a030e, 0xa674096a, 0x4926bf8b, 0xa3a062e9, 0x4cf2d408, + 0x942e2c78, 0x7b7c9a99, 0x91fa47fb, 0x7ea8f11a, 0x9f86fb7e, + 0x70d44d9f, 0x9a5290fd, 0x7500261c, 0x837f8274, 0x6c2d3495, + 0x86abe9f7, 0x69f95f16, 0x88d75572, 0x6785e393, 0x8d033ef1, + 0x62518810, 0xe7cbc850, 0x08997eb1, 0xe21fa3d3, 0x0d4d1532, + 0xec631f56, 0x0331a9b7, 0xe9b774d5, 0x06e5c234, 0xf09a665c, + 0x1fc8d0bd, 0xf54e0ddf, 0x1a1cbb3e, 0xfb32b15a, 0x146007bb, + 0xfee6dad9, 0x11b46c38, 0xc9689448, 0x263a22a9, 0xccbcffcb, + 0x23ee492a, 0xc2c0434e, 0x2d92f5af, 0xc71428cd, 0x28469e2c, + 0xde393a44, 0x316b8ca5, 0xdbed51c7, 0x34bfe726, 0xd591ed42, + 0x3ac35ba3, 0xd04586c1, 0x3f173020, 0xae6be681, 0x41395060, + 0xabbf8d02, 0x44ed3be3, 0xa5c33187, 0x4a918766, 0xa0175a04, + 0x4f45ece5, 0xb93a488d, 0x5668fe6c, 0xbcee230e, 0x53bc95ef, + 0xb2929f8b, 0x5dc0296a, 0xb746f408, 0x581442e9, 0x80c8ba99, + 0x6f9a0c78, 0x851cd11a, 0x6a4e67fb, 0x8b606d9f, 0x6432db7e, + 0x8eb4061c, 0x61e6b0fd, 0x97991495, 0x78cba274, 0x924d7f16, + 0x7d1fc9f7, 0x9c31c393, 0x73637572, 0x99e5a810, 0x76b71ef1, + 0xf32d5eb1, 0x1c7fe850, 0xf6f93532, 0x19ab83d3, 0xf88589b7, + 0x17d73f56, 0xfd51e234, 0x120354d5, 0xe47cf0bd, 0x0b2e465c, + 0xe1a89b3e, 0x0efa2ddf, 0xefd427bb, 0x0086915a, 0xea004c38, + 0x0552fad9, 0xdd8e02a9, 0x32dcb448, 0xd85a692a, 0x3708dfcb, + 0xd626d5af, 0x3974634e, 0xd3f2be2c, 0x3ca008cd, 0xcadfaca5, + 0x258d1a44, 0xcf0bc726, 0x205971c7, 0xc1777ba3, 0x2e25cd42, + 0xc4a31020, 0x2bf1a6c1, 0x14e696e1, 0xfbb42000, 0x1132fd62, + 0xfe604b83, 0x1f4e41e7, 0xf01cf706, 0x1a9a2a64, 0xf5c89c85, + 0x03b738ed, 0xece58e0c, 0x0663536e, 0xe931e58f, 0x081fefeb, + 0xe74d590a, 0x0dcb8468, 0xe2993289, 0x3a45caf9, 0xd5177c18, + 0x3f91a17a, 0xd0c3179b, 0x31ed1dff, 0xdebfab1e, 0x3439767c, + 0xdb6bc09d, 0x2d1464f5, 0xc246d214, 0x28c00f76, 0xc792b997, + 0x26bcb3f3, 0xc9ee0512, 0x2368d870, 0xcc3a6e91, 0x49a02ed1, + 0xa6f29830, 0x4c744552, 0xa326f3b3, 0x4208f9d7, 0xad5a4f36, + 0x47dc9254, 0xa88e24b5, 0x5ef180dd, 0xb1a3363c, 0x5b25eb5e, + 0xb4775dbf, 0x555957db, 0xba0be13a, 0x508d3c58, 0xbfdf8ab9, + 0x670372c9, 0x8851c428, 0x62d7194a, 0x8d85afab, 0x6caba5cf, + 0x83f9132e, 0x697fce4c, 0x862d78ad, 0x7052dcc5, 0x9f006a24, + 0x7586b746, 0x9ad401a7, 0x7bfa0bc3, 0x94a8bd22, 0x7e2e6040, + 0x917cd6a1}, + {0x00000000, 0x87a6cb43, 0xd43c90c7, 0x539a5b84, 0x730827cf, + 0xf4aeec8c, 0xa734b708, 0x20927c4b, 0xe6104f9e, 0x61b684dd, + 0x322cdf59, 0xb58a141a, 0x95186851, 0x12bea312, 0x4124f896, + 0xc68233d5, 0x1751997d, 0x90f7523e, 0xc36d09ba, 0x44cbc2f9, + 0x6459beb2, 0xe3ff75f1, 0xb0652e75, 0x37c3e536, 0xf141d6e3, + 0x76e71da0, 0x257d4624, 0xa2db8d67, 0x8249f12c, 0x05ef3a6f, + 0x567561eb, 0xd1d3aaa8, 0x2ea332fa, 0xa905f9b9, 0xfa9fa23d, + 0x7d39697e, 0x5dab1535, 0xda0dde76, 0x899785f2, 0x0e314eb1, + 0xc8b37d64, 0x4f15b627, 0x1c8feda3, 0x9b2926e0, 0xbbbb5aab, + 0x3c1d91e8, 0x6f87ca6c, 0xe821012f, 0x39f2ab87, 0xbe5460c4, + 0xedce3b40, 0x6a68f003, 0x4afa8c48, 0xcd5c470b, 0x9ec61c8f, + 0x1960d7cc, 0xdfe2e419, 0x58442f5a, 0x0bde74de, 0x8c78bf9d, + 0xaceac3d6, 0x2b4c0895, 0x78d65311, 0xff709852, 0x5d4665f4, + 0xdae0aeb7, 0x897af533, 0x0edc3e70, 0x2e4e423b, 0xa9e88978, + 0xfa72d2fc, 0x7dd419bf, 0xbb562a6a, 0x3cf0e129, 0x6f6abaad, + 0xe8cc71ee, 0xc85e0da5, 0x4ff8c6e6, 0x1c629d62, 0x9bc45621, + 0x4a17fc89, 0xcdb137ca, 0x9e2b6c4e, 0x198da70d, 0x391fdb46, + 0xbeb91005, 0xed234b81, 0x6a8580c2, 0xac07b317, 0x2ba17854, + 0x783b23d0, 0xff9de893, 0xdf0f94d8, 0x58a95f9b, 0x0b33041f, + 0x8c95cf5c, 0x73e5570e, 0xf4439c4d, 0xa7d9c7c9, 0x207f0c8a, + 0x00ed70c1, 0x874bbb82, 0xd4d1e006, 0x53772b45, 0x95f51890, + 0x1253d3d3, 0x41c98857, 0xc66f4314, 0xe6fd3f5f, 0x615bf41c, + 0x32c1af98, 0xb56764db, 0x64b4ce73, 0xe3120530, 0xb0885eb4, + 0x372e95f7, 0x17bce9bc, 0x901a22ff, 0xc380797b, 0x4426b238, + 0x82a481ed, 0x05024aae, 0x5698112a, 0xd13eda69, 0xf1aca622, + 0x760a6d61, 0x259036e5, 0xa236fda6, 0xba8ccbe8, 0x3d2a00ab, + 0x6eb05b2f, 0xe916906c, 0xc984ec27, 0x4e222764, 0x1db87ce0, + 0x9a1eb7a3, 0x5c9c8476, 0xdb3a4f35, 0x88a014b1, 0x0f06dff2, + 0x2f94a3b9, 0xa83268fa, 0xfba8337e, 0x7c0ef83d, 0xaddd5295, + 0x2a7b99d6, 0x79e1c252, 0xfe470911, 0xded5755a, 0x5973be19, + 0x0ae9e59d, 0x8d4f2ede, 0x4bcd1d0b, 0xcc6bd648, 0x9ff18dcc, + 0x1857468f, 0x38c53ac4, 0xbf63f187, 0xecf9aa03, 0x6b5f6140, + 0x942ff912, 0x13893251, 0x401369d5, 0xc7b5a296, 0xe727dedd, + 0x6081159e, 0x331b4e1a, 0xb4bd8559, 0x723fb68c, 0xf5997dcf, + 0xa603264b, 0x21a5ed08, 0x01379143, 0x86915a00, 0xd50b0184, + 0x52adcac7, 0x837e606f, 0x04d8ab2c, 0x5742f0a8, 0xd0e43beb, + 0xf07647a0, 0x77d08ce3, 0x244ad767, 0xa3ec1c24, 0x656e2ff1, + 0xe2c8e4b2, 0xb152bf36, 0x36f47475, 0x1666083e, 0x91c0c37d, + 0xc25a98f9, 0x45fc53ba, 0xe7caae1c, 0x606c655f, 0x33f63edb, + 0xb450f598, 0x94c289d3, 0x13644290, 0x40fe1914, 0xc758d257, + 0x01dae182, 0x867c2ac1, 0xd5e67145, 0x5240ba06, 0x72d2c64d, + 0xf5740d0e, 0xa6ee568a, 0x21489dc9, 0xf09b3761, 0x773dfc22, + 0x24a7a7a6, 0xa3016ce5, 0x839310ae, 0x0435dbed, 0x57af8069, + 0xd0094b2a, 0x168b78ff, 0x912db3bc, 0xc2b7e838, 0x4511237b, + 0x65835f30, 0xe2259473, 0xb1bfcff7, 0x361904b4, 0xc9699ce6, + 0x4ecf57a5, 0x1d550c21, 0x9af3c762, 0xba61bb29, 0x3dc7706a, + 0x6e5d2bee, 0xe9fbe0ad, 0x2f79d378, 0xa8df183b, 0xfb4543bf, + 0x7ce388fc, 0x5c71f4b7, 0xdbd73ff4, 0x884d6470, 0x0febaf33, + 0xde38059b, 0x599eced8, 0x0a04955c, 0x8da25e1f, 0xad302254, + 0x2a96e917, 0x790cb293, 0xfeaa79d0, 0x38284a05, 0xbf8e8146, + 0xec14dac2, 0x6bb21181, 0x4b206dca, 0xcc86a689, 0x9f1cfd0d, + 0x18ba364e}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x43cba687, 0xc7903cd4, 0x845b9a53, 0xcf270873, + 0x8cecaef4, 0x08b734a7, 0x4b7c9220, 0x9e4f10e6, 0xdd84b661, + 0x59df2c32, 0x1a148ab5, 0x51681895, 0x12a3be12, 0x96f82441, + 0xd53382c6, 0x7d995117, 0x3e52f790, 0xba096dc3, 0xf9c2cb44, + 0xb2be5964, 0xf175ffe3, 0x752e65b0, 0x36e5c337, 0xe3d641f1, + 0xa01de776, 0x24467d25, 0x678ddba2, 0x2cf14982, 0x6f3aef05, + 0xeb617556, 0xa8aad3d1, 0xfa32a32e, 0xb9f905a9, 0x3da29ffa, + 0x7e69397d, 0x3515ab5d, 0x76de0dda, 0xf2859789, 0xb14e310e, + 0x647db3c8, 0x27b6154f, 0xa3ed8f1c, 0xe026299b, 0xab5abbbb, + 0xe8911d3c, 0x6cca876f, 0x2f0121e8, 0x87abf239, 0xc46054be, + 0x403bceed, 0x03f0686a, 0x488cfa4a, 0x0b475ccd, 0x8f1cc69e, + 0xccd76019, 0x19e4e2df, 0x5a2f4458, 0xde74de0b, 0x9dbf788c, + 0xd6c3eaac, 0x95084c2b, 0x1153d678, 0x529870ff, 0xf465465d, + 0xb7aee0da, 0x33f57a89, 0x703edc0e, 0x3b424e2e, 0x7889e8a9, + 0xfcd272fa, 0xbf19d47d, 0x6a2a56bb, 0x29e1f03c, 0xadba6a6f, + 0xee71cce8, 0xa50d5ec8, 0xe6c6f84f, 0x629d621c, 0x2156c49b, + 0x89fc174a, 0xca37b1cd, 0x4e6c2b9e, 0x0da78d19, 0x46db1f39, + 0x0510b9be, 0x814b23ed, 0xc280856a, 0x17b307ac, 0x5478a12b, + 0xd0233b78, 0x93e89dff, 0xd8940fdf, 0x9b5fa958, 0x1f04330b, + 0x5ccf958c, 0x0e57e573, 0x4d9c43f4, 0xc9c7d9a7, 0x8a0c7f20, + 0xc170ed00, 0x82bb4b87, 0x06e0d1d4, 0x452b7753, 0x9018f595, + 0xd3d35312, 0x5788c941, 0x14436fc6, 0x5f3ffde6, 0x1cf45b61, + 0x98afc132, 0xdb6467b5, 0x73ceb464, 0x300512e3, 0xb45e88b0, + 0xf7952e37, 0xbce9bc17, 0xff221a90, 0x7b7980c3, 0x38b22644, + 0xed81a482, 0xae4a0205, 0x2a119856, 0x69da3ed1, 0x22a6acf1, + 0x616d0a76, 0xe5369025, 0xa6fd36a2, 0xe8cb8cba, 0xab002a3d, + 0x2f5bb06e, 0x6c9016e9, 0x27ec84c9, 0x6427224e, 0xe07cb81d, + 0xa3b71e9a, 0x76849c5c, 0x354f3adb, 0xb114a088, 0xf2df060f, + 0xb9a3942f, 0xfa6832a8, 0x7e33a8fb, 0x3df80e7c, 0x9552ddad, + 0xd6997b2a, 0x52c2e179, 0x110947fe, 0x5a75d5de, 0x19be7359, + 0x9de5e90a, 0xde2e4f8d, 0x0b1dcd4b, 0x48d66bcc, 0xcc8df19f, + 0x8f465718, 0xc43ac538, 0x87f163bf, 0x03aaf9ec, 0x40615f6b, + 0x12f92f94, 0x51328913, 0xd5691340, 0x96a2b5c7, 0xddde27e7, + 0x9e158160, 0x1a4e1b33, 0x5985bdb4, 0x8cb63f72, 0xcf7d99f5, + 0x4b2603a6, 0x08eda521, 0x43913701, 0x005a9186, 0x84010bd5, + 0xc7caad52, 0x6f607e83, 0x2cabd804, 0xa8f04257, 0xeb3be4d0, + 0xa04776f0, 0xe38cd077, 0x67d74a24, 0x241ceca3, 0xf12f6e65, + 0xb2e4c8e2, 0x36bf52b1, 0x7574f436, 0x3e086616, 0x7dc3c091, + 0xf9985ac2, 0xba53fc45, 0x1caecae7, 0x5f656c60, 0xdb3ef633, + 0x98f550b4, 0xd389c294, 0x90426413, 0x1419fe40, 0x57d258c7, + 0x82e1da01, 0xc12a7c86, 0x4571e6d5, 0x06ba4052, 0x4dc6d272, + 0x0e0d74f5, 0x8a56eea6, 0xc99d4821, 0x61379bf0, 0x22fc3d77, + 0xa6a7a724, 0xe56c01a3, 0xae109383, 0xeddb3504, 0x6980af57, + 0x2a4b09d0, 0xff788b16, 0xbcb32d91, 0x38e8b7c2, 0x7b231145, + 0x305f8365, 0x739425e2, 0xf7cfbfb1, 0xb4041936, 0xe69c69c9, + 0xa557cf4e, 0x210c551d, 0x62c7f39a, 0x29bb61ba, 0x6a70c73d, + 0xee2b5d6e, 0xade0fbe9, 0x78d3792f, 0x3b18dfa8, 0xbf4345fb, + 0xfc88e37c, 0xb7f4715c, 0xf43fd7db, 0x70644d88, 0x33afeb0f, + 0x9b0538de, 0xd8ce9e59, 0x5c95040a, 0x1f5ea28d, 0x542230ad, + 0x17e9962a, 0x93b20c79, 0xd079aafe, 0x054a2838, 0x46818ebf, + 0xc2da14ec, 0x8111b26b, 0xca6d204b, 0x89a686cc, 0x0dfd1c9f, + 0x4e36ba18}, + {0x00000000, 0xe1b652ef, 0x836bd405, 0x62dd86ea, 0x06d7a80b, + 0xe761fae4, 0x85bc7c0e, 0x640a2ee1, 0x0cae5117, 0xed1803f8, + 0x8fc58512, 0x6e73d7fd, 0x0a79f91c, 0xebcfabf3, 0x89122d19, + 0x68a47ff6, 0x185ca32e, 0xf9eaf1c1, 0x9b37772b, 0x7a8125c4, + 0x1e8b0b25, 0xff3d59ca, 0x9de0df20, 0x7c568dcf, 0x14f2f239, + 0xf544a0d6, 0x9799263c, 0x762f74d3, 0x12255a32, 0xf39308dd, + 0x914e8e37, 0x70f8dcd8, 0x30b8465d, 0xd10e14b2, 0xb3d39258, + 0x5265c0b7, 0x366fee56, 0xd7d9bcb9, 0xb5043a53, 0x54b268bc, + 0x3c16174a, 0xdda045a5, 0xbf7dc34f, 0x5ecb91a0, 0x3ac1bf41, + 0xdb77edae, 0xb9aa6b44, 0x581c39ab, 0x28e4e573, 0xc952b79c, + 0xab8f3176, 0x4a396399, 0x2e334d78, 0xcf851f97, 0xad58997d, + 0x4ceecb92, 0x244ab464, 0xc5fce68b, 0xa7216061, 0x4697328e, + 0x229d1c6f, 0xc32b4e80, 0xa1f6c86a, 0x40409a85, 0x60708dba, + 0x81c6df55, 0xe31b59bf, 0x02ad0b50, 0x66a725b1, 0x8711775e, + 0xe5ccf1b4, 0x047aa35b, 0x6cdedcad, 0x8d688e42, 0xefb508a8, + 0x0e035a47, 0x6a0974a6, 0x8bbf2649, 0xe962a0a3, 0x08d4f24c, + 0x782c2e94, 0x999a7c7b, 0xfb47fa91, 0x1af1a87e, 0x7efb869f, + 0x9f4dd470, 0xfd90529a, 0x1c260075, 0x74827f83, 0x95342d6c, + 0xf7e9ab86, 0x165ff969, 0x7255d788, 0x93e38567, 0xf13e038d, + 0x10885162, 0x50c8cbe7, 0xb17e9908, 0xd3a31fe2, 0x32154d0d, + 0x561f63ec, 0xb7a93103, 0xd574b7e9, 0x34c2e506, 0x5c669af0, + 0xbdd0c81f, 0xdf0d4ef5, 0x3ebb1c1a, 0x5ab132fb, 0xbb076014, + 0xd9dae6fe, 0x386cb411, 0x489468c9, 0xa9223a26, 0xcbffbccc, + 0x2a49ee23, 0x4e43c0c2, 0xaff5922d, 0xcd2814c7, 0x2c9e4628, + 0x443a39de, 0xa58c6b31, 0xc751eddb, 0x26e7bf34, 0x42ed91d5, + 0xa35bc33a, 0xc18645d0, 0x2030173f, 0x81e66bae, 0x60503941, + 0x028dbfab, 0xe33bed44, 0x8731c3a5, 0x6687914a, 0x045a17a0, + 0xe5ec454f, 0x8d483ab9, 0x6cfe6856, 0x0e23eebc, 0xef95bc53, + 0x8b9f92b2, 0x6a29c05d, 0x08f446b7, 0xe9421458, 0x99bac880, + 0x780c9a6f, 0x1ad11c85, 0xfb674e6a, 0x9f6d608b, 0x7edb3264, + 0x1c06b48e, 0xfdb0e661, 0x95149997, 0x74a2cb78, 0x167f4d92, + 0xf7c91f7d, 0x93c3319c, 0x72756373, 0x10a8e599, 0xf11eb776, + 0xb15e2df3, 0x50e87f1c, 0x3235f9f6, 0xd383ab19, 0xb78985f8, + 0x563fd717, 0x34e251fd, 0xd5540312, 0xbdf07ce4, 0x5c462e0b, + 0x3e9ba8e1, 0xdf2dfa0e, 0xbb27d4ef, 0x5a918600, 0x384c00ea, + 0xd9fa5205, 0xa9028edd, 0x48b4dc32, 0x2a695ad8, 0xcbdf0837, + 0xafd526d6, 0x4e637439, 0x2cbef2d3, 0xcd08a03c, 0xa5acdfca, + 0x441a8d25, 0x26c70bcf, 0xc7715920, 0xa37b77c1, 0x42cd252e, + 0x2010a3c4, 0xc1a6f12b, 0xe196e614, 0x0020b4fb, 0x62fd3211, + 0x834b60fe, 0xe7414e1f, 0x06f71cf0, 0x642a9a1a, 0x859cc8f5, + 0xed38b703, 0x0c8ee5ec, 0x6e536306, 0x8fe531e9, 0xebef1f08, + 0x0a594de7, 0x6884cb0d, 0x893299e2, 0xf9ca453a, 0x187c17d5, + 0x7aa1913f, 0x9b17c3d0, 0xff1ded31, 0x1eabbfde, 0x7c763934, + 0x9dc06bdb, 0xf564142d, 0x14d246c2, 0x760fc028, 0x97b992c7, + 0xf3b3bc26, 0x1205eec9, 0x70d86823, 0x916e3acc, 0xd12ea049, + 0x3098f2a6, 0x5245744c, 0xb3f326a3, 0xd7f90842, 0x364f5aad, + 0x5492dc47, 0xb5248ea8, 0xdd80f15e, 0x3c36a3b1, 0x5eeb255b, + 0xbf5d77b4, 0xdb575955, 0x3ae10bba, 0x583c8d50, 0xb98adfbf, + 0xc9720367, 0x28c45188, 0x4a19d762, 0xabaf858d, 0xcfa5ab6c, + 0x2e13f983, 0x4cce7f69, 0xad782d86, 0xc5dc5270, 0x246a009f, + 0x46b78675, 0xa701d49a, 0xc30bfa7b, 0x22bda894, 0x40602e7e, + 0xa1d67c91}, + {0x00000000, 0x5880e2d7, 0xf106b474, 0xa98656a3, 0xe20d68e9, + 0xba8d8a3e, 0x130bdc9d, 0x4b8b3e4a, 0x851da109, 0xdd9d43de, + 0x741b157d, 0x2c9bf7aa, 0x6710c9e0, 0x3f902b37, 0x96167d94, + 0xce969f43, 0x0a3b4213, 0x52bba0c4, 0xfb3df667, 0xa3bd14b0, + 0xe8362afa, 0xb0b6c82d, 0x19309e8e, 0x41b07c59, 0x8f26e31a, + 0xd7a601cd, 0x7e20576e, 0x26a0b5b9, 0x6d2b8bf3, 0x35ab6924, + 0x9c2d3f87, 0xc4addd50, 0x14768426, 0x4cf666f1, 0xe5703052, + 0xbdf0d285, 0xf67beccf, 0xaefb0e18, 0x077d58bb, 0x5ffdba6c, + 0x916b252f, 0xc9ebc7f8, 0x606d915b, 0x38ed738c, 0x73664dc6, + 0x2be6af11, 0x8260f9b2, 0xdae01b65, 0x1e4dc635, 0x46cd24e2, + 0xef4b7241, 0xb7cb9096, 0xfc40aedc, 0xa4c04c0b, 0x0d461aa8, + 0x55c6f87f, 0x9b50673c, 0xc3d085eb, 0x6a56d348, 0x32d6319f, + 0x795d0fd5, 0x21dded02, 0x885bbba1, 0xd0db5976, 0x28ec084d, + 0x706cea9a, 0xd9eabc39, 0x816a5eee, 0xcae160a4, 0x92618273, + 0x3be7d4d0, 0x63673607, 0xadf1a944, 0xf5714b93, 0x5cf71d30, + 0x0477ffe7, 0x4ffcc1ad, 0x177c237a, 0xbefa75d9, 0xe67a970e, + 0x22d74a5e, 0x7a57a889, 0xd3d1fe2a, 0x8b511cfd, 0xc0da22b7, + 0x985ac060, 0x31dc96c3, 0x695c7414, 0xa7caeb57, 0xff4a0980, + 0x56cc5f23, 0x0e4cbdf4, 0x45c783be, 0x1d476169, 0xb4c137ca, + 0xec41d51d, 0x3c9a8c6b, 0x641a6ebc, 0xcd9c381f, 0x951cdac8, + 0xde97e482, 0x86170655, 0x2f9150f6, 0x7711b221, 0xb9872d62, + 0xe107cfb5, 0x48819916, 0x10017bc1, 0x5b8a458b, 0x030aa75c, + 0xaa8cf1ff, 0xf20c1328, 0x36a1ce78, 0x6e212caf, 0xc7a77a0c, + 0x9f2798db, 0xd4aca691, 0x8c2c4446, 0x25aa12e5, 0x7d2af032, + 0xb3bc6f71, 0xeb3c8da6, 0x42badb05, 0x1a3a39d2, 0x51b10798, + 0x0931e54f, 0xa0b7b3ec, 0xf837513b, 0x50d8119a, 0x0858f34d, + 0xa1dea5ee, 0xf95e4739, 0xb2d57973, 0xea559ba4, 0x43d3cd07, + 0x1b532fd0, 0xd5c5b093, 0x8d455244, 0x24c304e7, 0x7c43e630, + 0x37c8d87a, 0x6f483aad, 0xc6ce6c0e, 0x9e4e8ed9, 0x5ae35389, + 0x0263b15e, 0xabe5e7fd, 0xf365052a, 0xb8ee3b60, 0xe06ed9b7, + 0x49e88f14, 0x11686dc3, 0xdffef280, 0x877e1057, 0x2ef846f4, + 0x7678a423, 0x3df39a69, 0x657378be, 0xccf52e1d, 0x9475ccca, + 0x44ae95bc, 0x1c2e776b, 0xb5a821c8, 0xed28c31f, 0xa6a3fd55, + 0xfe231f82, 0x57a54921, 0x0f25abf6, 0xc1b334b5, 0x9933d662, + 0x30b580c1, 0x68356216, 0x23be5c5c, 0x7b3ebe8b, 0xd2b8e828, + 0x8a380aff, 0x4e95d7af, 0x16153578, 0xbf9363db, 0xe713810c, + 0xac98bf46, 0xf4185d91, 0x5d9e0b32, 0x051ee9e5, 0xcb8876a6, + 0x93089471, 0x3a8ec2d2, 0x620e2005, 0x29851e4f, 0x7105fc98, + 0xd883aa3b, 0x800348ec, 0x783419d7, 0x20b4fb00, 0x8932ada3, + 0xd1b24f74, 0x9a39713e, 0xc2b993e9, 0x6b3fc54a, 0x33bf279d, + 0xfd29b8de, 0xa5a95a09, 0x0c2f0caa, 0x54afee7d, 0x1f24d037, + 0x47a432e0, 0xee226443, 0xb6a28694, 0x720f5bc4, 0x2a8fb913, + 0x8309efb0, 0xdb890d67, 0x9002332d, 0xc882d1fa, 0x61048759, + 0x3984658e, 0xf712facd, 0xaf92181a, 0x06144eb9, 0x5e94ac6e, + 0x151f9224, 0x4d9f70f3, 0xe4192650, 0xbc99c487, 0x6c429df1, + 0x34c27f26, 0x9d442985, 0xc5c4cb52, 0x8e4ff518, 0xd6cf17cf, + 0x7f49416c, 0x27c9a3bb, 0xe95f3cf8, 0xb1dfde2f, 0x1859888c, + 0x40d96a5b, 0x0b525411, 0x53d2b6c6, 0xfa54e065, 0xa2d402b2, + 0x6679dfe2, 0x3ef93d35, 0x977f6b96, 0xcfff8941, 0x8474b70b, + 0xdcf455dc, 0x7572037f, 0x2df2e1a8, 0xe3647eeb, 0xbbe49c3c, + 0x1262ca9f, 0x4ae22848, 0x01691602, 0x59e9f4d5, 0xf06fa276, + 0xa8ef40a1}, + {0x00000000, 0x463b6765, 0x8c76ceca, 0xca4da9af, 0x59ebed4e, + 0x1fd08a2b, 0xd59d2384, 0x93a644e1, 0xb2d6db9d, 0xf4edbcf8, + 0x3ea01557, 0x789b7232, 0xeb3d36d3, 0xad0651b6, 0x674bf819, + 0x21709f7c, 0x25abc6e0, 0x6390a185, 0xa9dd082a, 0xefe66f4f, + 0x7c402bae, 0x3a7b4ccb, 0xf036e564, 0xb60d8201, 0x977d1d7d, + 0xd1467a18, 0x1b0bd3b7, 0x5d30b4d2, 0xce96f033, 0x88ad9756, + 0x42e03ef9, 0x04db599c, 0x0b50fc1a, 0x4d6b9b7f, 0x872632d0, + 0xc11d55b5, 0x52bb1154, 0x14807631, 0xdecddf9e, 0x98f6b8fb, + 0xb9862787, 0xffbd40e2, 0x35f0e94d, 0x73cb8e28, 0xe06dcac9, + 0xa656adac, 0x6c1b0403, 0x2a206366, 0x2efb3afa, 0x68c05d9f, + 0xa28df430, 0xe4b69355, 0x7710d7b4, 0x312bb0d1, 0xfb66197e, + 0xbd5d7e1b, 0x9c2de167, 0xda168602, 0x105b2fad, 0x566048c8, + 0xc5c60c29, 0x83fd6b4c, 0x49b0c2e3, 0x0f8ba586, 0x16a0f835, + 0x509b9f50, 0x9ad636ff, 0xdced519a, 0x4f4b157b, 0x0970721e, + 0xc33ddbb1, 0x8506bcd4, 0xa47623a8, 0xe24d44cd, 0x2800ed62, + 0x6e3b8a07, 0xfd9dcee6, 0xbba6a983, 0x71eb002c, 0x37d06749, + 0x330b3ed5, 0x753059b0, 0xbf7df01f, 0xf946977a, 0x6ae0d39b, + 0x2cdbb4fe, 0xe6961d51, 0xa0ad7a34, 0x81dde548, 0xc7e6822d, + 0x0dab2b82, 0x4b904ce7, 0xd8360806, 0x9e0d6f63, 0x5440c6cc, + 0x127ba1a9, 0x1df0042f, 0x5bcb634a, 0x9186cae5, 0xd7bdad80, + 0x441be961, 0x02208e04, 0xc86d27ab, 0x8e5640ce, 0xaf26dfb2, + 0xe91db8d7, 0x23501178, 0x656b761d, 0xf6cd32fc, 0xb0f65599, + 0x7abbfc36, 0x3c809b53, 0x385bc2cf, 0x7e60a5aa, 0xb42d0c05, + 0xf2166b60, 0x61b02f81, 0x278b48e4, 0xedc6e14b, 0xabfd862e, + 0x8a8d1952, 0xccb67e37, 0x06fbd798, 0x40c0b0fd, 0xd366f41c, + 0x955d9379, 0x5f103ad6, 0x192b5db3, 0x2c40f16b, 0x6a7b960e, + 0xa0363fa1, 0xe60d58c4, 0x75ab1c25, 0x33907b40, 0xf9ddd2ef, + 0xbfe6b58a, 0x9e962af6, 0xd8ad4d93, 0x12e0e43c, 0x54db8359, + 0xc77dc7b8, 0x8146a0dd, 0x4b0b0972, 0x0d306e17, 0x09eb378b, + 0x4fd050ee, 0x859df941, 0xc3a69e24, 0x5000dac5, 0x163bbda0, + 0xdc76140f, 0x9a4d736a, 0xbb3dec16, 0xfd068b73, 0x374b22dc, + 0x717045b9, 0xe2d60158, 0xa4ed663d, 0x6ea0cf92, 0x289ba8f7, + 0x27100d71, 0x612b6a14, 0xab66c3bb, 0xed5da4de, 0x7efbe03f, + 0x38c0875a, 0xf28d2ef5, 0xb4b64990, 0x95c6d6ec, 0xd3fdb189, + 0x19b01826, 0x5f8b7f43, 0xcc2d3ba2, 0x8a165cc7, 0x405bf568, + 0x0660920d, 0x02bbcb91, 0x4480acf4, 0x8ecd055b, 0xc8f6623e, + 0x5b5026df, 0x1d6b41ba, 0xd726e815, 0x911d8f70, 0xb06d100c, + 0xf6567769, 0x3c1bdec6, 0x7a20b9a3, 0xe986fd42, 0xafbd9a27, + 0x65f03388, 0x23cb54ed, 0x3ae0095e, 0x7cdb6e3b, 0xb696c794, + 0xf0ada0f1, 0x630be410, 0x25308375, 0xef7d2ada, 0xa9464dbf, + 0x8836d2c3, 0xce0db5a6, 0x04401c09, 0x427b7b6c, 0xd1dd3f8d, + 0x97e658e8, 0x5dabf147, 0x1b909622, 0x1f4bcfbe, 0x5970a8db, + 0x933d0174, 0xd5066611, 0x46a022f0, 0x009b4595, 0xcad6ec3a, + 0x8ced8b5f, 0xad9d1423, 0xeba67346, 0x21ebdae9, 0x67d0bd8c, + 0xf476f96d, 0xb24d9e08, 0x780037a7, 0x3e3b50c2, 0x31b0f544, + 0x778b9221, 0xbdc63b8e, 0xfbfd5ceb, 0x685b180a, 0x2e607f6f, + 0xe42dd6c0, 0xa216b1a5, 0x83662ed9, 0xc55d49bc, 0x0f10e013, + 0x492b8776, 0xda8dc397, 0x9cb6a4f2, 0x56fb0d5d, 0x10c06a38, + 0x141b33a4, 0x522054c1, 0x986dfd6e, 0xde569a0b, 0x4df0deea, + 0x0bcbb98f, 0xc1861020, 0x87bd7745, 0xa6cde839, 0xe0f68f5c, + 0x2abb26f3, 0x6c804196, 0xff260577, 0xb91d6212, 0x7350cbbd, + 0x356bacd8}}; + +#endif /* W */ + +#endif /* N == 5 */ +#if N == 6 + +#if W == 8 + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x3db1ecdc, 0x7b63d9b8, 0x46d23564, 0xf6c7b370, + 0xcb765fac, 0x8da46ac8, 0xb0158614, 0x36fe60a1, 0x0b4f8c7d, + 0x4d9db919, 0x702c55c5, 0xc039d3d1, 0xfd883f0d, 0xbb5a0a69, + 0x86ebe6b5, 0x6dfcc142, 0x504d2d9e, 0x169f18fa, 0x2b2ef426, + 0x9b3b7232, 0xa68a9eee, 0xe058ab8a, 0xdde94756, 0x5b02a1e3, + 0x66b34d3f, 0x2061785b, 0x1dd09487, 0xadc51293, 0x9074fe4f, + 0xd6a6cb2b, 0xeb1727f7, 0xdbf98284, 0xe6486e58, 0xa09a5b3c, + 0x9d2bb7e0, 0x2d3e31f4, 0x108fdd28, 0x565de84c, 0x6bec0490, + 0xed07e225, 0xd0b60ef9, 0x96643b9d, 0xabd5d741, 0x1bc05155, + 0x2671bd89, 0x60a388ed, 0x5d126431, 0xb60543c6, 0x8bb4af1a, + 0xcd669a7e, 0xf0d776a2, 0x40c2f0b6, 0x7d731c6a, 0x3ba1290e, + 0x0610c5d2, 0x80fb2367, 0xbd4acfbb, 0xfb98fadf, 0xc6291603, + 0x763c9017, 0x4b8d7ccb, 0x0d5f49af, 0x30eea573, 0x6c820349, + 0x5133ef95, 0x17e1daf1, 0x2a50362d, 0x9a45b039, 0xa7f45ce5, + 0xe1266981, 0xdc97855d, 0x5a7c63e8, 0x67cd8f34, 0x211fba50, + 0x1cae568c, 0xacbbd098, 0x910a3c44, 0xd7d80920, 0xea69e5fc, + 0x017ec20b, 0x3ccf2ed7, 0x7a1d1bb3, 0x47acf76f, 0xf7b9717b, + 0xca089da7, 0x8cdaa8c3, 0xb16b441f, 0x3780a2aa, 0x0a314e76, + 0x4ce37b12, 0x715297ce, 0xc14711da, 0xfcf6fd06, 0xba24c862, + 0x879524be, 0xb77b81cd, 0x8aca6d11, 0xcc185875, 0xf1a9b4a9, + 0x41bc32bd, 0x7c0dde61, 0x3adfeb05, 0x076e07d9, 0x8185e16c, + 0xbc340db0, 0xfae638d4, 0xc757d408, 0x7742521c, 0x4af3bec0, + 0x0c218ba4, 0x31906778, 0xda87408f, 0xe736ac53, 0xa1e49937, + 0x9c5575eb, 0x2c40f3ff, 0x11f11f23, 0x57232a47, 0x6a92c69b, + 0xec79202e, 0xd1c8ccf2, 0x971af996, 0xaaab154a, 0x1abe935e, + 0x270f7f82, 0x61dd4ae6, 0x5c6ca63a, 0xd9040692, 0xe4b5ea4e, + 0xa267df2a, 0x9fd633f6, 0x2fc3b5e2, 0x1272593e, 0x54a06c5a, + 0x69118086, 0xeffa6633, 0xd24b8aef, 0x9499bf8b, 0xa9285357, + 0x193dd543, 0x248c399f, 0x625e0cfb, 0x5fefe027, 0xb4f8c7d0, + 0x89492b0c, 0xcf9b1e68, 0xf22af2b4, 0x423f74a0, 0x7f8e987c, + 0x395cad18, 0x04ed41c4, 0x8206a771, 0xbfb74bad, 0xf9657ec9, + 0xc4d49215, 0x74c11401, 0x4970f8dd, 0x0fa2cdb9, 0x32132165, + 0x02fd8416, 0x3f4c68ca, 0x799e5dae, 0x442fb172, 0xf43a3766, + 0xc98bdbba, 0x8f59eede, 0xb2e80202, 0x3403e4b7, 0x09b2086b, + 0x4f603d0f, 0x72d1d1d3, 0xc2c457c7, 0xff75bb1b, 0xb9a78e7f, + 0x841662a3, 0x6f014554, 0x52b0a988, 0x14629cec, 0x29d37030, + 0x99c6f624, 0xa4771af8, 0xe2a52f9c, 0xdf14c340, 0x59ff25f5, + 0x644ec929, 0x229cfc4d, 0x1f2d1091, 0xaf389685, 0x92897a59, + 0xd45b4f3d, 0xe9eaa3e1, 0xb58605db, 0x8837e907, 0xcee5dc63, + 0xf35430bf, 0x4341b6ab, 0x7ef05a77, 0x38226f13, 0x059383cf, + 0x8378657a, 0xbec989a6, 0xf81bbcc2, 0xc5aa501e, 0x75bfd60a, + 0x480e3ad6, 0x0edc0fb2, 0x336de36e, 0xd87ac499, 0xe5cb2845, + 0xa3191d21, 0x9ea8f1fd, 0x2ebd77e9, 0x130c9b35, 0x55deae51, + 0x686f428d, 0xee84a438, 0xd33548e4, 0x95e77d80, 0xa856915c, + 0x18431748, 0x25f2fb94, 0x6320cef0, 0x5e91222c, 0x6e7f875f, + 0x53ce6b83, 0x151c5ee7, 0x28adb23b, 0x98b8342f, 0xa509d8f3, + 0xe3dbed97, 0xde6a014b, 0x5881e7fe, 0x65300b22, 0x23e23e46, + 0x1e53d29a, 0xae46548e, 0x93f7b852, 0xd5258d36, 0xe89461ea, + 0x0383461d, 0x3e32aac1, 0x78e09fa5, 0x45517379, 0xf544f56d, + 0xc8f519b1, 0x8e272cd5, 0xb396c009, 0x357d26bc, 0x08ccca60, + 0x4e1eff04, 0x73af13d8, 0xc3ba95cc, 0xfe0b7910, 0xb8d94c74, + 0x8568a0a8}, + {0x00000000, 0x69790b65, 0xd2f216ca, 0xbb8b1daf, 0x7e952bd5, + 0x17ec20b0, 0xac673d1f, 0xc51e367a, 0xfd2a57aa, 0x94535ccf, + 0x2fd84160, 0x46a14a05, 0x83bf7c7f, 0xeac6771a, 0x514d6ab5, + 0x383461d0, 0x2125a915, 0x485ca270, 0xf3d7bfdf, 0x9aaeb4ba, + 0x5fb082c0, 0x36c989a5, 0x8d42940a, 0xe43b9f6f, 0xdc0ffebf, + 0xb576f5da, 0x0efde875, 0x6784e310, 0xa29ad56a, 0xcbe3de0f, + 0x7068c3a0, 0x1911c8c5, 0x424b522a, 0x2b32594f, 0x90b944e0, + 0xf9c04f85, 0x3cde79ff, 0x55a7729a, 0xee2c6f35, 0x87556450, + 0xbf610580, 0xd6180ee5, 0x6d93134a, 0x04ea182f, 0xc1f42e55, + 0xa88d2530, 0x1306389f, 0x7a7f33fa, 0x636efb3f, 0x0a17f05a, + 0xb19cedf5, 0xd8e5e690, 0x1dfbd0ea, 0x7482db8f, 0xcf09c620, + 0xa670cd45, 0x9e44ac95, 0xf73da7f0, 0x4cb6ba5f, 0x25cfb13a, + 0xe0d18740, 0x89a88c25, 0x3223918a, 0x5b5a9aef, 0x8496a454, + 0xedefaf31, 0x5664b29e, 0x3f1db9fb, 0xfa038f81, 0x937a84e4, + 0x28f1994b, 0x4188922e, 0x79bcf3fe, 0x10c5f89b, 0xab4ee534, + 0xc237ee51, 0x0729d82b, 0x6e50d34e, 0xd5dbcee1, 0xbca2c584, + 0xa5b30d41, 0xccca0624, 0x77411b8b, 0x1e3810ee, 0xdb262694, + 0xb25f2df1, 0x09d4305e, 0x60ad3b3b, 0x58995aeb, 0x31e0518e, + 0x8a6b4c21, 0xe3124744, 0x260c713e, 0x4f757a5b, 0xf4fe67f4, + 0x9d876c91, 0xc6ddf67e, 0xafa4fd1b, 0x142fe0b4, 0x7d56ebd1, + 0xb848ddab, 0xd131d6ce, 0x6abacb61, 0x03c3c004, 0x3bf7a1d4, + 0x528eaab1, 0xe905b71e, 0x807cbc7b, 0x45628a01, 0x2c1b8164, + 0x97909ccb, 0xfee997ae, 0xe7f85f6b, 0x8e81540e, 0x350a49a1, + 0x5c7342c4, 0x996d74be, 0xf0147fdb, 0x4b9f6274, 0x22e66911, + 0x1ad208c1, 0x73ab03a4, 0xc8201e0b, 0xa159156e, 0x64472314, + 0x0d3e2871, 0xb6b535de, 0xdfcc3ebb, 0xd25c4ee9, 0xbb25458c, + 0x00ae5823, 0x69d75346, 0xacc9653c, 0xc5b06e59, 0x7e3b73f6, + 0x17427893, 0x2f761943, 0x460f1226, 0xfd840f89, 0x94fd04ec, + 0x51e33296, 0x389a39f3, 0x8311245c, 0xea682f39, 0xf379e7fc, + 0x9a00ec99, 0x218bf136, 0x48f2fa53, 0x8deccc29, 0xe495c74c, + 0x5f1edae3, 0x3667d186, 0x0e53b056, 0x672abb33, 0xdca1a69c, + 0xb5d8adf9, 0x70c69b83, 0x19bf90e6, 0xa2348d49, 0xcb4d862c, + 0x90171cc3, 0xf96e17a6, 0x42e50a09, 0x2b9c016c, 0xee823716, + 0x87fb3c73, 0x3c7021dc, 0x55092ab9, 0x6d3d4b69, 0x0444400c, + 0xbfcf5da3, 0xd6b656c6, 0x13a860bc, 0x7ad16bd9, 0xc15a7676, + 0xa8237d13, 0xb132b5d6, 0xd84bbeb3, 0x63c0a31c, 0x0ab9a879, + 0xcfa79e03, 0xa6de9566, 0x1d5588c9, 0x742c83ac, 0x4c18e27c, + 0x2561e919, 0x9eeaf4b6, 0xf793ffd3, 0x328dc9a9, 0x5bf4c2cc, + 0xe07fdf63, 0x8906d406, 0x56caeabd, 0x3fb3e1d8, 0x8438fc77, + 0xed41f712, 0x285fc168, 0x4126ca0d, 0xfaadd7a2, 0x93d4dcc7, + 0xabe0bd17, 0xc299b672, 0x7912abdd, 0x106ba0b8, 0xd57596c2, + 0xbc0c9da7, 0x07878008, 0x6efe8b6d, 0x77ef43a8, 0x1e9648cd, + 0xa51d5562, 0xcc645e07, 0x097a687d, 0x60036318, 0xdb887eb7, + 0xb2f175d2, 0x8ac51402, 0xe3bc1f67, 0x583702c8, 0x314e09ad, + 0xf4503fd7, 0x9d2934b2, 0x26a2291d, 0x4fdb2278, 0x1481b897, + 0x7df8b3f2, 0xc673ae5d, 0xaf0aa538, 0x6a149342, 0x036d9827, + 0xb8e68588, 0xd19f8eed, 0xe9abef3d, 0x80d2e458, 0x3b59f9f7, + 0x5220f292, 0x973ec4e8, 0xfe47cf8d, 0x45ccd222, 0x2cb5d947, + 0x35a41182, 0x5cdd1ae7, 0xe7560748, 0x8e2f0c2d, 0x4b313a57, + 0x22483132, 0x99c32c9d, 0xf0ba27f8, 0xc88e4628, 0xa1f74d4d, + 0x1a7c50e2, 0x73055b87, 0xb61b6dfd, 0xdf626698, 0x64e97b37, + 0x0d907052}, + {0x00000000, 0x7fc99b93, 0xff933726, 0x805aacb5, 0x2457680d, + 0x5b9ef39e, 0xdbc45f2b, 0xa40dc4b8, 0x48aed01a, 0x37674b89, + 0xb73de73c, 0xc8f47caf, 0x6cf9b817, 0x13302384, 0x936a8f31, + 0xeca314a2, 0x915da034, 0xee943ba7, 0x6ece9712, 0x11070c81, + 0xb50ac839, 0xcac353aa, 0x4a99ff1f, 0x3550648c, 0xd9f3702e, + 0xa63aebbd, 0x26604708, 0x59a9dc9b, 0xfda41823, 0x826d83b0, + 0x02372f05, 0x7dfeb496, 0xf9ca4629, 0x8603ddba, 0x0659710f, + 0x7990ea9c, 0xdd9d2e24, 0xa254b5b7, 0x220e1902, 0x5dc78291, + 0xb1649633, 0xcead0da0, 0x4ef7a115, 0x313e3a86, 0x9533fe3e, + 0xeafa65ad, 0x6aa0c918, 0x1569528b, 0x6897e61d, 0x175e7d8e, + 0x9704d13b, 0xe8cd4aa8, 0x4cc08e10, 0x33091583, 0xb353b936, + 0xcc9a22a5, 0x20393607, 0x5ff0ad94, 0xdfaa0121, 0xa0639ab2, + 0x046e5e0a, 0x7ba7c599, 0xfbfd692c, 0x8434f2bf, 0x28e58a13, + 0x572c1180, 0xd776bd35, 0xa8bf26a6, 0x0cb2e21e, 0x737b798d, + 0xf321d538, 0x8ce84eab, 0x604b5a09, 0x1f82c19a, 0x9fd86d2f, + 0xe011f6bc, 0x441c3204, 0x3bd5a997, 0xbb8f0522, 0xc4469eb1, + 0xb9b82a27, 0xc671b1b4, 0x462b1d01, 0x39e28692, 0x9def422a, + 0xe226d9b9, 0x627c750c, 0x1db5ee9f, 0xf116fa3d, 0x8edf61ae, + 0x0e85cd1b, 0x714c5688, 0xd5419230, 0xaa8809a3, 0x2ad2a516, + 0x551b3e85, 0xd12fcc3a, 0xaee657a9, 0x2ebcfb1c, 0x5175608f, + 0xf578a437, 0x8ab13fa4, 0x0aeb9311, 0x75220882, 0x99811c20, + 0xe64887b3, 0x66122b06, 0x19dbb095, 0xbdd6742d, 0xc21fefbe, + 0x4245430b, 0x3d8cd898, 0x40726c0e, 0x3fbbf79d, 0xbfe15b28, + 0xc028c0bb, 0x64250403, 0x1bec9f90, 0x9bb63325, 0xe47fa8b6, + 0x08dcbc14, 0x77152787, 0xf74f8b32, 0x888610a1, 0x2c8bd419, + 0x53424f8a, 0xd318e33f, 0xacd178ac, 0x51cb1426, 0x2e028fb5, + 0xae582300, 0xd191b893, 0x759c7c2b, 0x0a55e7b8, 0x8a0f4b0d, + 0xf5c6d09e, 0x1965c43c, 0x66ac5faf, 0xe6f6f31a, 0x993f6889, + 0x3d32ac31, 0x42fb37a2, 0xc2a19b17, 0xbd680084, 0xc096b412, + 0xbf5f2f81, 0x3f058334, 0x40cc18a7, 0xe4c1dc1f, 0x9b08478c, + 0x1b52eb39, 0x649b70aa, 0x88386408, 0xf7f1ff9b, 0x77ab532e, + 0x0862c8bd, 0xac6f0c05, 0xd3a69796, 0x53fc3b23, 0x2c35a0b0, + 0xa801520f, 0xd7c8c99c, 0x57926529, 0x285bfeba, 0x8c563a02, + 0xf39fa191, 0x73c50d24, 0x0c0c96b7, 0xe0af8215, 0x9f661986, + 0x1f3cb533, 0x60f52ea0, 0xc4f8ea18, 0xbb31718b, 0x3b6bdd3e, + 0x44a246ad, 0x395cf23b, 0x469569a8, 0xc6cfc51d, 0xb9065e8e, + 0x1d0b9a36, 0x62c201a5, 0xe298ad10, 0x9d513683, 0x71f22221, + 0x0e3bb9b2, 0x8e611507, 0xf1a88e94, 0x55a54a2c, 0x2a6cd1bf, + 0xaa367d0a, 0xd5ffe699, 0x792e9e35, 0x06e705a6, 0x86bda913, + 0xf9743280, 0x5d79f638, 0x22b06dab, 0xa2eac11e, 0xdd235a8d, + 0x31804e2f, 0x4e49d5bc, 0xce137909, 0xb1dae29a, 0x15d72622, + 0x6a1ebdb1, 0xea441104, 0x958d8a97, 0xe8733e01, 0x97baa592, + 0x17e00927, 0x682992b4, 0xcc24560c, 0xb3edcd9f, 0x33b7612a, + 0x4c7efab9, 0xa0ddee1b, 0xdf147588, 0x5f4ed93d, 0x208742ae, + 0x848a8616, 0xfb431d85, 0x7b19b130, 0x04d02aa3, 0x80e4d81c, + 0xff2d438f, 0x7f77ef3a, 0x00be74a9, 0xa4b3b011, 0xdb7a2b82, + 0x5b208737, 0x24e91ca4, 0xc84a0806, 0xb7839395, 0x37d93f20, + 0x4810a4b3, 0xec1d600b, 0x93d4fb98, 0x138e572d, 0x6c47ccbe, + 0x11b97828, 0x6e70e3bb, 0xee2a4f0e, 0x91e3d49d, 0x35ee1025, + 0x4a278bb6, 0xca7d2703, 0xb5b4bc90, 0x5917a832, 0x26de33a1, + 0xa6849f14, 0xd94d0487, 0x7d40c03f, 0x02895bac, 0x82d3f719, + 0xfd1a6c8a}, + {0x00000000, 0xa396284c, 0x9c5d56d9, 0x3fcb7e95, 0xe3cbabf3, + 0x405d83bf, 0x7f96fd2a, 0xdc00d566, 0x1ce651a7, 0xbf7079eb, + 0x80bb077e, 0x232d2f32, 0xff2dfa54, 0x5cbbd218, 0x6370ac8d, + 0xc0e684c1, 0x39cca34e, 0x9a5a8b02, 0xa591f597, 0x0607dddb, + 0xda0708bd, 0x799120f1, 0x465a5e64, 0xe5cc7628, 0x252af2e9, + 0x86bcdaa5, 0xb977a430, 0x1ae18c7c, 0xc6e1591a, 0x65777156, + 0x5abc0fc3, 0xf92a278f, 0x7399469c, 0xd00f6ed0, 0xefc41045, + 0x4c523809, 0x9052ed6f, 0x33c4c523, 0x0c0fbbb6, 0xaf9993fa, + 0x6f7f173b, 0xcce93f77, 0xf32241e2, 0x50b469ae, 0x8cb4bcc8, + 0x2f229484, 0x10e9ea11, 0xb37fc25d, 0x4a55e5d2, 0xe9c3cd9e, + 0xd608b30b, 0x759e9b47, 0xa99e4e21, 0x0a08666d, 0x35c318f8, + 0x965530b4, 0x56b3b475, 0xf5259c39, 0xcaeee2ac, 0x6978cae0, + 0xb5781f86, 0x16ee37ca, 0x2925495f, 0x8ab36113, 0xe7328d38, + 0x44a4a574, 0x7b6fdbe1, 0xd8f9f3ad, 0x04f926cb, 0xa76f0e87, + 0x98a47012, 0x3b32585e, 0xfbd4dc9f, 0x5842f4d3, 0x67898a46, + 0xc41fa20a, 0x181f776c, 0xbb895f20, 0x844221b5, 0x27d409f9, + 0xdefe2e76, 0x7d68063a, 0x42a378af, 0xe13550e3, 0x3d358585, + 0x9ea3adc9, 0xa168d35c, 0x02fefb10, 0xc2187fd1, 0x618e579d, + 0x5e452908, 0xfdd30144, 0x21d3d422, 0x8245fc6e, 0xbd8e82fb, + 0x1e18aab7, 0x94abcba4, 0x373de3e8, 0x08f69d7d, 0xab60b531, + 0x77606057, 0xd4f6481b, 0xeb3d368e, 0x48ab1ec2, 0x884d9a03, + 0x2bdbb24f, 0x1410ccda, 0xb786e496, 0x6b8631f0, 0xc81019bc, + 0xf7db6729, 0x544d4f65, 0xad6768ea, 0x0ef140a6, 0x313a3e33, + 0x92ac167f, 0x4eacc319, 0xed3aeb55, 0xd2f195c0, 0x7167bd8c, + 0xb181394d, 0x12171101, 0x2ddc6f94, 0x8e4a47d8, 0x524a92be, + 0xf1dcbaf2, 0xce17c467, 0x6d81ec2b, 0x15141c31, 0xb682347d, + 0x89494ae8, 0x2adf62a4, 0xf6dfb7c2, 0x55499f8e, 0x6a82e11b, + 0xc914c957, 0x09f24d96, 0xaa6465da, 0x95af1b4f, 0x36393303, + 0xea39e665, 0x49afce29, 0x7664b0bc, 0xd5f298f0, 0x2cd8bf7f, + 0x8f4e9733, 0xb085e9a6, 0x1313c1ea, 0xcf13148c, 0x6c853cc0, + 0x534e4255, 0xf0d86a19, 0x303eeed8, 0x93a8c694, 0xac63b801, + 0x0ff5904d, 0xd3f5452b, 0x70636d67, 0x4fa813f2, 0xec3e3bbe, + 0x668d5aad, 0xc51b72e1, 0xfad00c74, 0x59462438, 0x8546f15e, + 0x26d0d912, 0x191ba787, 0xba8d8fcb, 0x7a6b0b0a, 0xd9fd2346, + 0xe6365dd3, 0x45a0759f, 0x99a0a0f9, 0x3a3688b5, 0x05fdf620, + 0xa66bde6c, 0x5f41f9e3, 0xfcd7d1af, 0xc31caf3a, 0x608a8776, + 0xbc8a5210, 0x1f1c7a5c, 0x20d704c9, 0x83412c85, 0x43a7a844, + 0xe0318008, 0xdffafe9d, 0x7c6cd6d1, 0xa06c03b7, 0x03fa2bfb, + 0x3c31556e, 0x9fa77d22, 0xf2269109, 0x51b0b945, 0x6e7bc7d0, + 0xcdedef9c, 0x11ed3afa, 0xb27b12b6, 0x8db06c23, 0x2e26446f, + 0xeec0c0ae, 0x4d56e8e2, 0x729d9677, 0xd10bbe3b, 0x0d0b6b5d, + 0xae9d4311, 0x91563d84, 0x32c015c8, 0xcbea3247, 0x687c1a0b, + 0x57b7649e, 0xf4214cd2, 0x282199b4, 0x8bb7b1f8, 0xb47ccf6d, + 0x17eae721, 0xd70c63e0, 0x749a4bac, 0x4b513539, 0xe8c71d75, + 0x34c7c813, 0x9751e05f, 0xa89a9eca, 0x0b0cb686, 0x81bfd795, + 0x2229ffd9, 0x1de2814c, 0xbe74a900, 0x62747c66, 0xc1e2542a, + 0xfe292abf, 0x5dbf02f3, 0x9d598632, 0x3ecfae7e, 0x0104d0eb, + 0xa292f8a7, 0x7e922dc1, 0xdd04058d, 0xe2cf7b18, 0x41595354, + 0xb87374db, 0x1be55c97, 0x242e2202, 0x87b80a4e, 0x5bb8df28, + 0xf82ef764, 0xc7e589f1, 0x6473a1bd, 0xa495257c, 0x07030d30, + 0x38c873a5, 0x9b5e5be9, 0x475e8e8f, 0xe4c8a6c3, 0xdb03d856, + 0x7895f01a}, + {0x00000000, 0x2a283862, 0x545070c4, 0x7e7848a6, 0xa8a0e188, + 0x8288d9ea, 0xfcf0914c, 0xd6d8a92e, 0x8a30c551, 0xa018fd33, + 0xde60b595, 0xf4488df7, 0x229024d9, 0x08b81cbb, 0x76c0541d, + 0x5ce86c7f, 0xcf108ce3, 0xe538b481, 0x9b40fc27, 0xb168c445, + 0x67b06d6b, 0x4d985509, 0x33e01daf, 0x19c825cd, 0x452049b2, + 0x6f0871d0, 0x11703976, 0x3b580114, 0xed80a83a, 0xc7a89058, + 0xb9d0d8fe, 0x93f8e09c, 0x45501f87, 0x6f7827e5, 0x11006f43, + 0x3b285721, 0xedf0fe0f, 0xc7d8c66d, 0xb9a08ecb, 0x9388b6a9, + 0xcf60dad6, 0xe548e2b4, 0x9b30aa12, 0xb1189270, 0x67c03b5e, + 0x4de8033c, 0x33904b9a, 0x19b873f8, 0x8a409364, 0xa068ab06, + 0xde10e3a0, 0xf438dbc2, 0x22e072ec, 0x08c84a8e, 0x76b00228, + 0x5c983a4a, 0x00705635, 0x2a586e57, 0x542026f1, 0x7e081e93, + 0xa8d0b7bd, 0x82f88fdf, 0xfc80c779, 0xd6a8ff1b, 0x8aa03f0e, + 0xa088076c, 0xdef04fca, 0xf4d877a8, 0x2200de86, 0x0828e6e4, + 0x7650ae42, 0x5c789620, 0x0090fa5f, 0x2ab8c23d, 0x54c08a9b, + 0x7ee8b2f9, 0xa8301bd7, 0x821823b5, 0xfc606b13, 0xd6485371, + 0x45b0b3ed, 0x6f988b8f, 0x11e0c329, 0x3bc8fb4b, 0xed105265, + 0xc7386a07, 0xb94022a1, 0x93681ac3, 0xcf8076bc, 0xe5a84ede, + 0x9bd00678, 0xb1f83e1a, 0x67209734, 0x4d08af56, 0x3370e7f0, + 0x1958df92, 0xcff02089, 0xe5d818eb, 0x9ba0504d, 0xb188682f, + 0x6750c101, 0x4d78f963, 0x3300b1c5, 0x192889a7, 0x45c0e5d8, + 0x6fe8ddba, 0x1190951c, 0x3bb8ad7e, 0xed600450, 0xc7483c32, + 0xb9307494, 0x93184cf6, 0x00e0ac6a, 0x2ac89408, 0x54b0dcae, + 0x7e98e4cc, 0xa8404de2, 0x82687580, 0xfc103d26, 0xd6380544, + 0x8ad0693b, 0xa0f85159, 0xde8019ff, 0xf4a8219d, 0x227088b3, + 0x0858b0d1, 0x7620f877, 0x5c08c015, 0xce31785d, 0xe419403f, + 0x9a610899, 0xb04930fb, 0x669199d5, 0x4cb9a1b7, 0x32c1e911, + 0x18e9d173, 0x4401bd0c, 0x6e29856e, 0x1051cdc8, 0x3a79f5aa, + 0xeca15c84, 0xc68964e6, 0xb8f12c40, 0x92d91422, 0x0121f4be, + 0x2b09ccdc, 0x5571847a, 0x7f59bc18, 0xa9811536, 0x83a92d54, + 0xfdd165f2, 0xd7f95d90, 0x8b1131ef, 0xa139098d, 0xdf41412b, + 0xf5697949, 0x23b1d067, 0x0999e805, 0x77e1a0a3, 0x5dc998c1, + 0x8b6167da, 0xa1495fb8, 0xdf31171e, 0xf5192f7c, 0x23c18652, + 0x09e9be30, 0x7791f696, 0x5db9cef4, 0x0151a28b, 0x2b799ae9, + 0x5501d24f, 0x7f29ea2d, 0xa9f14303, 0x83d97b61, 0xfda133c7, + 0xd7890ba5, 0x4471eb39, 0x6e59d35b, 0x10219bfd, 0x3a09a39f, + 0xecd10ab1, 0xc6f932d3, 0xb8817a75, 0x92a94217, 0xce412e68, + 0xe469160a, 0x9a115eac, 0xb03966ce, 0x66e1cfe0, 0x4cc9f782, + 0x32b1bf24, 0x18998746, 0x44914753, 0x6eb97f31, 0x10c13797, + 0x3ae90ff5, 0xec31a6db, 0xc6199eb9, 0xb861d61f, 0x9249ee7d, + 0xcea18202, 0xe489ba60, 0x9af1f2c6, 0xb0d9caa4, 0x6601638a, + 0x4c295be8, 0x3251134e, 0x18792b2c, 0x8b81cbb0, 0xa1a9f3d2, + 0xdfd1bb74, 0xf5f98316, 0x23212a38, 0x0909125a, 0x77715afc, + 0x5d59629e, 0x01b10ee1, 0x2b993683, 0x55e17e25, 0x7fc94647, + 0xa911ef69, 0x8339d70b, 0xfd419fad, 0xd769a7cf, 0x01c158d4, + 0x2be960b6, 0x55912810, 0x7fb91072, 0xa961b95c, 0x8349813e, + 0xfd31c998, 0xd719f1fa, 0x8bf19d85, 0xa1d9a5e7, 0xdfa1ed41, + 0xf589d523, 0x23517c0d, 0x0979446f, 0x77010cc9, 0x5d2934ab, + 0xced1d437, 0xe4f9ec55, 0x9a81a4f3, 0xb0a99c91, 0x667135bf, + 0x4c590ddd, 0x3221457b, 0x18097d19, 0x44e11166, 0x6ec92904, + 0x10b161a2, 0x3a9959c0, 0xec41f0ee, 0xc669c88c, 0xb811802a, + 0x9239b848}, + {0x00000000, 0x4713f6fb, 0x8e27edf6, 0xc9341b0d, 0xc73eddad, + 0x802d2b56, 0x4919305b, 0x0e0ac6a0, 0x550cbd1b, 0x121f4be0, + 0xdb2b50ed, 0x9c38a616, 0x923260b6, 0xd521964d, 0x1c158d40, + 0x5b067bbb, 0xaa197a36, 0xed0a8ccd, 0x243e97c0, 0x632d613b, + 0x6d27a79b, 0x2a345160, 0xe3004a6d, 0xa413bc96, 0xff15c72d, + 0xb80631d6, 0x71322adb, 0x3621dc20, 0x382b1a80, 0x7f38ec7b, + 0xb60cf776, 0xf11f018d, 0x8f43f22d, 0xc85004d6, 0x01641fdb, + 0x4677e920, 0x487d2f80, 0x0f6ed97b, 0xc65ac276, 0x8149348d, + 0xda4f4f36, 0x9d5cb9cd, 0x5468a2c0, 0x137b543b, 0x1d71929b, + 0x5a626460, 0x93567f6d, 0xd4458996, 0x255a881b, 0x62497ee0, + 0xab7d65ed, 0xec6e9316, 0xe26455b6, 0xa577a34d, 0x6c43b840, + 0x2b504ebb, 0x70563500, 0x3745c3fb, 0xfe71d8f6, 0xb9622e0d, + 0xb768e8ad, 0xf07b1e56, 0x394f055b, 0x7e5cf3a0, 0xc5f6e21b, + 0x82e514e0, 0x4bd10fed, 0x0cc2f916, 0x02c83fb6, 0x45dbc94d, + 0x8cefd240, 0xcbfc24bb, 0x90fa5f00, 0xd7e9a9fb, 0x1eddb2f6, + 0x59ce440d, 0x57c482ad, 0x10d77456, 0xd9e36f5b, 0x9ef099a0, + 0x6fef982d, 0x28fc6ed6, 0xe1c875db, 0xa6db8320, 0xa8d14580, + 0xefc2b37b, 0x26f6a876, 0x61e55e8d, 0x3ae32536, 0x7df0d3cd, + 0xb4c4c8c0, 0xf3d73e3b, 0xfdddf89b, 0xbace0e60, 0x73fa156d, + 0x34e9e396, 0x4ab51036, 0x0da6e6cd, 0xc492fdc0, 0x83810b3b, + 0x8d8bcd9b, 0xca983b60, 0x03ac206d, 0x44bfd696, 0x1fb9ad2d, + 0x58aa5bd6, 0x919e40db, 0xd68db620, 0xd8877080, 0x9f94867b, + 0x56a09d76, 0x11b36b8d, 0xe0ac6a00, 0xa7bf9cfb, 0x6e8b87f6, + 0x2998710d, 0x2792b7ad, 0x60814156, 0xa9b55a5b, 0xeea6aca0, + 0xb5a0d71b, 0xf2b321e0, 0x3b873aed, 0x7c94cc16, 0x729e0ab6, + 0x358dfc4d, 0xfcb9e740, 0xbbaa11bb, 0x509cc277, 0x178f348c, + 0xdebb2f81, 0x99a8d97a, 0x97a21fda, 0xd0b1e921, 0x1985f22c, + 0x5e9604d7, 0x05907f6c, 0x42838997, 0x8bb7929a, 0xcca46461, + 0xc2aea2c1, 0x85bd543a, 0x4c894f37, 0x0b9ab9cc, 0xfa85b841, + 0xbd964eba, 0x74a255b7, 0x33b1a34c, 0x3dbb65ec, 0x7aa89317, + 0xb39c881a, 0xf48f7ee1, 0xaf89055a, 0xe89af3a1, 0x21aee8ac, + 0x66bd1e57, 0x68b7d8f7, 0x2fa42e0c, 0xe6903501, 0xa183c3fa, + 0xdfdf305a, 0x98ccc6a1, 0x51f8ddac, 0x16eb2b57, 0x18e1edf7, + 0x5ff21b0c, 0x96c60001, 0xd1d5f6fa, 0x8ad38d41, 0xcdc07bba, + 0x04f460b7, 0x43e7964c, 0x4ded50ec, 0x0afea617, 0xc3cabd1a, + 0x84d94be1, 0x75c64a6c, 0x32d5bc97, 0xfbe1a79a, 0xbcf25161, + 0xb2f897c1, 0xf5eb613a, 0x3cdf7a37, 0x7bcc8ccc, 0x20caf777, + 0x67d9018c, 0xaeed1a81, 0xe9feec7a, 0xe7f42ada, 0xa0e7dc21, + 0x69d3c72c, 0x2ec031d7, 0x956a206c, 0xd279d697, 0x1b4dcd9a, + 0x5c5e3b61, 0x5254fdc1, 0x15470b3a, 0xdc731037, 0x9b60e6cc, + 0xc0669d77, 0x87756b8c, 0x4e417081, 0x0952867a, 0x075840da, + 0x404bb621, 0x897fad2c, 0xce6c5bd7, 0x3f735a5a, 0x7860aca1, + 0xb154b7ac, 0xf6474157, 0xf84d87f7, 0xbf5e710c, 0x766a6a01, + 0x31799cfa, 0x6a7fe741, 0x2d6c11ba, 0xe4580ab7, 0xa34bfc4c, + 0xad413aec, 0xea52cc17, 0x2366d71a, 0x647521e1, 0x1a29d241, + 0x5d3a24ba, 0x940e3fb7, 0xd31dc94c, 0xdd170fec, 0x9a04f917, + 0x5330e21a, 0x142314e1, 0x4f256f5a, 0x083699a1, 0xc10282ac, + 0x86117457, 0x881bb2f7, 0xcf08440c, 0x063c5f01, 0x412fa9fa, + 0xb030a877, 0xf7235e8c, 0x3e174581, 0x7904b37a, 0x770e75da, + 0x301d8321, 0xf929982c, 0xbe3a6ed7, 0xe53c156c, 0xa22fe397, + 0x6b1bf89a, 0x2c080e61, 0x2202c8c1, 0x65113e3a, 0xac252537, + 0xeb36d3cc}, + {0x00000000, 0xa13984ee, 0x99020f9d, 0x383b8b73, 0xe975197b, + 0x484c9d95, 0x707716e6, 0xd14e9208, 0x099b34b7, 0xa8a2b059, + 0x90993b2a, 0x31a0bfc4, 0xe0ee2dcc, 0x41d7a922, 0x79ec2251, + 0xd8d5a6bf, 0x1336696e, 0xb20fed80, 0x8a3466f3, 0x2b0de21d, + 0xfa437015, 0x5b7af4fb, 0x63417f88, 0xc278fb66, 0x1aad5dd9, + 0xbb94d937, 0x83af5244, 0x2296d6aa, 0xf3d844a2, 0x52e1c04c, + 0x6ada4b3f, 0xcbe3cfd1, 0x266cd2dc, 0x87555632, 0xbf6edd41, + 0x1e5759af, 0xcf19cba7, 0x6e204f49, 0x561bc43a, 0xf72240d4, + 0x2ff7e66b, 0x8ece6285, 0xb6f5e9f6, 0x17cc6d18, 0xc682ff10, + 0x67bb7bfe, 0x5f80f08d, 0xfeb97463, 0x355abbb2, 0x94633f5c, + 0xac58b42f, 0x0d6130c1, 0xdc2fa2c9, 0x7d162627, 0x452dad54, + 0xe41429ba, 0x3cc18f05, 0x9df80beb, 0xa5c38098, 0x04fa0476, + 0xd5b4967e, 0x748d1290, 0x4cb699e3, 0xed8f1d0d, 0x4cd9a5b8, + 0xede02156, 0xd5dbaa25, 0x74e22ecb, 0xa5acbcc3, 0x0495382d, + 0x3caeb35e, 0x9d9737b0, 0x4542910f, 0xe47b15e1, 0xdc409e92, + 0x7d791a7c, 0xac378874, 0x0d0e0c9a, 0x353587e9, 0x940c0307, + 0x5fefccd6, 0xfed64838, 0xc6edc34b, 0x67d447a5, 0xb69ad5ad, + 0x17a35143, 0x2f98da30, 0x8ea15ede, 0x5674f861, 0xf74d7c8f, + 0xcf76f7fc, 0x6e4f7312, 0xbf01e11a, 0x1e3865f4, 0x2603ee87, + 0x873a6a69, 0x6ab57764, 0xcb8cf38a, 0xf3b778f9, 0x528efc17, + 0x83c06e1f, 0x22f9eaf1, 0x1ac26182, 0xbbfbe56c, 0x632e43d3, + 0xc217c73d, 0xfa2c4c4e, 0x5b15c8a0, 0x8a5b5aa8, 0x2b62de46, + 0x13595535, 0xb260d1db, 0x79831e0a, 0xd8ba9ae4, 0xe0811197, + 0x41b89579, 0x90f60771, 0x31cf839f, 0x09f408ec, 0xa8cd8c02, + 0x70182abd, 0xd121ae53, 0xe91a2520, 0x4823a1ce, 0x996d33c6, + 0x3854b728, 0x006f3c5b, 0xa156b8b5, 0x99b34b70, 0x388acf9e, + 0x00b144ed, 0xa188c003, 0x70c6520b, 0xd1ffd6e5, 0xe9c45d96, + 0x48fdd978, 0x90287fc7, 0x3111fb29, 0x092a705a, 0xa813f4b4, + 0x795d66bc, 0xd864e252, 0xe05f6921, 0x4166edcf, 0x8a85221e, + 0x2bbca6f0, 0x13872d83, 0xb2bea96d, 0x63f03b65, 0xc2c9bf8b, + 0xfaf234f8, 0x5bcbb016, 0x831e16a9, 0x22279247, 0x1a1c1934, + 0xbb259dda, 0x6a6b0fd2, 0xcb528b3c, 0xf369004f, 0x525084a1, + 0xbfdf99ac, 0x1ee61d42, 0x26dd9631, 0x87e412df, 0x56aa80d7, + 0xf7930439, 0xcfa88f4a, 0x6e910ba4, 0xb644ad1b, 0x177d29f5, + 0x2f46a286, 0x8e7f2668, 0x5f31b460, 0xfe08308e, 0xc633bbfd, + 0x670a3f13, 0xace9f0c2, 0x0dd0742c, 0x35ebff5f, 0x94d27bb1, + 0x459ce9b9, 0xe4a56d57, 0xdc9ee624, 0x7da762ca, 0xa572c475, + 0x044b409b, 0x3c70cbe8, 0x9d494f06, 0x4c07dd0e, 0xed3e59e0, + 0xd505d293, 0x743c567d, 0xd56aeec8, 0x74536a26, 0x4c68e155, + 0xed5165bb, 0x3c1ff7b3, 0x9d26735d, 0xa51df82e, 0x04247cc0, + 0xdcf1da7f, 0x7dc85e91, 0x45f3d5e2, 0xe4ca510c, 0x3584c304, + 0x94bd47ea, 0xac86cc99, 0x0dbf4877, 0xc65c87a6, 0x67650348, + 0x5f5e883b, 0xfe670cd5, 0x2f299edd, 0x8e101a33, 0xb62b9140, + 0x171215ae, 0xcfc7b311, 0x6efe37ff, 0x56c5bc8c, 0xf7fc3862, + 0x26b2aa6a, 0x878b2e84, 0xbfb0a5f7, 0x1e892119, 0xf3063c14, + 0x523fb8fa, 0x6a043389, 0xcb3db767, 0x1a73256f, 0xbb4aa181, + 0x83712af2, 0x2248ae1c, 0xfa9d08a3, 0x5ba48c4d, 0x639f073e, + 0xc2a683d0, 0x13e811d8, 0xb2d19536, 0x8aea1e45, 0x2bd39aab, + 0xe030557a, 0x4109d194, 0x79325ae7, 0xd80bde09, 0x09454c01, + 0xa87cc8ef, 0x9047439c, 0x317ec772, 0xe9ab61cd, 0x4892e523, + 0x70a96e50, 0xd190eabe, 0x00de78b6, 0xa1e7fc58, 0x99dc772b, + 0x38e5f3c5}, + {0x00000000, 0xe81790a1, 0x0b5e2703, 0xe349b7a2, 0x16bc4e06, + 0xfeabdea7, 0x1de26905, 0xf5f5f9a4, 0x2d789c0c, 0xc56f0cad, + 0x2626bb0f, 0xce312bae, 0x3bc4d20a, 0xd3d342ab, 0x309af509, + 0xd88d65a8, 0x5af13818, 0xb2e6a8b9, 0x51af1f1b, 0xb9b88fba, + 0x4c4d761e, 0xa45ae6bf, 0x4713511d, 0xaf04c1bc, 0x7789a414, + 0x9f9e34b5, 0x7cd78317, 0x94c013b6, 0x6135ea12, 0x89227ab3, + 0x6a6bcd11, 0x827c5db0, 0xb5e27030, 0x5df5e091, 0xbebc5733, + 0x56abc792, 0xa35e3e36, 0x4b49ae97, 0xa8001935, 0x40178994, + 0x989aec3c, 0x708d7c9d, 0x93c4cb3f, 0x7bd35b9e, 0x8e26a23a, + 0x6631329b, 0x85788539, 0x6d6f1598, 0xef134828, 0x0704d889, + 0xe44d6f2b, 0x0c5aff8a, 0xf9af062e, 0x11b8968f, 0xf2f1212d, + 0x1ae6b18c, 0xc26bd424, 0x2a7c4485, 0xc935f327, 0x21226386, + 0xd4d79a22, 0x3cc00a83, 0xdf89bd21, 0x379e2d80, 0xb0b5e621, + 0x58a27680, 0xbbebc122, 0x53fc5183, 0xa609a827, 0x4e1e3886, + 0xad578f24, 0x45401f85, 0x9dcd7a2d, 0x75daea8c, 0x96935d2e, + 0x7e84cd8f, 0x8b71342b, 0x6366a48a, 0x802f1328, 0x68388389, + 0xea44de39, 0x02534e98, 0xe11af93a, 0x090d699b, 0xfcf8903f, + 0x14ef009e, 0xf7a6b73c, 0x1fb1279d, 0xc73c4235, 0x2f2bd294, + 0xcc626536, 0x2475f597, 0xd1800c33, 0x39979c92, 0xdade2b30, + 0x32c9bb91, 0x05579611, 0xed4006b0, 0x0e09b112, 0xe61e21b3, + 0x13ebd817, 0xfbfc48b6, 0x18b5ff14, 0xf0a26fb5, 0x282f0a1d, + 0xc0389abc, 0x23712d1e, 0xcb66bdbf, 0x3e93441b, 0xd684d4ba, + 0x35cd6318, 0xdddaf3b9, 0x5fa6ae09, 0xb7b13ea8, 0x54f8890a, + 0xbcef19ab, 0x491ae00f, 0xa10d70ae, 0x4244c70c, 0xaa5357ad, + 0x72de3205, 0x9ac9a2a4, 0x79801506, 0x919785a7, 0x64627c03, + 0x8c75eca2, 0x6f3c5b00, 0x872bcba1, 0xba1aca03, 0x520d5aa2, + 0xb144ed00, 0x59537da1, 0xaca68405, 0x44b114a4, 0xa7f8a306, + 0x4fef33a7, 0x9762560f, 0x7f75c6ae, 0x9c3c710c, 0x742be1ad, + 0x81de1809, 0x69c988a8, 0x8a803f0a, 0x6297afab, 0xe0ebf21b, + 0x08fc62ba, 0xebb5d518, 0x03a245b9, 0xf657bc1d, 0x1e402cbc, + 0xfd099b1e, 0x151e0bbf, 0xcd936e17, 0x2584feb6, 0xc6cd4914, + 0x2edad9b5, 0xdb2f2011, 0x3338b0b0, 0xd0710712, 0x386697b3, + 0x0ff8ba33, 0xe7ef2a92, 0x04a69d30, 0xecb10d91, 0x1944f435, + 0xf1536494, 0x121ad336, 0xfa0d4397, 0x2280263f, 0xca97b69e, + 0x29de013c, 0xc1c9919d, 0x343c6839, 0xdc2bf898, 0x3f624f3a, + 0xd775df9b, 0x5509822b, 0xbd1e128a, 0x5e57a528, 0xb6403589, + 0x43b5cc2d, 0xaba25c8c, 0x48ebeb2e, 0xa0fc7b8f, 0x78711e27, + 0x90668e86, 0x732f3924, 0x9b38a985, 0x6ecd5021, 0x86dac080, + 0x65937722, 0x8d84e783, 0x0aaf2c22, 0xe2b8bc83, 0x01f10b21, + 0xe9e69b80, 0x1c136224, 0xf404f285, 0x174d4527, 0xff5ad586, + 0x27d7b02e, 0xcfc0208f, 0x2c89972d, 0xc49e078c, 0x316bfe28, + 0xd97c6e89, 0x3a35d92b, 0xd222498a, 0x505e143a, 0xb849849b, + 0x5b003339, 0xb317a398, 0x46e25a3c, 0xaef5ca9d, 0x4dbc7d3f, + 0xa5abed9e, 0x7d268836, 0x95311897, 0x7678af35, 0x9e6f3f94, + 0x6b9ac630, 0x838d5691, 0x60c4e133, 0x88d37192, 0xbf4d5c12, + 0x575accb3, 0xb4137b11, 0x5c04ebb0, 0xa9f11214, 0x41e682b5, + 0xa2af3517, 0x4ab8a5b6, 0x9235c01e, 0x7a2250bf, 0x996be71d, + 0x717c77bc, 0x84898e18, 0x6c9e1eb9, 0x8fd7a91b, 0x67c039ba, + 0xe5bc640a, 0x0dabf4ab, 0xeee24309, 0x06f5d3a8, 0xf3002a0c, + 0x1b17baad, 0xf85e0d0f, 0x10499dae, 0xc8c4f806, 0x20d368a7, + 0xc39adf05, 0x2b8d4fa4, 0xde78b600, 0x366f26a1, 0xd5269103, + 0x3d3101a2}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x0000000000000000, 0xa19017e800000000, 0x03275e0b00000000, + 0xa2b749e300000000, 0x064ebc1600000000, 0xa7deabfe00000000, + 0x0569e21d00000000, 0xa4f9f5f500000000, 0x0c9c782d00000000, + 0xad0c6fc500000000, 0x0fbb262600000000, 0xae2b31ce00000000, + 0x0ad2c43b00000000, 0xab42d3d300000000, 0x09f59a3000000000, + 0xa8658dd800000000, 0x1838f15a00000000, 0xb9a8e6b200000000, + 0x1b1faf5100000000, 0xba8fb8b900000000, 0x1e764d4c00000000, + 0xbfe65aa400000000, 0x1d51134700000000, 0xbcc104af00000000, + 0x14a4897700000000, 0xb5349e9f00000000, 0x1783d77c00000000, + 0xb613c09400000000, 0x12ea356100000000, 0xb37a228900000000, + 0x11cd6b6a00000000, 0xb05d7c8200000000, 0x3070e2b500000000, + 0x91e0f55d00000000, 0x3357bcbe00000000, 0x92c7ab5600000000, + 0x363e5ea300000000, 0x97ae494b00000000, 0x351900a800000000, + 0x9489174000000000, 0x3cec9a9800000000, 0x9d7c8d7000000000, + 0x3fcbc49300000000, 0x9e5bd37b00000000, 0x3aa2268e00000000, + 0x9b32316600000000, 0x3985788500000000, 0x98156f6d00000000, + 0x284813ef00000000, 0x89d8040700000000, 0x2b6f4de400000000, + 0x8aff5a0c00000000, 0x2e06aff900000000, 0x8f96b81100000000, + 0x2d21f1f200000000, 0x8cb1e61a00000000, 0x24d46bc200000000, + 0x85447c2a00000000, 0x27f335c900000000, 0x8663222100000000, + 0x229ad7d400000000, 0x830ac03c00000000, 0x21bd89df00000000, + 0x802d9e3700000000, 0x21e6b5b000000000, 0x8076a25800000000, + 0x22c1ebbb00000000, 0x8351fc5300000000, 0x27a809a600000000, + 0x86381e4e00000000, 0x248f57ad00000000, 0x851f404500000000, + 0x2d7acd9d00000000, 0x8ceada7500000000, 0x2e5d939600000000, + 0x8fcd847e00000000, 0x2b34718b00000000, 0x8aa4666300000000, + 0x28132f8000000000, 0x8983386800000000, 0x39de44ea00000000, + 0x984e530200000000, 0x3af91ae100000000, 0x9b690d0900000000, + 0x3f90f8fc00000000, 0x9e00ef1400000000, 0x3cb7a6f700000000, + 0x9d27b11f00000000, 0x35423cc700000000, 0x94d22b2f00000000, + 0x366562cc00000000, 0x97f5752400000000, 0x330c80d100000000, + 0x929c973900000000, 0x302bdeda00000000, 0x91bbc93200000000, + 0x1196570500000000, 0xb00640ed00000000, 0x12b1090e00000000, + 0xb3211ee600000000, 0x17d8eb1300000000, 0xb648fcfb00000000, + 0x14ffb51800000000, 0xb56fa2f000000000, 0x1d0a2f2800000000, + 0xbc9a38c000000000, 0x1e2d712300000000, 0xbfbd66cb00000000, + 0x1b44933e00000000, 0xbad484d600000000, 0x1863cd3500000000, + 0xb9f3dadd00000000, 0x09aea65f00000000, 0xa83eb1b700000000, + 0x0a89f85400000000, 0xab19efbc00000000, 0x0fe01a4900000000, + 0xae700da100000000, 0x0cc7444200000000, 0xad5753aa00000000, + 0x0532de7200000000, 0xa4a2c99a00000000, 0x0615807900000000, + 0xa785979100000000, 0x037c626400000000, 0xa2ec758c00000000, + 0x005b3c6f00000000, 0xa1cb2b8700000000, 0x03ca1aba00000000, + 0xa25a0d5200000000, 0x00ed44b100000000, 0xa17d535900000000, + 0x0584a6ac00000000, 0xa414b14400000000, 0x06a3f8a700000000, + 0xa733ef4f00000000, 0x0f56629700000000, 0xaec6757f00000000, + 0x0c713c9c00000000, 0xade12b7400000000, 0x0918de8100000000, + 0xa888c96900000000, 0x0a3f808a00000000, 0xabaf976200000000, + 0x1bf2ebe000000000, 0xba62fc0800000000, 0x18d5b5eb00000000, + 0xb945a20300000000, 0x1dbc57f600000000, 0xbc2c401e00000000, + 0x1e9b09fd00000000, 0xbf0b1e1500000000, 0x176e93cd00000000, + 0xb6fe842500000000, 0x1449cdc600000000, 0xb5d9da2e00000000, + 0x11202fdb00000000, 0xb0b0383300000000, 0x120771d000000000, + 0xb397663800000000, 0x33baf80f00000000, 0x922aefe700000000, + 0x309da60400000000, 0x910db1ec00000000, 0x35f4441900000000, + 0x946453f100000000, 0x36d31a1200000000, 0x97430dfa00000000, + 0x3f26802200000000, 0x9eb697ca00000000, 0x3c01de2900000000, + 0x9d91c9c100000000, 0x39683c3400000000, 0x98f82bdc00000000, + 0x3a4f623f00000000, 0x9bdf75d700000000, 0x2b82095500000000, + 0x8a121ebd00000000, 0x28a5575e00000000, 0x893540b600000000, + 0x2dccb54300000000, 0x8c5ca2ab00000000, 0x2eebeb4800000000, + 0x8f7bfca000000000, 0x271e717800000000, 0x868e669000000000, + 0x24392f7300000000, 0x85a9389b00000000, 0x2150cd6e00000000, + 0x80c0da8600000000, 0x2277936500000000, 0x83e7848d00000000, + 0x222caf0a00000000, 0x83bcb8e200000000, 0x210bf10100000000, + 0x809be6e900000000, 0x2462131c00000000, 0x85f204f400000000, + 0x27454d1700000000, 0x86d55aff00000000, 0x2eb0d72700000000, + 0x8f20c0cf00000000, 0x2d97892c00000000, 0x8c079ec400000000, + 0x28fe6b3100000000, 0x896e7cd900000000, 0x2bd9353a00000000, + 0x8a4922d200000000, 0x3a145e5000000000, 0x9b8449b800000000, + 0x3933005b00000000, 0x98a317b300000000, 0x3c5ae24600000000, + 0x9dcaf5ae00000000, 0x3f7dbc4d00000000, 0x9eedaba500000000, + 0x3688267d00000000, 0x9718319500000000, 0x35af787600000000, + 0x943f6f9e00000000, 0x30c69a6b00000000, 0x91568d8300000000, + 0x33e1c46000000000, 0x9271d38800000000, 0x125c4dbf00000000, + 0xb3cc5a5700000000, 0x117b13b400000000, 0xb0eb045c00000000, + 0x1412f1a900000000, 0xb582e64100000000, 0x1735afa200000000, + 0xb6a5b84a00000000, 0x1ec0359200000000, 0xbf50227a00000000, + 0x1de76b9900000000, 0xbc777c7100000000, 0x188e898400000000, + 0xb91e9e6c00000000, 0x1ba9d78f00000000, 0xba39c06700000000, + 0x0a64bce500000000, 0xabf4ab0d00000000, 0x0943e2ee00000000, + 0xa8d3f50600000000, 0x0c2a00f300000000, 0xadba171b00000000, + 0x0f0d5ef800000000, 0xae9d491000000000, 0x06f8c4c800000000, + 0xa768d32000000000, 0x05df9ac300000000, 0xa44f8d2b00000000, + 0x00b678de00000000, 0xa1266f3600000000, 0x039126d500000000, + 0xa201313d00000000}, + {0x0000000000000000, 0xee8439a100000000, 0x9d0f029900000000, + 0x738b3b3800000000, 0x7b1975e900000000, 0x959d4c4800000000, + 0xe616777000000000, 0x08924ed100000000, 0xb7349b0900000000, + 0x59b0a2a800000000, 0x2a3b999000000000, 0xc4bfa03100000000, + 0xcc2deee000000000, 0x22a9d74100000000, 0x5122ec7900000000, + 0xbfa6d5d800000000, 0x6e69361300000000, 0x80ed0fb200000000, + 0xf366348a00000000, 0x1de20d2b00000000, 0x157043fa00000000, + 0xfbf47a5b00000000, 0x887f416300000000, 0x66fb78c200000000, + 0xd95dad1a00000000, 0x37d994bb00000000, 0x4452af8300000000, + 0xaad6962200000000, 0xa244d8f300000000, 0x4cc0e15200000000, + 0x3f4bda6a00000000, 0xd1cfe3cb00000000, 0xdcd26c2600000000, + 0x3256558700000000, 0x41dd6ebf00000000, 0xaf59571e00000000, + 0xa7cb19cf00000000, 0x494f206e00000000, 0x3ac41b5600000000, + 0xd44022f700000000, 0x6be6f72f00000000, 0x8562ce8e00000000, + 0xf6e9f5b600000000, 0x186dcc1700000000, 0x10ff82c600000000, + 0xfe7bbb6700000000, 0x8df0805f00000000, 0x6374b9fe00000000, + 0xb2bb5a3500000000, 0x5c3f639400000000, 0x2fb458ac00000000, + 0xc130610d00000000, 0xc9a22fdc00000000, 0x2726167d00000000, + 0x54ad2d4500000000, 0xba2914e400000000, 0x058fc13c00000000, + 0xeb0bf89d00000000, 0x9880c3a500000000, 0x7604fa0400000000, + 0x7e96b4d500000000, 0x90128d7400000000, 0xe399b64c00000000, + 0x0d1d8fed00000000, 0xb8a5d94c00000000, 0x5621e0ed00000000, + 0x25aadbd500000000, 0xcb2ee27400000000, 0xc3bcaca500000000, + 0x2d38950400000000, 0x5eb3ae3c00000000, 0xb037979d00000000, + 0x0f91424500000000, 0xe1157be400000000, 0x929e40dc00000000, + 0x7c1a797d00000000, 0x748837ac00000000, 0x9a0c0e0d00000000, + 0xe987353500000000, 0x07030c9400000000, 0xd6ccef5f00000000, + 0x3848d6fe00000000, 0x4bc3edc600000000, 0xa547d46700000000, + 0xadd59ab600000000, 0x4351a31700000000, 0x30da982f00000000, + 0xde5ea18e00000000, 0x61f8745600000000, 0x8f7c4df700000000, + 0xfcf776cf00000000, 0x12734f6e00000000, 0x1ae101bf00000000, + 0xf465381e00000000, 0x87ee032600000000, 0x696a3a8700000000, + 0x6477b56a00000000, 0x8af38ccb00000000, 0xf978b7f300000000, + 0x17fc8e5200000000, 0x1f6ec08300000000, 0xf1eaf92200000000, + 0x8261c21a00000000, 0x6ce5fbbb00000000, 0xd3432e6300000000, + 0x3dc717c200000000, 0x4e4c2cfa00000000, 0xa0c8155b00000000, + 0xa85a5b8a00000000, 0x46de622b00000000, 0x3555591300000000, + 0xdbd160b200000000, 0x0a1e837900000000, 0xe49abad800000000, + 0x971181e000000000, 0x7995b84100000000, 0x7107f69000000000, + 0x9f83cf3100000000, 0xec08f40900000000, 0x028ccda800000000, + 0xbd2a187000000000, 0x53ae21d100000000, 0x20251ae900000000, + 0xcea1234800000000, 0xc6336d9900000000, 0x28b7543800000000, + 0x5b3c6f0000000000, 0xb5b856a100000000, 0x704bb39900000000, + 0x9ecf8a3800000000, 0xed44b10000000000, 0x03c088a100000000, + 0x0b52c67000000000, 0xe5d6ffd100000000, 0x965dc4e900000000, + 0x78d9fd4800000000, 0xc77f289000000000, 0x29fb113100000000, + 0x5a702a0900000000, 0xb4f413a800000000, 0xbc665d7900000000, + 0x52e264d800000000, 0x21695fe000000000, 0xcfed664100000000, + 0x1e22858a00000000, 0xf0a6bc2b00000000, 0x832d871300000000, + 0x6da9beb200000000, 0x653bf06300000000, 0x8bbfc9c200000000, + 0xf834f2fa00000000, 0x16b0cb5b00000000, 0xa9161e8300000000, + 0x4792272200000000, 0x34191c1a00000000, 0xda9d25bb00000000, + 0xd20f6b6a00000000, 0x3c8b52cb00000000, 0x4f0069f300000000, + 0xa184505200000000, 0xac99dfbf00000000, 0x421de61e00000000, + 0x3196dd2600000000, 0xdf12e48700000000, 0xd780aa5600000000, + 0x390493f700000000, 0x4a8fa8cf00000000, 0xa40b916e00000000, + 0x1bad44b600000000, 0xf5297d1700000000, 0x86a2462f00000000, + 0x68267f8e00000000, 0x60b4315f00000000, 0x8e3008fe00000000, + 0xfdbb33c600000000, 0x133f0a6700000000, 0xc2f0e9ac00000000, + 0x2c74d00d00000000, 0x5fffeb3500000000, 0xb17bd29400000000, + 0xb9e99c4500000000, 0x576da5e400000000, 0x24e69edc00000000, + 0xca62a77d00000000, 0x75c472a500000000, 0x9b404b0400000000, + 0xe8cb703c00000000, 0x064f499d00000000, 0x0edd074c00000000, + 0xe0593eed00000000, 0x93d205d500000000, 0x7d563c7400000000, + 0xc8ee6ad500000000, 0x266a537400000000, 0x55e1684c00000000, + 0xbb6551ed00000000, 0xb3f71f3c00000000, 0x5d73269d00000000, + 0x2ef81da500000000, 0xc07c240400000000, 0x7fdaf1dc00000000, + 0x915ec87d00000000, 0xe2d5f34500000000, 0x0c51cae400000000, + 0x04c3843500000000, 0xea47bd9400000000, 0x99cc86ac00000000, + 0x7748bf0d00000000, 0xa6875cc600000000, 0x4803656700000000, + 0x3b885e5f00000000, 0xd50c67fe00000000, 0xdd9e292f00000000, + 0x331a108e00000000, 0x40912bb600000000, 0xae15121700000000, + 0x11b3c7cf00000000, 0xff37fe6e00000000, 0x8cbcc55600000000, + 0x6238fcf700000000, 0x6aaab22600000000, 0x842e8b8700000000, + 0xf7a5b0bf00000000, 0x1921891e00000000, 0x143c06f300000000, + 0xfab83f5200000000, 0x8933046a00000000, 0x67b73dcb00000000, + 0x6f25731a00000000, 0x81a14abb00000000, 0xf22a718300000000, + 0x1cae482200000000, 0xa3089dfa00000000, 0x4d8ca45b00000000, + 0x3e079f6300000000, 0xd083a6c200000000, 0xd811e81300000000, + 0x3695d1b200000000, 0x451eea8a00000000, 0xab9ad32b00000000, + 0x7a5530e000000000, 0x94d1094100000000, 0xe75a327900000000, + 0x09de0bd800000000, 0x014c450900000000, 0xefc87ca800000000, + 0x9c43479000000000, 0x72c77e3100000000, 0xcd61abe900000000, + 0x23e5924800000000, 0x506ea97000000000, 0xbeea90d100000000, + 0xb678de0000000000, 0x58fce7a100000000, 0x2b77dc9900000000, + 0xc5f3e53800000000}, + {0x0000000000000000, 0xfbf6134700000000, 0xf6ed278e00000000, + 0x0d1b34c900000000, 0xaddd3ec700000000, 0x562b2d8000000000, + 0x5b30194900000000, 0xa0c60a0e00000000, 0x1bbd0c5500000000, + 0xe04b1f1200000000, 0xed502bdb00000000, 0x16a6389c00000000, + 0xb660329200000000, 0x4d9621d500000000, 0x408d151c00000000, + 0xbb7b065b00000000, 0x367a19aa00000000, 0xcd8c0aed00000000, + 0xc0973e2400000000, 0x3b612d6300000000, 0x9ba7276d00000000, + 0x6051342a00000000, 0x6d4a00e300000000, 0x96bc13a400000000, + 0x2dc715ff00000000, 0xd63106b800000000, 0xdb2a327100000000, + 0x20dc213600000000, 0x801a2b3800000000, 0x7bec387f00000000, + 0x76f70cb600000000, 0x8d011ff100000000, 0x2df2438f00000000, + 0xd60450c800000000, 0xdb1f640100000000, 0x20e9774600000000, + 0x802f7d4800000000, 0x7bd96e0f00000000, 0x76c25ac600000000, + 0x8d34498100000000, 0x364f4fda00000000, 0xcdb95c9d00000000, + 0xc0a2685400000000, 0x3b547b1300000000, 0x9b92711d00000000, + 0x6064625a00000000, 0x6d7f569300000000, 0x968945d400000000, + 0x1b885a2500000000, 0xe07e496200000000, 0xed657dab00000000, + 0x16936eec00000000, 0xb65564e200000000, 0x4da377a500000000, + 0x40b8436c00000000, 0xbb4e502b00000000, 0x0035567000000000, + 0xfbc3453700000000, 0xf6d871fe00000000, 0x0d2e62b900000000, + 0xade868b700000000, 0x561e7bf000000000, 0x5b054f3900000000, + 0xa0f35c7e00000000, 0x1be2f6c500000000, 0xe014e58200000000, + 0xed0fd14b00000000, 0x16f9c20c00000000, 0xb63fc80200000000, + 0x4dc9db4500000000, 0x40d2ef8c00000000, 0xbb24fccb00000000, + 0x005ffa9000000000, 0xfba9e9d700000000, 0xf6b2dd1e00000000, + 0x0d44ce5900000000, 0xad82c45700000000, 0x5674d71000000000, + 0x5b6fe3d900000000, 0xa099f09e00000000, 0x2d98ef6f00000000, + 0xd66efc2800000000, 0xdb75c8e100000000, 0x2083dba600000000, + 0x8045d1a800000000, 0x7bb3c2ef00000000, 0x76a8f62600000000, + 0x8d5ee56100000000, 0x3625e33a00000000, 0xcdd3f07d00000000, + 0xc0c8c4b400000000, 0x3b3ed7f300000000, 0x9bf8ddfd00000000, + 0x600eceba00000000, 0x6d15fa7300000000, 0x96e3e93400000000, + 0x3610b54a00000000, 0xcde6a60d00000000, 0xc0fd92c400000000, + 0x3b0b818300000000, 0x9bcd8b8d00000000, 0x603b98ca00000000, + 0x6d20ac0300000000, 0x96d6bf4400000000, 0x2dadb91f00000000, + 0xd65baa5800000000, 0xdb409e9100000000, 0x20b68dd600000000, + 0x807087d800000000, 0x7b86949f00000000, 0x769da05600000000, + 0x8d6bb31100000000, 0x006aace000000000, 0xfb9cbfa700000000, + 0xf6878b6e00000000, 0x0d71982900000000, 0xadb7922700000000, + 0x5641816000000000, 0x5b5ab5a900000000, 0xa0aca6ee00000000, + 0x1bd7a0b500000000, 0xe021b3f200000000, 0xed3a873b00000000, + 0x16cc947c00000000, 0xb60a9e7200000000, 0x4dfc8d3500000000, + 0x40e7b9fc00000000, 0xbb11aabb00000000, 0x77c29c5000000000, + 0x8c348f1700000000, 0x812fbbde00000000, 0x7ad9a89900000000, + 0xda1fa29700000000, 0x21e9b1d000000000, 0x2cf2851900000000, + 0xd704965e00000000, 0x6c7f900500000000, 0x9789834200000000, + 0x9a92b78b00000000, 0x6164a4cc00000000, 0xc1a2aec200000000, + 0x3a54bd8500000000, 0x374f894c00000000, 0xccb99a0b00000000, + 0x41b885fa00000000, 0xba4e96bd00000000, 0xb755a27400000000, + 0x4ca3b13300000000, 0xec65bb3d00000000, 0x1793a87a00000000, + 0x1a889cb300000000, 0xe17e8ff400000000, 0x5a0589af00000000, + 0xa1f39ae800000000, 0xace8ae2100000000, 0x571ebd6600000000, + 0xf7d8b76800000000, 0x0c2ea42f00000000, 0x013590e600000000, + 0xfac383a100000000, 0x5a30dfdf00000000, 0xa1c6cc9800000000, + 0xacddf85100000000, 0x572beb1600000000, 0xf7ede11800000000, + 0x0c1bf25f00000000, 0x0100c69600000000, 0xfaf6d5d100000000, + 0x418dd38a00000000, 0xba7bc0cd00000000, 0xb760f40400000000, + 0x4c96e74300000000, 0xec50ed4d00000000, 0x17a6fe0a00000000, + 0x1abdcac300000000, 0xe14bd98400000000, 0x6c4ac67500000000, + 0x97bcd53200000000, 0x9aa7e1fb00000000, 0x6151f2bc00000000, + 0xc197f8b200000000, 0x3a61ebf500000000, 0x377adf3c00000000, + 0xcc8ccc7b00000000, 0x77f7ca2000000000, 0x8c01d96700000000, + 0x811aedae00000000, 0x7aecfee900000000, 0xda2af4e700000000, + 0x21dce7a000000000, 0x2cc7d36900000000, 0xd731c02e00000000, + 0x6c206a9500000000, 0x97d679d200000000, 0x9acd4d1b00000000, + 0x613b5e5c00000000, 0xc1fd545200000000, 0x3a0b471500000000, + 0x371073dc00000000, 0xcce6609b00000000, 0x779d66c000000000, + 0x8c6b758700000000, 0x8170414e00000000, 0x7a86520900000000, + 0xda40580700000000, 0x21b64b4000000000, 0x2cad7f8900000000, + 0xd75b6cce00000000, 0x5a5a733f00000000, 0xa1ac607800000000, + 0xacb754b100000000, 0x574147f600000000, 0xf7874df800000000, + 0x0c715ebf00000000, 0x016a6a7600000000, 0xfa9c793100000000, + 0x41e77f6a00000000, 0xba116c2d00000000, 0xb70a58e400000000, + 0x4cfc4ba300000000, 0xec3a41ad00000000, 0x17cc52ea00000000, + 0x1ad7662300000000, 0xe121756400000000, 0x41d2291a00000000, + 0xba243a5d00000000, 0xb73f0e9400000000, 0x4cc91dd300000000, + 0xec0f17dd00000000, 0x17f9049a00000000, 0x1ae2305300000000, + 0xe114231400000000, 0x5a6f254f00000000, 0xa199360800000000, + 0xac8202c100000000, 0x5774118600000000, 0xf7b21b8800000000, + 0x0c4408cf00000000, 0x015f3c0600000000, 0xfaa92f4100000000, + 0x77a830b000000000, 0x8c5e23f700000000, 0x8145173e00000000, + 0x7ab3047900000000, 0xda750e7700000000, 0x21831d3000000000, + 0x2c9829f900000000, 0xd76e3abe00000000, 0x6c153ce500000000, + 0x97e32fa200000000, 0x9af81b6b00000000, 0x610e082c00000000, + 0xc1c8022200000000, 0x3a3e116500000000, 0x372525ac00000000, + 0xccd336eb00000000}, + {0x0000000000000000, 0x6238282a00000000, 0xc470505400000000, + 0xa648787e00000000, 0x88e1a0a800000000, 0xead9888200000000, + 0x4c91f0fc00000000, 0x2ea9d8d600000000, 0x51c5308a00000000, + 0x33fd18a000000000, 0x95b560de00000000, 0xf78d48f400000000, + 0xd924902200000000, 0xbb1cb80800000000, 0x1d54c07600000000, + 0x7f6ce85c00000000, 0xe38c10cf00000000, 0x81b438e500000000, + 0x27fc409b00000000, 0x45c468b100000000, 0x6b6db06700000000, + 0x0955984d00000000, 0xaf1de03300000000, 0xcd25c81900000000, + 0xb249204500000000, 0xd071086f00000000, 0x7639701100000000, + 0x1401583b00000000, 0x3aa880ed00000000, 0x5890a8c700000000, + 0xfed8d0b900000000, 0x9ce0f89300000000, 0x871f504500000000, + 0xe527786f00000000, 0x436f001100000000, 0x2157283b00000000, + 0x0ffef0ed00000000, 0x6dc6d8c700000000, 0xcb8ea0b900000000, + 0xa9b6889300000000, 0xd6da60cf00000000, 0xb4e248e500000000, + 0x12aa309b00000000, 0x709218b100000000, 0x5e3bc06700000000, + 0x3c03e84d00000000, 0x9a4b903300000000, 0xf873b81900000000, + 0x6493408a00000000, 0x06ab68a000000000, 0xa0e310de00000000, + 0xc2db38f400000000, 0xec72e02200000000, 0x8e4ac80800000000, + 0x2802b07600000000, 0x4a3a985c00000000, 0x3556700000000000, + 0x576e582a00000000, 0xf126205400000000, 0x931e087e00000000, + 0xbdb7d0a800000000, 0xdf8ff88200000000, 0x79c780fc00000000, + 0x1bffa8d600000000, 0x0e3fa08a00000000, 0x6c0788a000000000, + 0xca4ff0de00000000, 0xa877d8f400000000, 0x86de002200000000, + 0xe4e6280800000000, 0x42ae507600000000, 0x2096785c00000000, + 0x5ffa900000000000, 0x3dc2b82a00000000, 0x9b8ac05400000000, + 0xf9b2e87e00000000, 0xd71b30a800000000, 0xb523188200000000, + 0x136b60fc00000000, 0x715348d600000000, 0xedb3b04500000000, + 0x8f8b986f00000000, 0x29c3e01100000000, 0x4bfbc83b00000000, + 0x655210ed00000000, 0x076a38c700000000, 0xa12240b900000000, + 0xc31a689300000000, 0xbc7680cf00000000, 0xde4ea8e500000000, + 0x7806d09b00000000, 0x1a3ef8b100000000, 0x3497206700000000, + 0x56af084d00000000, 0xf0e7703300000000, 0x92df581900000000, + 0x8920f0cf00000000, 0xeb18d8e500000000, 0x4d50a09b00000000, + 0x2f6888b100000000, 0x01c1506700000000, 0x63f9784d00000000, + 0xc5b1003300000000, 0xa789281900000000, 0xd8e5c04500000000, + 0xbadde86f00000000, 0x1c95901100000000, 0x7eadb83b00000000, + 0x500460ed00000000, 0x323c48c700000000, 0x947430b900000000, + 0xf64c189300000000, 0x6aace00000000000, 0x0894c82a00000000, + 0xaedcb05400000000, 0xcce4987e00000000, 0xe24d40a800000000, + 0x8075688200000000, 0x263d10fc00000000, 0x440538d600000000, + 0x3b69d08a00000000, 0x5951f8a000000000, 0xff1980de00000000, + 0x9d21a8f400000000, 0xb388702200000000, 0xd1b0580800000000, + 0x77f8207600000000, 0x15c0085c00000000, 0x5d7831ce00000000, + 0x3f4019e400000000, 0x9908619a00000000, 0xfb3049b000000000, + 0xd599916600000000, 0xb7a1b94c00000000, 0x11e9c13200000000, + 0x73d1e91800000000, 0x0cbd014400000000, 0x6e85296e00000000, + 0xc8cd511000000000, 0xaaf5793a00000000, 0x845ca1ec00000000, + 0xe66489c600000000, 0x402cf1b800000000, 0x2214d99200000000, + 0xbef4210100000000, 0xdccc092b00000000, 0x7a84715500000000, + 0x18bc597f00000000, 0x361581a900000000, 0x542da98300000000, + 0xf265d1fd00000000, 0x905df9d700000000, 0xef31118b00000000, + 0x8d0939a100000000, 0x2b4141df00000000, 0x497969f500000000, + 0x67d0b12300000000, 0x05e8990900000000, 0xa3a0e17700000000, + 0xc198c95d00000000, 0xda67618b00000000, 0xb85f49a100000000, + 0x1e1731df00000000, 0x7c2f19f500000000, 0x5286c12300000000, + 0x30bee90900000000, 0x96f6917700000000, 0xf4ceb95d00000000, + 0x8ba2510100000000, 0xe99a792b00000000, 0x4fd2015500000000, + 0x2dea297f00000000, 0x0343f1a900000000, 0x617bd98300000000, + 0xc733a1fd00000000, 0xa50b89d700000000, 0x39eb714400000000, + 0x5bd3596e00000000, 0xfd9b211000000000, 0x9fa3093a00000000, + 0xb10ad1ec00000000, 0xd332f9c600000000, 0x757a81b800000000, + 0x1742a99200000000, 0x682e41ce00000000, 0x0a1669e400000000, + 0xac5e119a00000000, 0xce6639b000000000, 0xe0cfe16600000000, + 0x82f7c94c00000000, 0x24bfb13200000000, 0x4687991800000000, + 0x5347914400000000, 0x317fb96e00000000, 0x9737c11000000000, + 0xf50fe93a00000000, 0xdba631ec00000000, 0xb99e19c600000000, + 0x1fd661b800000000, 0x7dee499200000000, 0x0282a1ce00000000, + 0x60ba89e400000000, 0xc6f2f19a00000000, 0xa4cad9b000000000, + 0x8a63016600000000, 0xe85b294c00000000, 0x4e13513200000000, + 0x2c2b791800000000, 0xb0cb818b00000000, 0xd2f3a9a100000000, + 0x74bbd1df00000000, 0x1683f9f500000000, 0x382a212300000000, + 0x5a12090900000000, 0xfc5a717700000000, 0x9e62595d00000000, + 0xe10eb10100000000, 0x8336992b00000000, 0x257ee15500000000, + 0x4746c97f00000000, 0x69ef11a900000000, 0x0bd7398300000000, + 0xad9f41fd00000000, 0xcfa769d700000000, 0xd458c10100000000, + 0xb660e92b00000000, 0x1028915500000000, 0x7210b97f00000000, + 0x5cb961a900000000, 0x3e81498300000000, 0x98c931fd00000000, + 0xfaf119d700000000, 0x859df18b00000000, 0xe7a5d9a100000000, + 0x41eda1df00000000, 0x23d589f500000000, 0x0d7c512300000000, + 0x6f44790900000000, 0xc90c017700000000, 0xab34295d00000000, + 0x37d4d1ce00000000, 0x55ecf9e400000000, 0xf3a4819a00000000, + 0x919ca9b000000000, 0xbf35716600000000, 0xdd0d594c00000000, + 0x7b45213200000000, 0x197d091800000000, 0x6611e14400000000, + 0x0429c96e00000000, 0xa261b11000000000, 0xc059993a00000000, + 0xeef041ec00000000, 0x8cc869c600000000, 0x2a8011b800000000, + 0x48b8399200000000}, + {0x0000000000000000, 0x4c2896a300000000, 0xd9565d9c00000000, + 0x957ecb3f00000000, 0xf3abcbe300000000, 0xbf835d4000000000, + 0x2afd967f00000000, 0x66d500dc00000000, 0xa751e61c00000000, + 0xeb7970bf00000000, 0x7e07bb8000000000, 0x322f2d2300000000, + 0x54fa2dff00000000, 0x18d2bb5c00000000, 0x8dac706300000000, + 0xc184e6c000000000, 0x4ea3cc3900000000, 0x028b5a9a00000000, + 0x97f591a500000000, 0xdbdd070600000000, 0xbd0807da00000000, + 0xf120917900000000, 0x645e5a4600000000, 0x2876cce500000000, + 0xe9f22a2500000000, 0xa5dabc8600000000, 0x30a477b900000000, + 0x7c8ce11a00000000, 0x1a59e1c600000000, 0x5671776500000000, + 0xc30fbc5a00000000, 0x8f272af900000000, 0x9c46997300000000, + 0xd06e0fd000000000, 0x4510c4ef00000000, 0x0938524c00000000, + 0x6fed529000000000, 0x23c5c43300000000, 0xb6bb0f0c00000000, + 0xfa9399af00000000, 0x3b177f6f00000000, 0x773fe9cc00000000, + 0xe24122f300000000, 0xae69b45000000000, 0xc8bcb48c00000000, + 0x8494222f00000000, 0x11eae91000000000, 0x5dc27fb300000000, + 0xd2e5554a00000000, 0x9ecdc3e900000000, 0x0bb308d600000000, + 0x479b9e7500000000, 0x214e9ea900000000, 0x6d66080a00000000, + 0xf818c33500000000, 0xb430559600000000, 0x75b4b35600000000, + 0x399c25f500000000, 0xace2eeca00000000, 0xe0ca786900000000, + 0x861f78b500000000, 0xca37ee1600000000, 0x5f49252900000000, + 0x1361b38a00000000, 0x388d32e700000000, 0x74a5a44400000000, + 0xe1db6f7b00000000, 0xadf3f9d800000000, 0xcb26f90400000000, + 0x870e6fa700000000, 0x1270a49800000000, 0x5e58323b00000000, + 0x9fdcd4fb00000000, 0xd3f4425800000000, 0x468a896700000000, + 0x0aa21fc400000000, 0x6c771f1800000000, 0x205f89bb00000000, + 0xb521428400000000, 0xf909d42700000000, 0x762efede00000000, + 0x3a06687d00000000, 0xaf78a34200000000, 0xe35035e100000000, + 0x8585353d00000000, 0xc9ada39e00000000, 0x5cd368a100000000, + 0x10fbfe0200000000, 0xd17f18c200000000, 0x9d578e6100000000, + 0x0829455e00000000, 0x4401d3fd00000000, 0x22d4d32100000000, + 0x6efc458200000000, 0xfb828ebd00000000, 0xb7aa181e00000000, + 0xa4cbab9400000000, 0xe8e33d3700000000, 0x7d9df60800000000, + 0x31b560ab00000000, 0x5760607700000000, 0x1b48f6d400000000, + 0x8e363deb00000000, 0xc21eab4800000000, 0x039a4d8800000000, + 0x4fb2db2b00000000, 0xdacc101400000000, 0x96e486b700000000, + 0xf031866b00000000, 0xbc1910c800000000, 0x2967dbf700000000, + 0x654f4d5400000000, 0xea6867ad00000000, 0xa640f10e00000000, + 0x333e3a3100000000, 0x7f16ac9200000000, 0x19c3ac4e00000000, + 0x55eb3aed00000000, 0xc095f1d200000000, 0x8cbd677100000000, + 0x4d3981b100000000, 0x0111171200000000, 0x946fdc2d00000000, + 0xd8474a8e00000000, 0xbe924a5200000000, 0xf2badcf100000000, + 0x67c417ce00000000, 0x2bec816d00000000, 0x311c141500000000, + 0x7d3482b600000000, 0xe84a498900000000, 0xa462df2a00000000, + 0xc2b7dff600000000, 0x8e9f495500000000, 0x1be1826a00000000, + 0x57c914c900000000, 0x964df20900000000, 0xda6564aa00000000, + 0x4f1baf9500000000, 0x0333393600000000, 0x65e639ea00000000, + 0x29ceaf4900000000, 0xbcb0647600000000, 0xf098f2d500000000, + 0x7fbfd82c00000000, 0x33974e8f00000000, 0xa6e985b000000000, + 0xeac1131300000000, 0x8c1413cf00000000, 0xc03c856c00000000, + 0x55424e5300000000, 0x196ad8f000000000, 0xd8ee3e3000000000, + 0x94c6a89300000000, 0x01b863ac00000000, 0x4d90f50f00000000, + 0x2b45f5d300000000, 0x676d637000000000, 0xf213a84f00000000, + 0xbe3b3eec00000000, 0xad5a8d6600000000, 0xe1721bc500000000, + 0x740cd0fa00000000, 0x3824465900000000, 0x5ef1468500000000, + 0x12d9d02600000000, 0x87a71b1900000000, 0xcb8f8dba00000000, + 0x0a0b6b7a00000000, 0x4623fdd900000000, 0xd35d36e600000000, + 0x9f75a04500000000, 0xf9a0a09900000000, 0xb588363a00000000, + 0x20f6fd0500000000, 0x6cde6ba600000000, 0xe3f9415f00000000, + 0xafd1d7fc00000000, 0x3aaf1cc300000000, 0x76878a6000000000, + 0x10528abc00000000, 0x5c7a1c1f00000000, 0xc904d72000000000, + 0x852c418300000000, 0x44a8a74300000000, 0x088031e000000000, + 0x9dfefadf00000000, 0xd1d66c7c00000000, 0xb7036ca000000000, + 0xfb2bfa0300000000, 0x6e55313c00000000, 0x227da79f00000000, + 0x099126f200000000, 0x45b9b05100000000, 0xd0c77b6e00000000, + 0x9cefedcd00000000, 0xfa3aed1100000000, 0xb6127bb200000000, + 0x236cb08d00000000, 0x6f44262e00000000, 0xaec0c0ee00000000, + 0xe2e8564d00000000, 0x77969d7200000000, 0x3bbe0bd100000000, + 0x5d6b0b0d00000000, 0x11439dae00000000, 0x843d569100000000, + 0xc815c03200000000, 0x4732eacb00000000, 0x0b1a7c6800000000, + 0x9e64b75700000000, 0xd24c21f400000000, 0xb499212800000000, + 0xf8b1b78b00000000, 0x6dcf7cb400000000, 0x21e7ea1700000000, + 0xe0630cd700000000, 0xac4b9a7400000000, 0x3935514b00000000, + 0x751dc7e800000000, 0x13c8c73400000000, 0x5fe0519700000000, + 0xca9e9aa800000000, 0x86b60c0b00000000, 0x95d7bf8100000000, + 0xd9ff292200000000, 0x4c81e21d00000000, 0x00a974be00000000, + 0x667c746200000000, 0x2a54e2c100000000, 0xbf2a29fe00000000, + 0xf302bf5d00000000, 0x3286599d00000000, 0x7eaecf3e00000000, + 0xebd0040100000000, 0xa7f892a200000000, 0xc12d927e00000000, + 0x8d0504dd00000000, 0x187bcfe200000000, 0x5453594100000000, + 0xdb7473b800000000, 0x975ce51b00000000, 0x02222e2400000000, + 0x4e0ab88700000000, 0x28dfb85b00000000, 0x64f72ef800000000, + 0xf189e5c700000000, 0xbda1736400000000, 0x7c2595a400000000, + 0x300d030700000000, 0xa573c83800000000, 0xe95b5e9b00000000, + 0x8f8e5e4700000000, 0xc3a6c8e400000000, 0x56d803db00000000, + 0x1af0957800000000}, + {0x0000000000000000, 0x939bc97f00000000, 0x263793ff00000000, + 0xb5ac5a8000000000, 0x0d68572400000000, 0x9ef39e5b00000000, + 0x2b5fc4db00000000, 0xb8c40da400000000, 0x1ad0ae4800000000, + 0x894b673700000000, 0x3ce73db700000000, 0xaf7cf4c800000000, + 0x17b8f96c00000000, 0x8423301300000000, 0x318f6a9300000000, + 0xa214a3ec00000000, 0x34a05d9100000000, 0xa73b94ee00000000, + 0x1297ce6e00000000, 0x810c071100000000, 0x39c80ab500000000, + 0xaa53c3ca00000000, 0x1fff994a00000000, 0x8c64503500000000, + 0x2e70f3d900000000, 0xbdeb3aa600000000, 0x0847602600000000, + 0x9bdca95900000000, 0x2318a4fd00000000, 0xb0836d8200000000, + 0x052f370200000000, 0x96b4fe7d00000000, 0x2946caf900000000, + 0xbadd038600000000, 0x0f71590600000000, 0x9cea907900000000, + 0x242e9ddd00000000, 0xb7b554a200000000, 0x02190e2200000000, + 0x9182c75d00000000, 0x339664b100000000, 0xa00dadce00000000, + 0x15a1f74e00000000, 0x863a3e3100000000, 0x3efe339500000000, + 0xad65faea00000000, 0x18c9a06a00000000, 0x8b52691500000000, + 0x1de6976800000000, 0x8e7d5e1700000000, 0x3bd1049700000000, + 0xa84acde800000000, 0x108ec04c00000000, 0x8315093300000000, + 0x36b953b300000000, 0xa5229acc00000000, 0x0736392000000000, + 0x94adf05f00000000, 0x2101aadf00000000, 0xb29a63a000000000, + 0x0a5e6e0400000000, 0x99c5a77b00000000, 0x2c69fdfb00000000, + 0xbff2348400000000, 0x138ae52800000000, 0x80112c5700000000, + 0x35bd76d700000000, 0xa626bfa800000000, 0x1ee2b20c00000000, + 0x8d797b7300000000, 0x38d521f300000000, 0xab4ee88c00000000, + 0x095a4b6000000000, 0x9ac1821f00000000, 0x2f6dd89f00000000, + 0xbcf611e000000000, 0x04321c4400000000, 0x97a9d53b00000000, + 0x22058fbb00000000, 0xb19e46c400000000, 0x272ab8b900000000, + 0xb4b171c600000000, 0x011d2b4600000000, 0x9286e23900000000, + 0x2a42ef9d00000000, 0xb9d926e200000000, 0x0c757c6200000000, + 0x9feeb51d00000000, 0x3dfa16f100000000, 0xae61df8e00000000, + 0x1bcd850e00000000, 0x88564c7100000000, 0x309241d500000000, + 0xa30988aa00000000, 0x16a5d22a00000000, 0x853e1b5500000000, + 0x3acc2fd100000000, 0xa957e6ae00000000, 0x1cfbbc2e00000000, + 0x8f60755100000000, 0x37a478f500000000, 0xa43fb18a00000000, + 0x1193eb0a00000000, 0x8208227500000000, 0x201c819900000000, + 0xb38748e600000000, 0x062b126600000000, 0x95b0db1900000000, + 0x2d74d6bd00000000, 0xbeef1fc200000000, 0x0b43454200000000, + 0x98d88c3d00000000, 0x0e6c724000000000, 0x9df7bb3f00000000, + 0x285be1bf00000000, 0xbbc028c000000000, 0x0304256400000000, + 0x909fec1b00000000, 0x2533b69b00000000, 0xb6a87fe400000000, + 0x14bcdc0800000000, 0x8727157700000000, 0x328b4ff700000000, + 0xa110868800000000, 0x19d48b2c00000000, 0x8a4f425300000000, + 0x3fe318d300000000, 0xac78d1ac00000000, 0x2614cb5100000000, + 0xb58f022e00000000, 0x002358ae00000000, 0x93b891d100000000, + 0x2b7c9c7500000000, 0xb8e7550a00000000, 0x0d4b0f8a00000000, + 0x9ed0c6f500000000, 0x3cc4651900000000, 0xaf5fac6600000000, + 0x1af3f6e600000000, 0x89683f9900000000, 0x31ac323d00000000, + 0xa237fb4200000000, 0x179ba1c200000000, 0x840068bd00000000, + 0x12b496c000000000, 0x812f5fbf00000000, 0x3483053f00000000, + 0xa718cc4000000000, 0x1fdcc1e400000000, 0x8c47089b00000000, + 0x39eb521b00000000, 0xaa709b6400000000, 0x0864388800000000, + 0x9bfff1f700000000, 0x2e53ab7700000000, 0xbdc8620800000000, + 0x050c6fac00000000, 0x9697a6d300000000, 0x233bfc5300000000, + 0xb0a0352c00000000, 0x0f5201a800000000, 0x9cc9c8d700000000, + 0x2965925700000000, 0xbafe5b2800000000, 0x023a568c00000000, + 0x91a19ff300000000, 0x240dc57300000000, 0xb7960c0c00000000, + 0x1582afe000000000, 0x8619669f00000000, 0x33b53c1f00000000, + 0xa02ef56000000000, 0x18eaf8c400000000, 0x8b7131bb00000000, + 0x3edd6b3b00000000, 0xad46a24400000000, 0x3bf25c3900000000, + 0xa869954600000000, 0x1dc5cfc600000000, 0x8e5e06b900000000, + 0x369a0b1d00000000, 0xa501c26200000000, 0x10ad98e200000000, + 0x8336519d00000000, 0x2122f27100000000, 0xb2b93b0e00000000, + 0x0715618e00000000, 0x948ea8f100000000, 0x2c4aa55500000000, + 0xbfd16c2a00000000, 0x0a7d36aa00000000, 0x99e6ffd500000000, + 0x359e2e7900000000, 0xa605e70600000000, 0x13a9bd8600000000, + 0x803274f900000000, 0x38f6795d00000000, 0xab6db02200000000, + 0x1ec1eaa200000000, 0x8d5a23dd00000000, 0x2f4e803100000000, + 0xbcd5494e00000000, 0x097913ce00000000, 0x9ae2dab100000000, + 0x2226d71500000000, 0xb1bd1e6a00000000, 0x041144ea00000000, + 0x978a8d9500000000, 0x013e73e800000000, 0x92a5ba9700000000, + 0x2709e01700000000, 0xb492296800000000, 0x0c5624cc00000000, + 0x9fcdedb300000000, 0x2a61b73300000000, 0xb9fa7e4c00000000, + 0x1beedda000000000, 0x887514df00000000, 0x3dd94e5f00000000, + 0xae42872000000000, 0x16868a8400000000, 0x851d43fb00000000, + 0x30b1197b00000000, 0xa32ad00400000000, 0x1cd8e48000000000, + 0x8f432dff00000000, 0x3aef777f00000000, 0xa974be0000000000, + 0x11b0b3a400000000, 0x822b7adb00000000, 0x3787205b00000000, + 0xa41ce92400000000, 0x06084ac800000000, 0x959383b700000000, + 0x203fd93700000000, 0xb3a4104800000000, 0x0b601dec00000000, + 0x98fbd49300000000, 0x2d578e1300000000, 0xbecc476c00000000, + 0x2878b91100000000, 0xbbe3706e00000000, 0x0e4f2aee00000000, + 0x9dd4e39100000000, 0x2510ee3500000000, 0xb68b274a00000000, + 0x03277dca00000000, 0x90bcb4b500000000, 0x32a8175900000000, + 0xa133de2600000000, 0x149f84a600000000, 0x87044dd900000000, + 0x3fc0407d00000000, 0xac5b890200000000, 0x19f7d38200000000, + 0x8a6c1afd00000000}, + {0x0000000000000000, 0x650b796900000000, 0xca16f2d200000000, + 0xaf1d8bbb00000000, 0xd52b957e00000000, 0xb020ec1700000000, + 0x1f3d67ac00000000, 0x7a361ec500000000, 0xaa572afd00000000, + 0xcf5c539400000000, 0x6041d82f00000000, 0x054aa14600000000, + 0x7f7cbf8300000000, 0x1a77c6ea00000000, 0xb56a4d5100000000, + 0xd061343800000000, 0x15a9252100000000, 0x70a25c4800000000, + 0xdfbfd7f300000000, 0xbab4ae9a00000000, 0xc082b05f00000000, + 0xa589c93600000000, 0x0a94428d00000000, 0x6f9f3be400000000, + 0xbffe0fdc00000000, 0xdaf576b500000000, 0x75e8fd0e00000000, + 0x10e3846700000000, 0x6ad59aa200000000, 0x0fdee3cb00000000, + 0xa0c3687000000000, 0xc5c8111900000000, 0x2a524b4200000000, + 0x4f59322b00000000, 0xe044b99000000000, 0x854fc0f900000000, + 0xff79de3c00000000, 0x9a72a75500000000, 0x356f2cee00000000, + 0x5064558700000000, 0x800561bf00000000, 0xe50e18d600000000, + 0x4a13936d00000000, 0x2f18ea0400000000, 0x552ef4c100000000, + 0x30258da800000000, 0x9f38061300000000, 0xfa337f7a00000000, + 0x3ffb6e6300000000, 0x5af0170a00000000, 0xf5ed9cb100000000, + 0x90e6e5d800000000, 0xead0fb1d00000000, 0x8fdb827400000000, + 0x20c609cf00000000, 0x45cd70a600000000, 0x95ac449e00000000, + 0xf0a73df700000000, 0x5fbab64c00000000, 0x3ab1cf2500000000, + 0x4087d1e000000000, 0x258ca88900000000, 0x8a91233200000000, + 0xef9a5a5b00000000, 0x54a4968400000000, 0x31afefed00000000, + 0x9eb2645600000000, 0xfbb91d3f00000000, 0x818f03fa00000000, + 0xe4847a9300000000, 0x4b99f12800000000, 0x2e92884100000000, + 0xfef3bc7900000000, 0x9bf8c51000000000, 0x34e54eab00000000, + 0x51ee37c200000000, 0x2bd8290700000000, 0x4ed3506e00000000, + 0xe1cedbd500000000, 0x84c5a2bc00000000, 0x410db3a500000000, + 0x2406cacc00000000, 0x8b1b417700000000, 0xee10381e00000000, + 0x942626db00000000, 0xf12d5fb200000000, 0x5e30d40900000000, + 0x3b3bad6000000000, 0xeb5a995800000000, 0x8e51e03100000000, + 0x214c6b8a00000000, 0x444712e300000000, 0x3e710c2600000000, + 0x5b7a754f00000000, 0xf467fef400000000, 0x916c879d00000000, + 0x7ef6ddc600000000, 0x1bfda4af00000000, 0xb4e02f1400000000, + 0xd1eb567d00000000, 0xabdd48b800000000, 0xced631d100000000, + 0x61cbba6a00000000, 0x04c0c30300000000, 0xd4a1f73b00000000, + 0xb1aa8e5200000000, 0x1eb705e900000000, 0x7bbc7c8000000000, + 0x018a624500000000, 0x64811b2c00000000, 0xcb9c909700000000, + 0xae97e9fe00000000, 0x6b5ff8e700000000, 0x0e54818e00000000, + 0xa1490a3500000000, 0xc442735c00000000, 0xbe746d9900000000, + 0xdb7f14f000000000, 0x74629f4b00000000, 0x1169e62200000000, + 0xc108d21a00000000, 0xa403ab7300000000, 0x0b1e20c800000000, + 0x6e1559a100000000, 0x1423476400000000, 0x71283e0d00000000, + 0xde35b5b600000000, 0xbb3eccdf00000000, 0xe94e5cd200000000, + 0x8c4525bb00000000, 0x2358ae0000000000, 0x4653d76900000000, + 0x3c65c9ac00000000, 0x596eb0c500000000, 0xf6733b7e00000000, + 0x9378421700000000, 0x4319762f00000000, 0x26120f4600000000, + 0x890f84fd00000000, 0xec04fd9400000000, 0x9632e35100000000, + 0xf3399a3800000000, 0x5c24118300000000, 0x392f68ea00000000, + 0xfce779f300000000, 0x99ec009a00000000, 0x36f18b2100000000, + 0x53faf24800000000, 0x29ccec8d00000000, 0x4cc795e400000000, + 0xe3da1e5f00000000, 0x86d1673600000000, 0x56b0530e00000000, + 0x33bb2a6700000000, 0x9ca6a1dc00000000, 0xf9add8b500000000, + 0x839bc67000000000, 0xe690bf1900000000, 0x498d34a200000000, + 0x2c864dcb00000000, 0xc31c179000000000, 0xa6176ef900000000, + 0x090ae54200000000, 0x6c019c2b00000000, 0x163782ee00000000, + 0x733cfb8700000000, 0xdc21703c00000000, 0xb92a095500000000, + 0x694b3d6d00000000, 0x0c40440400000000, 0xa35dcfbf00000000, + 0xc656b6d600000000, 0xbc60a81300000000, 0xd96bd17a00000000, + 0x76765ac100000000, 0x137d23a800000000, 0xd6b532b100000000, + 0xb3be4bd800000000, 0x1ca3c06300000000, 0x79a8b90a00000000, + 0x039ea7cf00000000, 0x6695dea600000000, 0xc988551d00000000, + 0xac832c7400000000, 0x7ce2184c00000000, 0x19e9612500000000, + 0xb6f4ea9e00000000, 0xd3ff93f700000000, 0xa9c98d3200000000, + 0xccc2f45b00000000, 0x63df7fe000000000, 0x06d4068900000000, + 0xbdeaca5600000000, 0xd8e1b33f00000000, 0x77fc388400000000, + 0x12f741ed00000000, 0x68c15f2800000000, 0x0dca264100000000, + 0xa2d7adfa00000000, 0xc7dcd49300000000, 0x17bde0ab00000000, + 0x72b699c200000000, 0xddab127900000000, 0xb8a06b1000000000, + 0xc29675d500000000, 0xa79d0cbc00000000, 0x0880870700000000, + 0x6d8bfe6e00000000, 0xa843ef7700000000, 0xcd48961e00000000, + 0x62551da500000000, 0x075e64cc00000000, 0x7d687a0900000000, + 0x1863036000000000, 0xb77e88db00000000, 0xd275f1b200000000, + 0x0214c58a00000000, 0x671fbce300000000, 0xc802375800000000, + 0xad094e3100000000, 0xd73f50f400000000, 0xb234299d00000000, + 0x1d29a22600000000, 0x7822db4f00000000, 0x97b8811400000000, + 0xf2b3f87d00000000, 0x5dae73c600000000, 0x38a50aaf00000000, + 0x4293146a00000000, 0x27986d0300000000, 0x8885e6b800000000, + 0xed8e9fd100000000, 0x3defabe900000000, 0x58e4d28000000000, + 0xf7f9593b00000000, 0x92f2205200000000, 0xe8c43e9700000000, + 0x8dcf47fe00000000, 0x22d2cc4500000000, 0x47d9b52c00000000, + 0x8211a43500000000, 0xe71add5c00000000, 0x480756e700000000, + 0x2d0c2f8e00000000, 0x573a314b00000000, 0x3231482200000000, + 0x9d2cc39900000000, 0xf827baf000000000, 0x28468ec800000000, + 0x4d4df7a100000000, 0xe2507c1a00000000, 0x875b057300000000, + 0xfd6d1bb600000000, 0x986662df00000000, 0x377be96400000000, + 0x5270900d00000000}, + {0x0000000000000000, 0xdcecb13d00000000, 0xb8d9637b00000000, + 0x6435d24600000000, 0x70b3c7f600000000, 0xac5f76cb00000000, + 0xc86aa48d00000000, 0x148615b000000000, 0xa160fe3600000000, + 0x7d8c4f0b00000000, 0x19b99d4d00000000, 0xc5552c7000000000, + 0xd1d339c000000000, 0x0d3f88fd00000000, 0x690a5abb00000000, + 0xb5e6eb8600000000, 0x42c1fc6d00000000, 0x9e2d4d5000000000, + 0xfa189f1600000000, 0x26f42e2b00000000, 0x32723b9b00000000, + 0xee9e8aa600000000, 0x8aab58e000000000, 0x5647e9dd00000000, + 0xe3a1025b00000000, 0x3f4db36600000000, 0x5b78612000000000, + 0x8794d01d00000000, 0x9312c5ad00000000, 0x4ffe749000000000, + 0x2bcba6d600000000, 0xf72717eb00000000, 0x8482f9db00000000, + 0x586e48e600000000, 0x3c5b9aa000000000, 0xe0b72b9d00000000, + 0xf4313e2d00000000, 0x28dd8f1000000000, 0x4ce85d5600000000, + 0x9004ec6b00000000, 0x25e207ed00000000, 0xf90eb6d000000000, + 0x9d3b649600000000, 0x41d7d5ab00000000, 0x5551c01b00000000, + 0x89bd712600000000, 0xed88a36000000000, 0x3164125d00000000, + 0xc64305b600000000, 0x1aafb48b00000000, 0x7e9a66cd00000000, + 0xa276d7f000000000, 0xb6f0c24000000000, 0x6a1c737d00000000, + 0x0e29a13b00000000, 0xd2c5100600000000, 0x6723fb8000000000, + 0xbbcf4abd00000000, 0xdffa98fb00000000, 0x031629c600000000, + 0x17903c7600000000, 0xcb7c8d4b00000000, 0xaf495f0d00000000, + 0x73a5ee3000000000, 0x4903826c00000000, 0x95ef335100000000, + 0xf1dae11700000000, 0x2d36502a00000000, 0x39b0459a00000000, + 0xe55cf4a700000000, 0x816926e100000000, 0x5d8597dc00000000, + 0xe8637c5a00000000, 0x348fcd6700000000, 0x50ba1f2100000000, + 0x8c56ae1c00000000, 0x98d0bbac00000000, 0x443c0a9100000000, + 0x2009d8d700000000, 0xfce569ea00000000, 0x0bc27e0100000000, + 0xd72ecf3c00000000, 0xb31b1d7a00000000, 0x6ff7ac4700000000, + 0x7b71b9f700000000, 0xa79d08ca00000000, 0xc3a8da8c00000000, + 0x1f446bb100000000, 0xaaa2803700000000, 0x764e310a00000000, + 0x127be34c00000000, 0xce97527100000000, 0xda1147c100000000, + 0x06fdf6fc00000000, 0x62c824ba00000000, 0xbe24958700000000, + 0xcd817bb700000000, 0x116dca8a00000000, 0x755818cc00000000, + 0xa9b4a9f100000000, 0xbd32bc4100000000, 0x61de0d7c00000000, + 0x05ebdf3a00000000, 0xd9076e0700000000, 0x6ce1858100000000, + 0xb00d34bc00000000, 0xd438e6fa00000000, 0x08d457c700000000, + 0x1c52427700000000, 0xc0bef34a00000000, 0xa48b210c00000000, + 0x7867903100000000, 0x8f4087da00000000, 0x53ac36e700000000, + 0x3799e4a100000000, 0xeb75559c00000000, 0xfff3402c00000000, + 0x231ff11100000000, 0x472a235700000000, 0x9bc6926a00000000, + 0x2e2079ec00000000, 0xf2ccc8d100000000, 0x96f91a9700000000, + 0x4a15abaa00000000, 0x5e93be1a00000000, 0x827f0f2700000000, + 0xe64add6100000000, 0x3aa66c5c00000000, 0x920604d900000000, + 0x4eeab5e400000000, 0x2adf67a200000000, 0xf633d69f00000000, + 0xe2b5c32f00000000, 0x3e59721200000000, 0x5a6ca05400000000, + 0x8680116900000000, 0x3366faef00000000, 0xef8a4bd200000000, + 0x8bbf999400000000, 0x575328a900000000, 0x43d53d1900000000, + 0x9f398c2400000000, 0xfb0c5e6200000000, 0x27e0ef5f00000000, + 0xd0c7f8b400000000, 0x0c2b498900000000, 0x681e9bcf00000000, + 0xb4f22af200000000, 0xa0743f4200000000, 0x7c988e7f00000000, + 0x18ad5c3900000000, 0xc441ed0400000000, 0x71a7068200000000, + 0xad4bb7bf00000000, 0xc97e65f900000000, 0x1592d4c400000000, + 0x0114c17400000000, 0xddf8704900000000, 0xb9cda20f00000000, + 0x6521133200000000, 0x1684fd0200000000, 0xca684c3f00000000, + 0xae5d9e7900000000, 0x72b12f4400000000, 0x66373af400000000, + 0xbadb8bc900000000, 0xdeee598f00000000, 0x0202e8b200000000, + 0xb7e4033400000000, 0x6b08b20900000000, 0x0f3d604f00000000, + 0xd3d1d17200000000, 0xc757c4c200000000, 0x1bbb75ff00000000, + 0x7f8ea7b900000000, 0xa362168400000000, 0x5445016f00000000, + 0x88a9b05200000000, 0xec9c621400000000, 0x3070d32900000000, + 0x24f6c69900000000, 0xf81a77a400000000, 0x9c2fa5e200000000, + 0x40c314df00000000, 0xf525ff5900000000, 0x29c94e6400000000, + 0x4dfc9c2200000000, 0x91102d1f00000000, 0x859638af00000000, + 0x597a899200000000, 0x3d4f5bd400000000, 0xe1a3eae900000000, + 0xdb0586b500000000, 0x07e9378800000000, 0x63dce5ce00000000, + 0xbf3054f300000000, 0xabb6414300000000, 0x775af07e00000000, + 0x136f223800000000, 0xcf83930500000000, 0x7a65788300000000, + 0xa689c9be00000000, 0xc2bc1bf800000000, 0x1e50aac500000000, + 0x0ad6bf7500000000, 0xd63a0e4800000000, 0xb20fdc0e00000000, + 0x6ee36d3300000000, 0x99c47ad800000000, 0x4528cbe500000000, + 0x211d19a300000000, 0xfdf1a89e00000000, 0xe977bd2e00000000, + 0x359b0c1300000000, 0x51aede5500000000, 0x8d426f6800000000, + 0x38a484ee00000000, 0xe44835d300000000, 0x807de79500000000, + 0x5c9156a800000000, 0x4817431800000000, 0x94fbf22500000000, + 0xf0ce206300000000, 0x2c22915e00000000, 0x5f877f6e00000000, + 0x836bce5300000000, 0xe75e1c1500000000, 0x3bb2ad2800000000, + 0x2f34b89800000000, 0xf3d809a500000000, 0x97eddbe300000000, + 0x4b016ade00000000, 0xfee7815800000000, 0x220b306500000000, + 0x463ee22300000000, 0x9ad2531e00000000, 0x8e5446ae00000000, + 0x52b8f79300000000, 0x368d25d500000000, 0xea6194e800000000, + 0x1d46830300000000, 0xc1aa323e00000000, 0xa59fe07800000000, + 0x7973514500000000, 0x6df544f500000000, 0xb119f5c800000000, + 0xd52c278e00000000, 0x09c096b300000000, 0xbc267d3500000000, + 0x60cacc0800000000, 0x04ff1e4e00000000, 0xd813af7300000000, + 0xcc95bac300000000, 0x10790bfe00000000, 0x744cd9b800000000, + 0xa8a0688500000000}}; + +#else /* W == 4 */ + +static const uint32_t crc_braid_table[][256] = { + {0x00000000, 0x81256527, 0xd93bcc0f, 0x581ea928, 0x69069e5f, + 0xe823fb78, 0xb03d5250, 0x31183777, 0xd20d3cbe, 0x53285999, + 0x0b36f0b1, 0x8a139596, 0xbb0ba2e1, 0x3a2ec7c6, 0x62306eee, + 0xe3150bc9, 0x7f6b7f3d, 0xfe4e1a1a, 0xa650b332, 0x2775d615, + 0x166de162, 0x97488445, 0xcf562d6d, 0x4e73484a, 0xad664383, + 0x2c4326a4, 0x745d8f8c, 0xf578eaab, 0xc460dddc, 0x4545b8fb, + 0x1d5b11d3, 0x9c7e74f4, 0xfed6fe7a, 0x7ff39b5d, 0x27ed3275, + 0xa6c85752, 0x97d06025, 0x16f50502, 0x4eebac2a, 0xcfcec90d, + 0x2cdbc2c4, 0xadfea7e3, 0xf5e00ecb, 0x74c56bec, 0x45dd5c9b, + 0xc4f839bc, 0x9ce69094, 0x1dc3f5b3, 0x81bd8147, 0x0098e460, + 0x58864d48, 0xd9a3286f, 0xe8bb1f18, 0x699e7a3f, 0x3180d317, + 0xb0a5b630, 0x53b0bdf9, 0xd295d8de, 0x8a8b71f6, 0x0bae14d1, + 0x3ab623a6, 0xbb934681, 0xe38defa9, 0x62a88a8e, 0x26dcfab5, + 0xa7f99f92, 0xffe736ba, 0x7ec2539d, 0x4fda64ea, 0xceff01cd, + 0x96e1a8e5, 0x17c4cdc2, 0xf4d1c60b, 0x75f4a32c, 0x2dea0a04, + 0xaccf6f23, 0x9dd75854, 0x1cf23d73, 0x44ec945b, 0xc5c9f17c, + 0x59b78588, 0xd892e0af, 0x808c4987, 0x01a92ca0, 0x30b11bd7, + 0xb1947ef0, 0xe98ad7d8, 0x68afb2ff, 0x8bbab936, 0x0a9fdc11, + 0x52817539, 0xd3a4101e, 0xe2bc2769, 0x6399424e, 0x3b87eb66, + 0xbaa28e41, 0xd80a04cf, 0x592f61e8, 0x0131c8c0, 0x8014ade7, + 0xb10c9a90, 0x3029ffb7, 0x6837569f, 0xe91233b8, 0x0a073871, + 0x8b225d56, 0xd33cf47e, 0x52199159, 0x6301a62e, 0xe224c309, + 0xba3a6a21, 0x3b1f0f06, 0xa7617bf2, 0x26441ed5, 0x7e5ab7fd, + 0xff7fd2da, 0xce67e5ad, 0x4f42808a, 0x175c29a2, 0x96794c85, + 0x756c474c, 0xf449226b, 0xac578b43, 0x2d72ee64, 0x1c6ad913, + 0x9d4fbc34, 0xc551151c, 0x4474703b, 0x4db9f56a, 0xcc9c904d, + 0x94823965, 0x15a75c42, 0x24bf6b35, 0xa59a0e12, 0xfd84a73a, + 0x7ca1c21d, 0x9fb4c9d4, 0x1e91acf3, 0x468f05db, 0xc7aa60fc, + 0xf6b2578b, 0x779732ac, 0x2f899b84, 0xaeacfea3, 0x32d28a57, + 0xb3f7ef70, 0xebe94658, 0x6acc237f, 0x5bd41408, 0xdaf1712f, + 0x82efd807, 0x03cabd20, 0xe0dfb6e9, 0x61fad3ce, 0x39e47ae6, + 0xb8c11fc1, 0x89d928b6, 0x08fc4d91, 0x50e2e4b9, 0xd1c7819e, + 0xb36f0b10, 0x324a6e37, 0x6a54c71f, 0xeb71a238, 0xda69954f, + 0x5b4cf068, 0x03525940, 0x82773c67, 0x616237ae, 0xe0475289, + 0xb859fba1, 0x397c9e86, 0x0864a9f1, 0x8941ccd6, 0xd15f65fe, + 0x507a00d9, 0xcc04742d, 0x4d21110a, 0x153fb822, 0x941add05, + 0xa502ea72, 0x24278f55, 0x7c39267d, 0xfd1c435a, 0x1e094893, + 0x9f2c2db4, 0xc732849c, 0x4617e1bb, 0x770fd6cc, 0xf62ab3eb, + 0xae341ac3, 0x2f117fe4, 0x6b650fdf, 0xea406af8, 0xb25ec3d0, + 0x337ba6f7, 0x02639180, 0x8346f4a7, 0xdb585d8f, 0x5a7d38a8, + 0xb9683361, 0x384d5646, 0x6053ff6e, 0xe1769a49, 0xd06ead3e, + 0x514bc819, 0x09556131, 0x88700416, 0x140e70e2, 0x952b15c5, + 0xcd35bced, 0x4c10d9ca, 0x7d08eebd, 0xfc2d8b9a, 0xa43322b2, + 0x25164795, 0xc6034c5c, 0x4726297b, 0x1f388053, 0x9e1de574, + 0xaf05d203, 0x2e20b724, 0x763e1e0c, 0xf71b7b2b, 0x95b3f1a5, + 0x14969482, 0x4c883daa, 0xcdad588d, 0xfcb56ffa, 0x7d900add, + 0x258ea3f5, 0xa4abc6d2, 0x47becd1b, 0xc69ba83c, 0x9e850114, + 0x1fa06433, 0x2eb85344, 0xaf9d3663, 0xf7839f4b, 0x76a6fa6c, + 0xead88e98, 0x6bfdebbf, 0x33e34297, 0xb2c627b0, 0x83de10c7, + 0x02fb75e0, 0x5ae5dcc8, 0xdbc0b9ef, 0x38d5b226, 0xb9f0d701, + 0xe1ee7e29, 0x60cb1b0e, 0x51d32c79, 0xd0f6495e, 0x88e8e076, + 0x09cd8551}, + {0x00000000, 0x9b73ead4, 0xed96d3e9, 0x76e5393d, 0x005ca193, + 0x9b2f4b47, 0xedca727a, 0x76b998ae, 0x00b94326, 0x9bcaa9f2, + 0xed2f90cf, 0x765c7a1b, 0x00e5e2b5, 0x9b960861, 0xed73315c, + 0x7600db88, 0x0172864c, 0x9a016c98, 0xece455a5, 0x7797bf71, + 0x012e27df, 0x9a5dcd0b, 0xecb8f436, 0x77cb1ee2, 0x01cbc56a, + 0x9ab82fbe, 0xec5d1683, 0x772efc57, 0x019764f9, 0x9ae48e2d, + 0xec01b710, 0x77725dc4, 0x02e50c98, 0x9996e64c, 0xef73df71, + 0x740035a5, 0x02b9ad0b, 0x99ca47df, 0xef2f7ee2, 0x745c9436, + 0x025c4fbe, 0x992fa56a, 0xefca9c57, 0x74b97683, 0x0200ee2d, + 0x997304f9, 0xef963dc4, 0x74e5d710, 0x03978ad4, 0x98e46000, + 0xee01593d, 0x7572b3e9, 0x03cb2b47, 0x98b8c193, 0xee5df8ae, + 0x752e127a, 0x032ec9f2, 0x985d2326, 0xeeb81a1b, 0x75cbf0cf, + 0x03726861, 0x980182b5, 0xeee4bb88, 0x7597515c, 0x05ca1930, + 0x9eb9f3e4, 0xe85ccad9, 0x732f200d, 0x0596b8a3, 0x9ee55277, + 0xe8006b4a, 0x7373819e, 0x05735a16, 0x9e00b0c2, 0xe8e589ff, + 0x7396632b, 0x052ffb85, 0x9e5c1151, 0xe8b9286c, 0x73cac2b8, + 0x04b89f7c, 0x9fcb75a8, 0xe92e4c95, 0x725da641, 0x04e43eef, + 0x9f97d43b, 0xe972ed06, 0x720107d2, 0x0401dc5a, 0x9f72368e, + 0xe9970fb3, 0x72e4e567, 0x045d7dc9, 0x9f2e971d, 0xe9cbae20, + 0x72b844f4, 0x072f15a8, 0x9c5cff7c, 0xeab9c641, 0x71ca2c95, + 0x0773b43b, 0x9c005eef, 0xeae567d2, 0x71968d06, 0x0796568e, + 0x9ce5bc5a, 0xea008567, 0x71736fb3, 0x07caf71d, 0x9cb91dc9, + 0xea5c24f4, 0x712fce20, 0x065d93e4, 0x9d2e7930, 0xebcb400d, + 0x70b8aad9, 0x06013277, 0x9d72d8a3, 0xeb97e19e, 0x70e40b4a, + 0x06e4d0c2, 0x9d973a16, 0xeb72032b, 0x7001e9ff, 0x06b87151, + 0x9dcb9b85, 0xeb2ea2b8, 0x705d486c, 0x0b943260, 0x90e7d8b4, + 0xe602e189, 0x7d710b5d, 0x0bc893f3, 0x90bb7927, 0xe65e401a, + 0x7d2daace, 0x0b2d7146, 0x905e9b92, 0xe6bba2af, 0x7dc8487b, + 0x0b71d0d5, 0x90023a01, 0xe6e7033c, 0x7d94e9e8, 0x0ae6b42c, + 0x91955ef8, 0xe77067c5, 0x7c038d11, 0x0aba15bf, 0x91c9ff6b, + 0xe72cc656, 0x7c5f2c82, 0x0a5ff70a, 0x912c1dde, 0xe7c924e3, + 0x7cbace37, 0x0a035699, 0x9170bc4d, 0xe7958570, 0x7ce66fa4, + 0x09713ef8, 0x9202d42c, 0xe4e7ed11, 0x7f9407c5, 0x092d9f6b, + 0x925e75bf, 0xe4bb4c82, 0x7fc8a656, 0x09c87dde, 0x92bb970a, + 0xe45eae37, 0x7f2d44e3, 0x0994dc4d, 0x92e73699, 0xe4020fa4, + 0x7f71e570, 0x0803b8b4, 0x93705260, 0xe5956b5d, 0x7ee68189, + 0x085f1927, 0x932cf3f3, 0xe5c9cace, 0x7eba201a, 0x08bafb92, + 0x93c91146, 0xe52c287b, 0x7e5fc2af, 0x08e65a01, 0x9395b0d5, + 0xe57089e8, 0x7e03633c, 0x0e5e2b50, 0x952dc184, 0xe3c8f8b9, + 0x78bb126d, 0x0e028ac3, 0x95716017, 0xe394592a, 0x78e7b3fe, + 0x0ee76876, 0x959482a2, 0xe371bb9f, 0x7802514b, 0x0ebbc9e5, + 0x95c82331, 0xe32d1a0c, 0x785ef0d8, 0x0f2cad1c, 0x945f47c8, + 0xe2ba7ef5, 0x79c99421, 0x0f700c8f, 0x9403e65b, 0xe2e6df66, + 0x799535b2, 0x0f95ee3a, 0x94e604ee, 0xe2033dd3, 0x7970d707, + 0x0fc94fa9, 0x94baa57d, 0xe25f9c40, 0x792c7694, 0x0cbb27c8, + 0x97c8cd1c, 0xe12df421, 0x7a5e1ef5, 0x0ce7865b, 0x97946c8f, + 0xe17155b2, 0x7a02bf66, 0x0c0264ee, 0x97718e3a, 0xe194b707, + 0x7ae75dd3, 0x0c5ec57d, 0x972d2fa9, 0xe1c81694, 0x7abbfc40, + 0x0dc9a184, 0x96ba4b50, 0xe05f726d, 0x7b2c98b9, 0x0d950017, + 0x96e6eac3, 0xe003d3fe, 0x7b70392a, 0x0d70e2a2, 0x96030876, + 0xe0e6314b, 0x7b95db9f, 0x0d2c4331, 0x965fa9e5, 0xe0ba90d8, + 0x7bc97a0c}, + {0x00000000, 0x172864c0, 0x2e50c980, 0x3978ad40, 0x5ca19300, + 0x4b89f7c0, 0x72f15a80, 0x65d93e40, 0xb9432600, 0xae6b42c0, + 0x9713ef80, 0x803b8b40, 0xe5e2b500, 0xf2cad1c0, 0xcbb27c80, + 0xdc9a1840, 0xa9f74a41, 0xbedf2e81, 0x87a783c1, 0x908fe701, + 0xf556d941, 0xe27ebd81, 0xdb0610c1, 0xcc2e7401, 0x10b46c41, + 0x079c0881, 0x3ee4a5c1, 0x29ccc101, 0x4c15ff41, 0x5b3d9b81, + 0x624536c1, 0x756d5201, 0x889f92c3, 0x9fb7f603, 0xa6cf5b43, + 0xb1e73f83, 0xd43e01c3, 0xc3166503, 0xfa6ec843, 0xed46ac83, + 0x31dcb4c3, 0x26f4d003, 0x1f8c7d43, 0x08a41983, 0x6d7d27c3, + 0x7a554303, 0x432dee43, 0x54058a83, 0x2168d882, 0x3640bc42, + 0x0f381102, 0x181075c2, 0x7dc94b82, 0x6ae12f42, 0x53998202, + 0x44b1e6c2, 0x982bfe82, 0x8f039a42, 0xb67b3702, 0xa15353c2, + 0xc48a6d82, 0xd3a20942, 0xeadaa402, 0xfdf2c0c2, 0xca4e23c7, + 0xdd664707, 0xe41eea47, 0xf3368e87, 0x96efb0c7, 0x81c7d407, + 0xb8bf7947, 0xaf971d87, 0x730d05c7, 0x64256107, 0x5d5dcc47, + 0x4a75a887, 0x2fac96c7, 0x3884f207, 0x01fc5f47, 0x16d43b87, + 0x63b96986, 0x74910d46, 0x4de9a006, 0x5ac1c4c6, 0x3f18fa86, + 0x28309e46, 0x11483306, 0x066057c6, 0xdafa4f86, 0xcdd22b46, + 0xf4aa8606, 0xe382e2c6, 0x865bdc86, 0x9173b846, 0xa80b1506, + 0xbf2371c6, 0x42d1b104, 0x55f9d5c4, 0x6c817884, 0x7ba91c44, + 0x1e702204, 0x095846c4, 0x3020eb84, 0x27088f44, 0xfb929704, + 0xecbaf3c4, 0xd5c25e84, 0xc2ea3a44, 0xa7330404, 0xb01b60c4, + 0x8963cd84, 0x9e4ba944, 0xeb26fb45, 0xfc0e9f85, 0xc57632c5, + 0xd25e5605, 0xb7876845, 0xa0af0c85, 0x99d7a1c5, 0x8effc505, + 0x5265dd45, 0x454db985, 0x7c3514c5, 0x6b1d7005, 0x0ec44e45, + 0x19ec2a85, 0x209487c5, 0x37bce305, 0x4fed41cf, 0x58c5250f, + 0x61bd884f, 0x7695ec8f, 0x134cd2cf, 0x0464b60f, 0x3d1c1b4f, + 0x2a347f8f, 0xf6ae67cf, 0xe186030f, 0xd8feae4f, 0xcfd6ca8f, + 0xaa0ff4cf, 0xbd27900f, 0x845f3d4f, 0x9377598f, 0xe61a0b8e, + 0xf1326f4e, 0xc84ac20e, 0xdf62a6ce, 0xbabb988e, 0xad93fc4e, + 0x94eb510e, 0x83c335ce, 0x5f592d8e, 0x4871494e, 0x7109e40e, + 0x662180ce, 0x03f8be8e, 0x14d0da4e, 0x2da8770e, 0x3a8013ce, + 0xc772d30c, 0xd05ab7cc, 0xe9221a8c, 0xfe0a7e4c, 0x9bd3400c, + 0x8cfb24cc, 0xb583898c, 0xa2abed4c, 0x7e31f50c, 0x691991cc, + 0x50613c8c, 0x4749584c, 0x2290660c, 0x35b802cc, 0x0cc0af8c, + 0x1be8cb4c, 0x6e85994d, 0x79adfd8d, 0x40d550cd, 0x57fd340d, + 0x32240a4d, 0x250c6e8d, 0x1c74c3cd, 0x0b5ca70d, 0xd7c6bf4d, + 0xc0eedb8d, 0xf99676cd, 0xeebe120d, 0x8b672c4d, 0x9c4f488d, + 0xa537e5cd, 0xb21f810d, 0x85a36208, 0x928b06c8, 0xabf3ab88, + 0xbcdbcf48, 0xd902f108, 0xce2a95c8, 0xf7523888, 0xe07a5c48, + 0x3ce04408, 0x2bc820c8, 0x12b08d88, 0x0598e948, 0x6041d708, + 0x7769b3c8, 0x4e111e88, 0x59397a48, 0x2c542849, 0x3b7c4c89, + 0x0204e1c9, 0x152c8509, 0x70f5bb49, 0x67dddf89, 0x5ea572c9, + 0x498d1609, 0x95170e49, 0x823f6a89, 0xbb47c7c9, 0xac6fa309, + 0xc9b69d49, 0xde9ef989, 0xe7e654c9, 0xf0ce3009, 0x0d3cf0cb, + 0x1a14940b, 0x236c394b, 0x34445d8b, 0x519d63cb, 0x46b5070b, + 0x7fcdaa4b, 0x68e5ce8b, 0xb47fd6cb, 0xa357b20b, 0x9a2f1f4b, + 0x8d077b8b, 0xe8de45cb, 0xfff6210b, 0xc68e8c4b, 0xd1a6e88b, + 0xa4cbba8a, 0xb3e3de4a, 0x8a9b730a, 0x9db317ca, 0xf86a298a, + 0xef424d4a, 0xd63ae00a, 0xc11284ca, 0x1d889c8a, 0x0aa0f84a, + 0x33d8550a, 0x24f031ca, 0x41290f8a, 0x56016b4a, 0x6f79c60a, + 0x7851a2ca}, + {0x00000000, 0x9fda839e, 0xe4c4017d, 0x7b1e82e3, 0x12f904bb, + 0x8d238725, 0xf63d05c6, 0x69e78658, 0x25f20976, 0xba288ae8, + 0xc136080b, 0x5eec8b95, 0x370b0dcd, 0xa8d18e53, 0xd3cf0cb0, + 0x4c158f2e, 0x4be412ec, 0xd43e9172, 0xaf201391, 0x30fa900f, + 0x591d1657, 0xc6c795c9, 0xbdd9172a, 0x220394b4, 0x6e161b9a, + 0xf1cc9804, 0x8ad21ae7, 0x15089979, 0x7cef1f21, 0xe3359cbf, + 0x982b1e5c, 0x07f19dc2, 0x97c825d8, 0x0812a646, 0x730c24a5, + 0xecd6a73b, 0x85312163, 0x1aeba2fd, 0x61f5201e, 0xfe2fa380, + 0xb23a2cae, 0x2de0af30, 0x56fe2dd3, 0xc924ae4d, 0xa0c32815, + 0x3f19ab8b, 0x44072968, 0xdbddaaf6, 0xdc2c3734, 0x43f6b4aa, + 0x38e83649, 0xa732b5d7, 0xced5338f, 0x510fb011, 0x2a1132f2, + 0xb5cbb16c, 0xf9de3e42, 0x6604bddc, 0x1d1a3f3f, 0x82c0bca1, + 0xeb273af9, 0x74fdb967, 0x0fe33b84, 0x9039b81a, 0xf4e14df1, + 0x6b3bce6f, 0x10254c8c, 0x8fffcf12, 0xe618494a, 0x79c2cad4, + 0x02dc4837, 0x9d06cba9, 0xd1134487, 0x4ec9c719, 0x35d745fa, + 0xaa0dc664, 0xc3ea403c, 0x5c30c3a2, 0x272e4141, 0xb8f4c2df, + 0xbf055f1d, 0x20dfdc83, 0x5bc15e60, 0xc41bddfe, 0xadfc5ba6, + 0x3226d838, 0x49385adb, 0xd6e2d945, 0x9af7566b, 0x052dd5f5, + 0x7e335716, 0xe1e9d488, 0x880e52d0, 0x17d4d14e, 0x6cca53ad, + 0xf310d033, 0x63296829, 0xfcf3ebb7, 0x87ed6954, 0x1837eaca, + 0x71d06c92, 0xee0aef0c, 0x95146def, 0x0aceee71, 0x46db615f, + 0xd901e2c1, 0xa21f6022, 0x3dc5e3bc, 0x542265e4, 0xcbf8e67a, + 0xb0e66499, 0x2f3ce707, 0x28cd7ac5, 0xb717f95b, 0xcc097bb8, + 0x53d3f826, 0x3a347e7e, 0xa5eefde0, 0xdef07f03, 0x412afc9d, + 0x0d3f73b3, 0x92e5f02d, 0xe9fb72ce, 0x7621f150, 0x1fc67708, + 0x801cf496, 0xfb027675, 0x64d8f5eb, 0x32b39da3, 0xad691e3d, + 0xd6779cde, 0x49ad1f40, 0x204a9918, 0xbf901a86, 0xc48e9865, + 0x5b541bfb, 0x174194d5, 0x889b174b, 0xf38595a8, 0x6c5f1636, + 0x05b8906e, 0x9a6213f0, 0xe17c9113, 0x7ea6128d, 0x79578f4f, + 0xe68d0cd1, 0x9d938e32, 0x02490dac, 0x6bae8bf4, 0xf474086a, + 0x8f6a8a89, 0x10b00917, 0x5ca58639, 0xc37f05a7, 0xb8618744, + 0x27bb04da, 0x4e5c8282, 0xd186011c, 0xaa9883ff, 0x35420061, + 0xa57bb87b, 0x3aa13be5, 0x41bfb906, 0xde653a98, 0xb782bcc0, + 0x28583f5e, 0x5346bdbd, 0xcc9c3e23, 0x8089b10d, 0x1f533293, + 0x644db070, 0xfb9733ee, 0x9270b5b6, 0x0daa3628, 0x76b4b4cb, + 0xe96e3755, 0xee9faa97, 0x71452909, 0x0a5babea, 0x95812874, + 0xfc66ae2c, 0x63bc2db2, 0x18a2af51, 0x87782ccf, 0xcb6da3e1, + 0x54b7207f, 0x2fa9a29c, 0xb0732102, 0xd994a75a, 0x464e24c4, + 0x3d50a627, 0xa28a25b9, 0xc652d052, 0x598853cc, 0x2296d12f, + 0xbd4c52b1, 0xd4abd4e9, 0x4b715777, 0x306fd594, 0xafb5560a, + 0xe3a0d924, 0x7c7a5aba, 0x0764d859, 0x98be5bc7, 0xf159dd9f, + 0x6e835e01, 0x159ddce2, 0x8a475f7c, 0x8db6c2be, 0x126c4120, + 0x6972c3c3, 0xf6a8405d, 0x9f4fc605, 0x0095459b, 0x7b8bc778, + 0xe45144e6, 0xa844cbc8, 0x379e4856, 0x4c80cab5, 0xd35a492b, + 0xbabdcf73, 0x25674ced, 0x5e79ce0e, 0xc1a34d90, 0x519af58a, + 0xce407614, 0xb55ef4f7, 0x2a847769, 0x4363f131, 0xdcb972af, + 0xa7a7f04c, 0x387d73d2, 0x7468fcfc, 0xebb27f62, 0x90acfd81, + 0x0f767e1f, 0x6691f847, 0xf94b7bd9, 0x8255f93a, 0x1d8f7aa4, + 0x1a7ee766, 0x85a464f8, 0xfebae61b, 0x61606585, 0x0887e3dd, + 0x975d6043, 0xec43e2a0, 0x7399613e, 0x3f8cee10, 0xa0566d8e, + 0xdb48ef6d, 0x44926cf3, 0x2d75eaab, 0xb2af6935, 0xc9b1ebd6, + 0x566b6848}}; + +static const z_word_t crc_braid_big_table[][256] = { + {0x00000000, 0x9e83da9f, 0x7d01c4e4, 0xe3821e7b, 0xbb04f912, + 0x2587238d, 0xc6053df6, 0x5886e769, 0x7609f225, 0xe88a28ba, + 0x0b0836c1, 0x958bec5e, 0xcd0d0b37, 0x538ed1a8, 0xb00ccfd3, + 0x2e8f154c, 0xec12e44b, 0x72913ed4, 0x911320af, 0x0f90fa30, + 0x57161d59, 0xc995c7c6, 0x2a17d9bd, 0xb4940322, 0x9a1b166e, + 0x0498ccf1, 0xe71ad28a, 0x79990815, 0x211fef7c, 0xbf9c35e3, + 0x5c1e2b98, 0xc29df107, 0xd825c897, 0x46a61208, 0xa5240c73, + 0x3ba7d6ec, 0x63213185, 0xfda2eb1a, 0x1e20f561, 0x80a32ffe, + 0xae2c3ab2, 0x30afe02d, 0xd32dfe56, 0x4dae24c9, 0x1528c3a0, + 0x8bab193f, 0x68290744, 0xf6aadddb, 0x34372cdc, 0xaab4f643, + 0x4936e838, 0xd7b532a7, 0x8f33d5ce, 0x11b00f51, 0xf232112a, + 0x6cb1cbb5, 0x423edef9, 0xdcbd0466, 0x3f3f1a1d, 0xa1bcc082, + 0xf93a27eb, 0x67b9fd74, 0x843be30f, 0x1ab83990, 0xf14de1f4, + 0x6fce3b6b, 0x8c4c2510, 0x12cfff8f, 0x4a4918e6, 0xd4cac279, + 0x3748dc02, 0xa9cb069d, 0x874413d1, 0x19c7c94e, 0xfa45d735, + 0x64c60daa, 0x3c40eac3, 0xa2c3305c, 0x41412e27, 0xdfc2f4b8, + 0x1d5f05bf, 0x83dcdf20, 0x605ec15b, 0xfedd1bc4, 0xa65bfcad, + 0x38d82632, 0xdb5a3849, 0x45d9e2d6, 0x6b56f79a, 0xf5d52d05, + 0x1657337e, 0x88d4e9e1, 0xd0520e88, 0x4ed1d417, 0xad53ca6c, + 0x33d010f3, 0x29682963, 0xb7ebf3fc, 0x5469ed87, 0xcaea3718, + 0x926cd071, 0x0cef0aee, 0xef6d1495, 0x71eece0a, 0x5f61db46, + 0xc1e201d9, 0x22601fa2, 0xbce3c53d, 0xe4652254, 0x7ae6f8cb, + 0x9964e6b0, 0x07e73c2f, 0xc57acd28, 0x5bf917b7, 0xb87b09cc, + 0x26f8d353, 0x7e7e343a, 0xe0fdeea5, 0x037ff0de, 0x9dfc2a41, + 0xb3733f0d, 0x2df0e592, 0xce72fbe9, 0x50f12176, 0x0877c61f, + 0x96f41c80, 0x757602fb, 0xebf5d864, 0xa39db332, 0x3d1e69ad, + 0xde9c77d6, 0x401fad49, 0x18994a20, 0x861a90bf, 0x65988ec4, + 0xfb1b545b, 0xd5944117, 0x4b179b88, 0xa89585f3, 0x36165f6c, + 0x6e90b805, 0xf013629a, 0x13917ce1, 0x8d12a67e, 0x4f8f5779, + 0xd10c8de6, 0x328e939d, 0xac0d4902, 0xf48bae6b, 0x6a0874f4, + 0x898a6a8f, 0x1709b010, 0x3986a55c, 0xa7057fc3, 0x448761b8, + 0xda04bb27, 0x82825c4e, 0x1c0186d1, 0xff8398aa, 0x61004235, + 0x7bb87ba5, 0xe53ba13a, 0x06b9bf41, 0x983a65de, 0xc0bc82b7, + 0x5e3f5828, 0xbdbd4653, 0x233e9ccc, 0x0db18980, 0x9332531f, + 0x70b04d64, 0xee3397fb, 0xb6b57092, 0x2836aa0d, 0xcbb4b476, + 0x55376ee9, 0x97aa9fee, 0x09294571, 0xeaab5b0a, 0x74288195, + 0x2cae66fc, 0xb22dbc63, 0x51afa218, 0xcf2c7887, 0xe1a36dcb, + 0x7f20b754, 0x9ca2a92f, 0x022173b0, 0x5aa794d9, 0xc4244e46, + 0x27a6503d, 0xb9258aa2, 0x52d052c6, 0xcc538859, 0x2fd19622, + 0xb1524cbd, 0xe9d4abd4, 0x7757714b, 0x94d56f30, 0x0a56b5af, + 0x24d9a0e3, 0xba5a7a7c, 0x59d86407, 0xc75bbe98, 0x9fdd59f1, + 0x015e836e, 0xe2dc9d15, 0x7c5f478a, 0xbec2b68d, 0x20416c12, + 0xc3c37269, 0x5d40a8f6, 0x05c64f9f, 0x9b459500, 0x78c78b7b, + 0xe64451e4, 0xc8cb44a8, 0x56489e37, 0xb5ca804c, 0x2b495ad3, + 0x73cfbdba, 0xed4c6725, 0x0ece795e, 0x904da3c1, 0x8af59a51, + 0x147640ce, 0xf7f45eb5, 0x6977842a, 0x31f16343, 0xaf72b9dc, + 0x4cf0a7a7, 0xd2737d38, 0xfcfc6874, 0x627fb2eb, 0x81fdac90, + 0x1f7e760f, 0x47f89166, 0xd97b4bf9, 0x3af95582, 0xa47a8f1d, + 0x66e77e1a, 0xf864a485, 0x1be6bafe, 0x85656061, 0xdde38708, + 0x43605d97, 0xa0e243ec, 0x3e619973, 0x10ee8c3f, 0x8e6d56a0, + 0x6def48db, 0xf36c9244, 0xabea752d, 0x3569afb2, 0xd6ebb1c9, + 0x48686b56}, + {0x00000000, 0xc0642817, 0x80c9502e, 0x40ad7839, 0x0093a15c, + 0xc0f7894b, 0x805af172, 0x403ed965, 0x002643b9, 0xc0426bae, + 0x80ef1397, 0x408b3b80, 0x00b5e2e5, 0xc0d1caf2, 0x807cb2cb, + 0x40189adc, 0x414af7a9, 0x812edfbe, 0xc183a787, 0x01e78f90, + 0x41d956f5, 0x81bd7ee2, 0xc11006db, 0x01742ecc, 0x416cb410, + 0x81089c07, 0xc1a5e43e, 0x01c1cc29, 0x41ff154c, 0x819b3d5b, + 0xc1364562, 0x01526d75, 0xc3929f88, 0x03f6b79f, 0x435bcfa6, + 0x833fe7b1, 0xc3013ed4, 0x036516c3, 0x43c86efa, 0x83ac46ed, + 0xc3b4dc31, 0x03d0f426, 0x437d8c1f, 0x8319a408, 0xc3277d6d, + 0x0343557a, 0x43ee2d43, 0x838a0554, 0x82d86821, 0x42bc4036, + 0x0211380f, 0xc2751018, 0x824bc97d, 0x422fe16a, 0x02829953, + 0xc2e6b144, 0x82fe2b98, 0x429a038f, 0x02377bb6, 0xc25353a1, + 0x826d8ac4, 0x4209a2d3, 0x02a4daea, 0xc2c0f2fd, 0xc7234eca, + 0x074766dd, 0x47ea1ee4, 0x878e36f3, 0xc7b0ef96, 0x07d4c781, + 0x4779bfb8, 0x871d97af, 0xc7050d73, 0x07612564, 0x47cc5d5d, + 0x87a8754a, 0xc796ac2f, 0x07f28438, 0x475ffc01, 0x873bd416, + 0x8669b963, 0x460d9174, 0x06a0e94d, 0xc6c4c15a, 0x86fa183f, + 0x469e3028, 0x06334811, 0xc6576006, 0x864ffada, 0x462bd2cd, + 0x0686aaf4, 0xc6e282e3, 0x86dc5b86, 0x46b87391, 0x06150ba8, + 0xc67123bf, 0x04b1d142, 0xc4d5f955, 0x8478816c, 0x441ca97b, + 0x0422701e, 0xc4465809, 0x84eb2030, 0x448f0827, 0x049792fb, + 0xc4f3baec, 0x845ec2d5, 0x443aeac2, 0x040433a7, 0xc4601bb0, + 0x84cd6389, 0x44a94b9e, 0x45fb26eb, 0x859f0efc, 0xc53276c5, + 0x05565ed2, 0x456887b7, 0x850cafa0, 0xc5a1d799, 0x05c5ff8e, + 0x45dd6552, 0x85b94d45, 0xc514357c, 0x05701d6b, 0x454ec40e, + 0x852aec19, 0xc5879420, 0x05e3bc37, 0xcf41ed4f, 0x0f25c558, + 0x4f88bd61, 0x8fec9576, 0xcfd24c13, 0x0fb66404, 0x4f1b1c3d, + 0x8f7f342a, 0xcf67aef6, 0x0f0386e1, 0x4faefed8, 0x8fcad6cf, + 0xcff40faa, 0x0f9027bd, 0x4f3d5f84, 0x8f597793, 0x8e0b1ae6, + 0x4e6f32f1, 0x0ec24ac8, 0xcea662df, 0x8e98bbba, 0x4efc93ad, + 0x0e51eb94, 0xce35c383, 0x8e2d595f, 0x4e497148, 0x0ee40971, + 0xce802166, 0x8ebef803, 0x4edad014, 0x0e77a82d, 0xce13803a, + 0x0cd372c7, 0xccb75ad0, 0x8c1a22e9, 0x4c7e0afe, 0x0c40d39b, + 0xcc24fb8c, 0x8c8983b5, 0x4cedaba2, 0x0cf5317e, 0xcc911969, + 0x8c3c6150, 0x4c584947, 0x0c669022, 0xcc02b835, 0x8cafc00c, + 0x4ccbe81b, 0x4d99856e, 0x8dfdad79, 0xcd50d540, 0x0d34fd57, + 0x4d0a2432, 0x8d6e0c25, 0xcdc3741c, 0x0da75c0b, 0x4dbfc6d7, + 0x8ddbeec0, 0xcd7696f9, 0x0d12beee, 0x4d2c678b, 0x8d484f9c, + 0xcde537a5, 0x0d811fb2, 0x0862a385, 0xc8068b92, 0x88abf3ab, + 0x48cfdbbc, 0x08f102d9, 0xc8952ace, 0x883852f7, 0x485c7ae0, + 0x0844e03c, 0xc820c82b, 0x888db012, 0x48e99805, 0x08d74160, + 0xc8b36977, 0x881e114e, 0x487a3959, 0x4928542c, 0x894c7c3b, + 0xc9e10402, 0x09852c15, 0x49bbf570, 0x89dfdd67, 0xc972a55e, + 0x09168d49, 0x490e1795, 0x896a3f82, 0xc9c747bb, 0x09a36fac, + 0x499db6c9, 0x89f99ede, 0xc954e6e7, 0x0930cef0, 0xcbf03c0d, + 0x0b94141a, 0x4b396c23, 0x8b5d4434, 0xcb639d51, 0x0b07b546, + 0x4baacd7f, 0x8bcee568, 0xcbd67fb4, 0x0bb257a3, 0x4b1f2f9a, + 0x8b7b078d, 0xcb45dee8, 0x0b21f6ff, 0x4b8c8ec6, 0x8be8a6d1, + 0x8abacba4, 0x4adee3b3, 0x0a739b8a, 0xca17b39d, 0x8a296af8, + 0x4a4d42ef, 0x0ae03ad6, 0xca8412c1, 0x8a9c881d, 0x4af8a00a, + 0x0a55d833, 0xca31f024, 0x8a0f2941, 0x4a6b0156, 0x0ac6796f, + 0xcaa25178}, + {0x00000000, 0xd4ea739b, 0xe9d396ed, 0x3d39e576, 0x93a15c00, + 0x474b2f9b, 0x7a72caed, 0xae98b976, 0x2643b900, 0xf2a9ca9b, + 0xcf902fed, 0x1b7a5c76, 0xb5e2e500, 0x6108969b, 0x5c3173ed, + 0x88db0076, 0x4c867201, 0x986c019a, 0xa555e4ec, 0x71bf9777, + 0xdf272e01, 0x0bcd5d9a, 0x36f4b8ec, 0xe21ecb77, 0x6ac5cb01, + 0xbe2fb89a, 0x83165dec, 0x57fc2e77, 0xf9649701, 0x2d8ee49a, + 0x10b701ec, 0xc45d7277, 0x980ce502, 0x4ce69699, 0x71df73ef, + 0xa5350074, 0x0badb902, 0xdf47ca99, 0xe27e2fef, 0x36945c74, + 0xbe4f5c02, 0x6aa52f99, 0x579ccaef, 0x8376b974, 0x2dee0002, + 0xf9047399, 0xc43d96ef, 0x10d7e574, 0xd48a9703, 0x0060e498, + 0x3d5901ee, 0xe9b37275, 0x472bcb03, 0x93c1b898, 0xaef85dee, + 0x7a122e75, 0xf2c92e03, 0x26235d98, 0x1b1ab8ee, 0xcff0cb75, + 0x61687203, 0xb5820198, 0x88bbe4ee, 0x5c519775, 0x3019ca05, + 0xe4f3b99e, 0xd9ca5ce8, 0x0d202f73, 0xa3b89605, 0x7752e59e, + 0x4a6b00e8, 0x9e817373, 0x165a7305, 0xc2b0009e, 0xff89e5e8, + 0x2b639673, 0x85fb2f05, 0x51115c9e, 0x6c28b9e8, 0xb8c2ca73, + 0x7c9fb804, 0xa875cb9f, 0x954c2ee9, 0x41a65d72, 0xef3ee404, + 0x3bd4979f, 0x06ed72e9, 0xd2070172, 0x5adc0104, 0x8e36729f, + 0xb30f97e9, 0x67e5e472, 0xc97d5d04, 0x1d972e9f, 0x20aecbe9, + 0xf444b872, 0xa8152f07, 0x7cff5c9c, 0x41c6b9ea, 0x952cca71, + 0x3bb47307, 0xef5e009c, 0xd267e5ea, 0x068d9671, 0x8e569607, + 0x5abce59c, 0x678500ea, 0xb36f7371, 0x1df7ca07, 0xc91db99c, + 0xf4245cea, 0x20ce2f71, 0xe4935d06, 0x30792e9d, 0x0d40cbeb, + 0xd9aab870, 0x77320106, 0xa3d8729d, 0x9ee197eb, 0x4a0be470, + 0xc2d0e406, 0x163a979d, 0x2b0372eb, 0xffe90170, 0x5171b806, + 0x859bcb9d, 0xb8a22eeb, 0x6c485d70, 0x6032940b, 0xb4d8e790, + 0x89e102e6, 0x5d0b717d, 0xf393c80b, 0x2779bb90, 0x1a405ee6, + 0xceaa2d7d, 0x46712d0b, 0x929b5e90, 0xafa2bbe6, 0x7b48c87d, + 0xd5d0710b, 0x013a0290, 0x3c03e7e6, 0xe8e9947d, 0x2cb4e60a, + 0xf85e9591, 0xc56770e7, 0x118d037c, 0xbf15ba0a, 0x6bffc991, + 0x56c62ce7, 0x822c5f7c, 0x0af75f0a, 0xde1d2c91, 0xe324c9e7, + 0x37ceba7c, 0x9956030a, 0x4dbc7091, 0x708595e7, 0xa46fe67c, + 0xf83e7109, 0x2cd40292, 0x11ede7e4, 0xc507947f, 0x6b9f2d09, + 0xbf755e92, 0x824cbbe4, 0x56a6c87f, 0xde7dc809, 0x0a97bb92, + 0x37ae5ee4, 0xe3442d7f, 0x4ddc9409, 0x9936e792, 0xa40f02e4, + 0x70e5717f, 0xb4b80308, 0x60527093, 0x5d6b95e5, 0x8981e67e, + 0x27195f08, 0xf3f32c93, 0xcecac9e5, 0x1a20ba7e, 0x92fbba08, + 0x4611c993, 0x7b282ce5, 0xafc25f7e, 0x015ae608, 0xd5b09593, + 0xe88970e5, 0x3c63037e, 0x502b5e0e, 0x84c12d95, 0xb9f8c8e3, + 0x6d12bb78, 0xc38a020e, 0x17607195, 0x2a5994e3, 0xfeb3e778, + 0x7668e70e, 0xa2829495, 0x9fbb71e3, 0x4b510278, 0xe5c9bb0e, + 0x3123c895, 0x0c1a2de3, 0xd8f05e78, 0x1cad2c0f, 0xc8475f94, + 0xf57ebae2, 0x2194c979, 0x8f0c700f, 0x5be60394, 0x66dfe6e2, + 0xb2359579, 0x3aee950f, 0xee04e694, 0xd33d03e2, 0x07d77079, + 0xa94fc90f, 0x7da5ba94, 0x409c5fe2, 0x94762c79, 0xc827bb0c, + 0x1ccdc897, 0x21f42de1, 0xf51e5e7a, 0x5b86e70c, 0x8f6c9497, + 0xb25571e1, 0x66bf027a, 0xee64020c, 0x3a8e7197, 0x07b794e1, + 0xd35de77a, 0x7dc55e0c, 0xa92f2d97, 0x9416c8e1, 0x40fcbb7a, + 0x84a1c90d, 0x504bba96, 0x6d725fe0, 0xb9982c7b, 0x1700950d, + 0xc3eae696, 0xfed303e0, 0x2a39707b, 0xa2e2700d, 0x76080396, + 0x4b31e6e0, 0x9fdb957b, 0x31432c0d, 0xe5a95f96, 0xd890bae0, + 0x0c7ac97b}, + {0x00000000, 0x27652581, 0x0fcc3bd9, 0x28a91e58, 0x5f9e0669, + 0x78fb23e8, 0x50523db0, 0x77371831, 0xbe3c0dd2, 0x99592853, + 0xb1f0360b, 0x9695138a, 0xe1a20bbb, 0xc6c72e3a, 0xee6e3062, + 0xc90b15e3, 0x3d7f6b7f, 0x1a1a4efe, 0x32b350a6, 0x15d67527, + 0x62e16d16, 0x45844897, 0x6d2d56cf, 0x4a48734e, 0x834366ad, + 0xa426432c, 0x8c8f5d74, 0xabea78f5, 0xdcdd60c4, 0xfbb84545, + 0xd3115b1d, 0xf4747e9c, 0x7afed6fe, 0x5d9bf37f, 0x7532ed27, + 0x5257c8a6, 0x2560d097, 0x0205f516, 0x2aaceb4e, 0x0dc9cecf, + 0xc4c2db2c, 0xe3a7fead, 0xcb0ee0f5, 0xec6bc574, 0x9b5cdd45, + 0xbc39f8c4, 0x9490e69c, 0xb3f5c31d, 0x4781bd81, 0x60e49800, + 0x484d8658, 0x6f28a3d9, 0x181fbbe8, 0x3f7a9e69, 0x17d38031, + 0x30b6a5b0, 0xf9bdb053, 0xded895d2, 0xf6718b8a, 0xd114ae0b, + 0xa623b63a, 0x814693bb, 0xa9ef8de3, 0x8e8aa862, 0xb5fadc26, + 0x929ff9a7, 0xba36e7ff, 0x9d53c27e, 0xea64da4f, 0xcd01ffce, + 0xe5a8e196, 0xc2cdc417, 0x0bc6d1f4, 0x2ca3f475, 0x040aea2d, + 0x236fcfac, 0x5458d79d, 0x733df21c, 0x5b94ec44, 0x7cf1c9c5, + 0x8885b759, 0xafe092d8, 0x87498c80, 0xa02ca901, 0xd71bb130, + 0xf07e94b1, 0xd8d78ae9, 0xffb2af68, 0x36b9ba8b, 0x11dc9f0a, + 0x39758152, 0x1e10a4d3, 0x6927bce2, 0x4e429963, 0x66eb873b, + 0x418ea2ba, 0xcf040ad8, 0xe8612f59, 0xc0c83101, 0xe7ad1480, + 0x909a0cb1, 0xb7ff2930, 0x9f563768, 0xb83312e9, 0x7138070a, + 0x565d228b, 0x7ef43cd3, 0x59911952, 0x2ea60163, 0x09c324e2, + 0x216a3aba, 0x060f1f3b, 0xf27b61a7, 0xd51e4426, 0xfdb75a7e, + 0xdad27fff, 0xade567ce, 0x8a80424f, 0xa2295c17, 0x854c7996, + 0x4c476c75, 0x6b2249f4, 0x438b57ac, 0x64ee722d, 0x13d96a1c, + 0x34bc4f9d, 0x1c1551c5, 0x3b707444, 0x6af5b94d, 0x4d909ccc, + 0x65398294, 0x425ca715, 0x356bbf24, 0x120e9aa5, 0x3aa784fd, + 0x1dc2a17c, 0xd4c9b49f, 0xf3ac911e, 0xdb058f46, 0xfc60aac7, + 0x8b57b2f6, 0xac329777, 0x849b892f, 0xa3feacae, 0x578ad232, + 0x70eff7b3, 0x5846e9eb, 0x7f23cc6a, 0x0814d45b, 0x2f71f1da, + 0x07d8ef82, 0x20bdca03, 0xe9b6dfe0, 0xced3fa61, 0xe67ae439, + 0xc11fc1b8, 0xb628d989, 0x914dfc08, 0xb9e4e250, 0x9e81c7d1, + 0x100b6fb3, 0x376e4a32, 0x1fc7546a, 0x38a271eb, 0x4f9569da, + 0x68f04c5b, 0x40595203, 0x673c7782, 0xae376261, 0x895247e0, + 0xa1fb59b8, 0x869e7c39, 0xf1a96408, 0xd6cc4189, 0xfe655fd1, + 0xd9007a50, 0x2d7404cc, 0x0a11214d, 0x22b83f15, 0x05dd1a94, + 0x72ea02a5, 0x558f2724, 0x7d26397c, 0x5a431cfd, 0x9348091e, + 0xb42d2c9f, 0x9c8432c7, 0xbbe11746, 0xccd60f77, 0xebb32af6, + 0xc31a34ae, 0xe47f112f, 0xdf0f656b, 0xf86a40ea, 0xd0c35eb2, + 0xf7a67b33, 0x80916302, 0xa7f44683, 0x8f5d58db, 0xa8387d5a, + 0x613368b9, 0x46564d38, 0x6eff5360, 0x499a76e1, 0x3ead6ed0, + 0x19c84b51, 0x31615509, 0x16047088, 0xe2700e14, 0xc5152b95, + 0xedbc35cd, 0xcad9104c, 0xbdee087d, 0x9a8b2dfc, 0xb22233a4, + 0x95471625, 0x5c4c03c6, 0x7b292647, 0x5380381f, 0x74e51d9e, + 0x03d205af, 0x24b7202e, 0x0c1e3e76, 0x2b7b1bf7, 0xa5f1b395, + 0x82949614, 0xaa3d884c, 0x8d58adcd, 0xfa6fb5fc, 0xdd0a907d, + 0xf5a38e25, 0xd2c6aba4, 0x1bcdbe47, 0x3ca89bc6, 0x1401859e, + 0x3364a01f, 0x4453b82e, 0x63369daf, 0x4b9f83f7, 0x6cfaa676, + 0x988ed8ea, 0xbfebfd6b, 0x9742e333, 0xb027c6b2, 0xc710de83, + 0xe075fb02, 0xc8dce55a, 0xefb9c0db, 0x26b2d538, 0x01d7f0b9, + 0x297eeee1, 0x0e1bcb60, 0x792cd351, 0x5e49f6d0, 0x76e0e888, + 0x5185cd09}}; + +#endif /* W */ + +#endif /* N == 6 */ + +static const uint32_t x2n_table[] = { + 0x40000000, 0x20000000, 0x08000000, 0x00800000, 0x00008000, + 0xedb88320, 0xb1e6b092, 0xa06a2517, 0xed627dae, 0x88d14467, + 0xd7bbfe6a, 0xec447f11, 0x8e7ea170, 0x6427800e, 0x4d47bae0, + 0x09fe548f, 0x83852d0f, 0x30362f1a, 0x7b5a9cc3, 0x31fec169, + 0x9fec022a, 0x6c8dedc4, 0x15d6874d, 0x5fde7a4e, 0xbad90e37, + 0x2e4e5eef, 0x4eaba214, 0xa8a472c0, 0x429a969e, 0x148d302a, + 0xc40ba6d0, 0xc4e22c3c}; + +#endif /* CRC32_BRAID_TBL_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.c b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.c new file mode 100644 index 000000000..5b3c7c459 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.c @@ -0,0 +1,33 @@ +/* crc32_fold.c -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#include "zbuild.h" +#include "functable.h" + +#include "crc32_fold.h" + +#include + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc) { + crc->value = CRC32_INITIAL_VALUE; + return crc->value; +} + +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len) { + crc->value = functable.crc32(crc->value, src, len); + memcpy(dst, src, len); +} + +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc) { + /* Note: while this is basically the same thing as the vanilla CRC function, we still need + * a functable entry for it so that we can generically dispatch to this function with the + * same arguments for the versions that _do_ do a folding CRC but we don't want a copy. The + * init_crc is an unused argument in this context */ + Z_UNUSED(init_crc); + crc->value = functable.crc32(crc->value, src, len); +} + +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc) { + return crc->value; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.h b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.h new file mode 100644 index 000000000..0d2ff6696 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/crc32_fold.h @@ -0,0 +1,21 @@ +/* crc32_fold.h -- crc32 folding interface + * Copyright (C) 2021 Nathan Moinvaziri + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef CRC32_FOLD_H_ +#define CRC32_FOLD_H_ + +#define CRC32_FOLD_BUFFER_SIZE (16 * 4) +/* sizeof(__m128i) * (4 folds) */ + +typedef struct crc32_fold_s { + uint8_t fold[CRC32_FOLD_BUFFER_SIZE]; + uint32_t value; +} crc32_fold; + +Z_INTERNAL uint32_t crc32_fold_reset_c(crc32_fold *crc); +Z_INTERNAL void crc32_fold_copy_c(crc32_fold *crc, uint8_t *dst, const uint8_t *src, size_t len); +Z_INTERNAL void crc32_fold_c(crc32_fold *crc, const uint8_t *src, size_t len, uint32_t init_crc); +Z_INTERNAL uint32_t crc32_fold_final_c(crc32_fold *crc); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate.c new file mode 100644 index 000000000..3ea92a82d --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate.c @@ -0,0 +1,1427 @@ +/* deflate.c -- compress data using the deflation algorithm + * Copyright (C) 1995-2022 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* + * ALGORITHM + * + * The "deflation" process depends on being able to identify portions + * of the input text which are identical to earlier input (within a + * sliding window trailing behind the input currently being processed). + * + * The most straightforward technique turns out to be the fastest for + * most input files: try all possible matches and select the longest. + * The key feature of this algorithm is that insertions into the string + * dictionary are very simple and thus fast, and deletions are avoided + * completely. Insertions are performed at each input character, whereas + * string matches are performed only when the previous match ends. So it + * is preferable to spend more time in matches to allow very fast string + * insertions and avoid deletions. The matching algorithm for small + * strings is inspired from that of Rabin & Karp. A brute force approach + * is used to find longer strings when a small match has been found. + * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze + * (by Leonid Broukhis). + * A previous version of this file used a more sophisticated algorithm + * (by Fiala and Greene) which is guaranteed to run in linear amortized + * time, but has a larger average cost, uses more memory and is patented. + * However the F&G algorithm may be faster for some highly redundant + * files if the parameter max_chain_length (described below) is too large. + * + * ACKNOWLEDGEMENTS + * + * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and + * I found it in 'freeze' written by Leonid Broukhis. + * Thanks to many people for bug reports and testing. + * + * REFERENCES + * + * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". + * Available in https://tools.ietf.org/html/rfc1951 + * + * A description of the Rabin and Karp algorithm is given in the book + * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. + * + * Fiala,E.R., and Greene,D.H. + * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 + * + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* Avoid conflicts with zlib.h macros */ +#ifdef ZLIB_COMPAT +# undef deflateInit +# undef deflateInit2 +#endif + +const char PREFIX(deflate_copyright)[] = " deflate 1.2.13 Copyright 1995-2022 Jean-loup Gailly and Mark Adler "; +/* + If you use the zlib library in a product, an acknowledgment is welcome + in the documentation of your product. If for some reason you cannot + include such an acknowledgment, I would appreciate that you keep this + copyright string in the executable of your product. + */ + +/* =========================================================================== + * Architecture-specific hooks. + */ +#ifdef S390_DFLTCC_DEFLATE +# include "arch/s390/dfltcc_deflate.h" +#else +/* Memory management for the deflate state. Useful for allocating arch-specific extension blocks. */ +# define ZALLOC_DEFLATE_STATE(strm) ((deflate_state *)ZALLOC(strm, 1, sizeof(deflate_state))) +# define ZFREE_STATE(strm, addr) ZFREE(strm, addr) +# define ZCOPY_DEFLATE_STATE(dst, src) memcpy(dst, src, sizeof(deflate_state)) +/* Memory management for the window. Useful for allocation the aligned window. */ +# define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size) +# define TRY_FREE_WINDOW(strm, addr) TRY_FREE(strm, addr) +/* Invoked at the beginning of deflateSetDictionary(). Useful for checking arch-specific window data. */ +# define DEFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the beginning of deflateGetDictionary(). Useful for adjusting arch-specific window data. */ +# define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0) +/* Invoked at the end of deflateResetKeep(). Useful for initializing arch-specific extension blocks. */ +# define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0) +/* Invoked at the beginning of deflateParams(). Useful for updating arch-specific compression parameters. */ +# define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0) +/* Returns whether the last deflate(flush) operation did everything it's supposed to do. */ +# define DEFLATE_DONE(strm, flush) 1 +/* Adjusts the upper bound on compressed data length based on compression parameters and uncompressed data length. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0) +/* Returns whether an optimistic upper bound on compressed data length should *not* be used. + * Useful when arch-specific deflation code behaves differently than regular zlib-ng algorithms. */ +# define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0 +/* Invoked for each deflate() call. Useful for plugging arch-specific deflation code. */ +# define DEFLATE_HOOK(strm, flush, bstate) 0 +/* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific deflation code already does that. */ +# define DEFLATE_NEED_CHECKSUM(strm) 1 +/* Returns whether reproducibility parameter can be set to a given value. */ +# define DEFLATE_CAN_SET_REPRODUCIBLE(strm, reproducible) 1 +#endif + +/* =========================================================================== + * Function prototypes. + */ +static int deflateStateCheck (PREFIX3(stream) *strm); +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush); +Z_INTERNAL block_state deflate_fast (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_quick (deflate_state *s, int flush); +#ifndef NO_MEDIUM_STRATEGY +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush); +#endif +Z_INTERNAL block_state deflate_slow (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_rle (deflate_state *s, int flush); +Z_INTERNAL block_state deflate_huff (deflate_state *s, int flush); +static void lm_set_level (deflate_state *s, int level); +static void lm_init (deflate_state *s); +Z_INTERNAL unsigned read_buf (PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +extern uint32_t update_hash_roll (deflate_state *const s, uint32_t h, uint32_t val); +extern void insert_string_roll (deflate_state *const s, uint32_t str, uint32_t count); +extern Pos quick_insert_string_roll(deflate_state *const s, uint32_t str); + +/* =========================================================================== + * Local data + */ + +/* Values for max_lazy_match, good_match and max_chain_length, depending on + * the desired pack level (0..9). The values given below have been tuned to + * exclude worst case performance for pathological files. Better values may be + * found for specific files. + */ +typedef struct config_s { + uint16_t good_length; /* reduce lazy search above this match length */ + uint16_t max_lazy; /* do not perform lazy search above this match length */ + uint16_t nice_length; /* quit search above this match length */ + uint16_t max_chain; + compress_func func; +} config; + +static const config configuration_table[10] = { +/* good lazy nice chain */ +/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ + +#ifdef NO_QUICK_STRATEGY +/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +/* 2 */ {4, 5, 16, 8, deflate_fast}, +#else +/* 1 */ {0, 0, 0, 0, deflate_quick}, +/* 2 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ +#endif + +#ifdef NO_MEDIUM_STRATEGY +/* 3 */ {4, 6, 32, 32, deflate_fast}, +/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_slow}, +/* 6 */ {8, 16, 128, 128, deflate_slow}, +#else +/* 3 */ {4, 6, 16, 6, deflate_medium}, +/* 4 */ {4, 12, 32, 24, deflate_medium}, /* lazy matches */ +/* 5 */ {8, 16, 32, 32, deflate_medium}, +/* 6 */ {8, 16, 128, 128, deflate_medium}, +#endif + +/* 7 */ {8, 32, 128, 256, deflate_slow}, +/* 8 */ {32, 128, 258, 1024, deflate_slow}, +/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ + +/* Note: the deflate() code requires max_lazy >= STD_MIN_MATCH and max_chain >= 4 + * For deflate_fast() (levels <= 3) good is ignored and lazy has a different + * meaning. + */ + +/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ +#define RANK(f) (((f) * 2) - ((f) > 4 ? 9 : 0)) + + +/* =========================================================================== + * Initialize the hash table. prev[] will be initialized on the fly. + */ +#define CLEAR_HASH(s) do { \ + memset((unsigned char *)s->head, 0, HASH_SIZE * sizeof(*s->head)); \ + } while (0) + +/* ========================================================================= */ +/* This function is hidden in ZLIB_COMPAT builds. */ +int32_t ZNG_CONDEXPORT PREFIX(deflateInit2)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy) { + /* Todo: ignore strm->next_in if we use it as window */ + uint32_t window_padding = 0; + deflate_state *s; + int wrap = 1; + + if (strm == NULL) + return Z_STREAM_ERROR; + + strm->msg = NULL; + if (strm->zalloc == NULL) { + strm->zalloc = PREFIX(zcalloc); + strm->opaque = NULL; + } + if (strm->zfree == NULL) + strm->zfree = PREFIX(zcfree); + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + + if (windowBits < 0) { /* suppress zlib wrapper */ + wrap = 0; + if (windowBits < -MAX_WBITS) + return Z_STREAM_ERROR; + windowBits = -windowBits; +#ifdef GZIP + } else if (windowBits > MAX_WBITS) { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; +#endif + } + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || windowBits < MIN_WBITS || + windowBits > MAX_WBITS || level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED || + (windowBits == 8 && wrap != 1)) { + return Z_STREAM_ERROR; + } + if (windowBits == 8) + windowBits = 9; /* until 256-byte window bug fixed */ + + s = ZALLOC_DEFLATE_STATE(strm); + if (s == NULL) + return Z_MEM_ERROR; + strm->state = (struct internal_state *)s; + s->strm = strm; + s->status = INIT_STATE; /* to pass state test in deflateReset() */ + + s->wrap = wrap; + s->gzhead = NULL; + s->w_bits = (unsigned int)windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + s->window = (unsigned char *) ZALLOC_WINDOW(strm, s->w_size + window_padding, 2*sizeof(unsigned char)); + s->prev = (Pos *) ZALLOC(strm, s->w_size, sizeof(Pos)); + memset(s->prev, 0, s->w_size * sizeof(Pos)); + s->head = (Pos *) ZALLOC(strm, HASH_SIZE, sizeof(Pos)); + + s->high_water = 0; /* nothing written to s->window yet */ + + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + + /* We overlay pending_buf and sym_buf. This works since the average size + * for length/distance pairs over any compressed block is assured to be 31 + * bits or less. + * + * Analysis: The longest fixed codes are a length code of 8 bits plus 5 + * extra bits, for lengths 131 to 257. The longest fixed distance codes are + * 5 bits plus 13 extra bits, for distances 16385 to 32768. The longest + * possible fixed-codes length/distance pair is then 31 bits total. + * + * sym_buf starts one-fourth of the way into pending_buf. So there are + * three bytes in sym_buf for every four bytes in pending_buf. Each symbol + * in sym_buf is three bytes -- two for the distance and one for the + * literal/length. As each symbol is consumed, the pointer to the next + * sym_buf value to read moves forward three bytes. From that symbol, up to + * 31 bits are written to pending_buf. The closest the written pending_buf + * bits gets to the next sym_buf symbol to read is just before the last + * code is written. At that time, 31*(n-2) bits have been written, just + * after 24*(n-2) bits have been consumed from sym_buf. sym_buf starts at + * 8*n bits into pending_buf. (Note that the symbol buffer fills when n-1 + * symbols are written.) The closest the writing gets to what is unread is + * then n+14 bits. Here n is lit_bufsize, which is 16384 by default, and + * can range from 128 to 32768. + * + * Therefore, at a minimum, there are 142 bits of space between what is + * written and what is read in the overlain buffers, so the symbols cannot + * be overwritten by the compressed data. That space is actually 139 bits, + * due to the three-bit fixed-code block header. + * + * That covers the case where either Z_FIXED is specified, forcing fixed + * codes, or when the use of fixed codes is chosen, because that choice + * results in a smaller compressed block than dynamic codes. That latter + * condition then assures that the above analysis also covers all dynamic + * blocks. A dynamic-code block will only be chosen to be emitted if it has + * fewer bits than a fixed-code block would for the same set of symbols. + * Therefore its average symbol length is assured to be less than 31. So + * the compressed data for a dynamic block also cannot overwrite the + * symbols from which it is being constructed. + */ + + s->pending_buf = (unsigned char *) ZALLOC(strm, s->lit_bufsize, 4); + s->pending_buf_size = s->lit_bufsize * 4; + + if (s->window == NULL || s->prev == NULL || s->head == NULL || s->pending_buf == NULL) { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + PREFIX(deflateEnd)(strm); + return Z_MEM_ERROR; + } + s->sym_buf = s->pending_buf + s->lit_bufsize; + s->sym_end = (s->lit_bufsize - 1) * 3; + /* We avoid equality with lit_bufsize*3 because of wraparound at 64K + * on 16 bit machines and because stored blocks are restricted to + * 64K-1 bytes. + */ + + s->level = level; + s->strategy = strategy; + s->block_open = 0; + s->reproducible = 0; + + return PREFIX(deflateReset)(strm); +} + +#ifndef ZLIB_COMPAT +int32_t Z_EXPORT PREFIX(deflateInit)(PREFIX3(stream) *strm, int32_t level) { + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} +#endif + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit_)(PREFIX3(stream) *strm, int32_t level, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); +} + +/* Function used by zlib.h and zlib-ng version 2.0 macros */ +int32_t Z_EXPORT PREFIX(deflateInit2_)(PREFIX3(stream) *strm, int32_t level, int32_t method, int32_t windowBits, + int32_t memLevel, int32_t strategy, const char *version, int32_t stream_size) { + if (CHECK_VER_STSIZE(version, stream_size)) + return Z_VERSION_ERROR; + return PREFIX(deflateInit2)(strm, level, method, windowBits, memLevel, strategy); +} + +/* ========================================================================= + * Check for a valid deflate stream state. Return 0 if ok, 1 if not. + */ +static int deflateStateCheck (PREFIX3(stream) *strm) { + deflate_state *s; + if (strm == NULL || strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + return 1; + s = strm->state; + if (s == NULL || s->strm != strm || (s->status != INIT_STATE && +#ifdef GZIP + s->status != GZIP_STATE && + s->status != EXTRA_STATE && + s->status != NAME_STATE && + s->status != COMMENT_STATE && + s->status != HCRC_STATE && +#endif + s->status != BUSY_STATE && + s->status != FINISH_STATE)) + return 1; + return 0; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetDictionary)(PREFIX3(stream) *strm, const uint8_t *dictionary, uint32_t dictLength) { + deflate_state *s; + unsigned int str, n; + int wrap; + uint32_t avail; + const unsigned char *next; + + if (deflateStateCheck(strm) || dictionary == NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; + + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = functable.adler32(strm->adler, dictionary, dictLength); + DEFLATE_SET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) { + if (wrap == 0) { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } + + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const unsigned char *)dictionary; + PREFIX(fill_window)(s); + while (s->lookahead >= STD_MIN_MATCH) { + str = s->strstart; + n = s->lookahead - (STD_MIN_MATCH - 1); + s->insert_string(s, str, n); + s->strstart = str + n; + s->lookahead = STD_MIN_MATCH - 1; + PREFIX(fill_window)(s); + } + s->strstart += s->lookahead; + s->block_start = (int)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->prev_length = 0; + s->match_available = 0; + strm->next_in = (z_const unsigned char *)next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateGetDictionary)(PREFIX3(stream) *strm, uint8_t *dictionary, uint32_t *dictLength) { + deflate_state *s; + unsigned int len; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + DEFLATE_GET_DICTIONARY_HOOK(strm, dictionary, dictLength); /* hook for IBM Z DFLTCC */ + s = strm->state; + len = s->strstart + s->lookahead; + if (len > s->w_size) + len = s->w_size; + if (dictionary != NULL && len) + memcpy(dictionary, s->window + s->strstart + s->lookahead - len, len); + if (dictLength != NULL) + *dictLength = len; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateResetKeep)(PREFIX3(stream) *strm) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + strm->total_in = strm->total_out = 0; + strm->msg = NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; + + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; + + if (s->wrap < 0) + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + + s->status = +#ifdef GZIP + s->wrap == 2 ? GZIP_STATE : +#endif + INIT_STATE; + +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_reset(&s->crc_fold); + } else +#endif + strm->adler = ADLER32_INITIAL_VALUE; + s->last_flush = -2; + + zng_tr_init(s); + + DEFLATE_RESET_KEEP_HOOK(strm); /* hook for IBM Z DFLTCC */ + + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateReset)(PREFIX3(stream) *strm) { + int ret; + + ret = PREFIX(deflateResetKeep)(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateSetHeader)(PREFIX3(stream) *strm, PREFIX(gz_headerp) head) { + if (deflateStateCheck(strm) || strm->state->wrap != 2) + return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePending)(PREFIX3(stream) *strm, uint32_t *pending, int32_t *bits) { + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + if (pending != NULL) + *pending = strm->state->pending; + if (bits != NULL) + *bits = strm->state->bi_valid; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflatePrime)(PREFIX3(stream) *strm, int32_t bits, int32_t value) { + deflate_state *s; + uint64_t value64 = (uint64_t)value; + int32_t put; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + if (bits < 0 || bits > BIT_BUF_SIZE || bits > (int32_t)(sizeof(value) << 3) || + s->sym_buf < s->pending_out + ((BIT_BUF_SIZE + 7) >> 3)) + return Z_BUF_ERROR; + do { + put = BIT_BUF_SIZE - s->bi_valid; + put = MIN(put, bits); + + if (s->bi_valid == 0) + s->bi_buf = value64; + else + s->bi_buf |= (value64 & ((UINT64_C(1) << put) - 1)) << s->bi_valid; + s->bi_valid += put; + zng_tr_flush_bits(s); + value64 >>= put; + bits -= put; + } while (bits); + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateParams)(PREFIX3(stream) *strm, int32_t level, int32_t strategy) { + deflate_state *s; + compress_func func; + int hook_flush = Z_NO_FLUSH; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + if (level == Z_DEFAULT_COMPRESSION) + level = 6; + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) + return Z_STREAM_ERROR; + DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush); /* hook for IBM Z DFLTCC */ + func = configuration_table[s->level].func; + + if (((strategy != s->strategy || func != configuration_table[level].func) && s->last_flush != -2) + || hook_flush != Z_NO_FLUSH) { + /* Flush the last buffer. Use Z_BLOCK mode, unless the hook requests a "stronger" one. */ + int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK; + int err = PREFIX(deflate)(strm, flush); + if (err == Z_STREAM_ERROR) + return err; + if (strm->avail_in || ((int)s->strstart - s->block_start) + s->lookahead || !DEFLATE_DONE(strm, flush)) + return Z_BUF_ERROR; + } + if (s->level != level) { + if (s->level == 0 && s->matches != 0) { + if (s->matches == 1) { + functable.slide_hash(s); + } else { + CLEAR_HASH(s); + } + s->matches = 0; + } + + lm_set_level(s, level); + } + s->strategy = strategy; + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateTune)(PREFIX3(stream) *strm, int32_t good_length, int32_t max_lazy, int32_t nice_length, int32_t max_chain) { + deflate_state *s; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + s->good_match = (unsigned int)good_length; + s->max_lazy_match = (unsigned int)max_lazy; + s->nice_match = nice_length; + s->max_chain_length = (unsigned int)max_chain; + return Z_OK; +} + +/* ========================================================================= + * For the default windowBits of 15 and memLevel of 8, this function returns + * a close to exact, as well as small, upper bound on the compressed size. + * They are coded as constants here for a reason--if the #define's are + * changed, then this function needs to be changed as well. The return + * value for 15 and 8 only works for those exact settings. + * + * For any setting other than those defaults for windowBits and memLevel, + * the value returned is a conservative worst case for the maximum expansion + * resulting from using fixed blocks instead of stored blocks, which deflate + * can emit on compressed data for some combinations of the parameters. + * + * This function could be more sophisticated to provide closer upper bounds for + * every combination of windowBits and memLevel. But even the conservative + * upper bound of about 14% expansion does not seem onerous for output buffer + * allocation. + */ +unsigned long Z_EXPORT PREFIX(deflateBound)(PREFIX3(stream) *strm, unsigned long sourceLen) { + deflate_state *s; + unsigned long complen, wraplen; + + /* conservative upper bound for compressed data */ + complen = sourceLen + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen); /* hook for IBM Z DFLTCC */ + + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (deflateStateCheck(strm)) + return complen + 6; + + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = ZLIB_WRAPLEN + (s->strstart ? 4 : 0); + break; +#ifdef GZIP + case 2: /* gzip wrapper */ + wraplen = GZIP_WRAPLEN; + if (s->gzhead != NULL) { /* user-supplied gzip header */ + unsigned char *str; + if (s->gzhead->extra != NULL) { + wraplen += 2 + s->gzhead->extra_len; + } + str = s->gzhead->name; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + str = s->gzhead->comment; + if (str != NULL) { + do { + wraplen++; + } while (*str++); + } + if (s->gzhead->hcrc) + wraplen += 2; + } + break; +#endif + default: /* for compiler happiness */ + wraplen = ZLIB_WRAPLEN; + } + + /* if not default parameters, return conservative bound */ + if (DEFLATE_NEED_CONSERVATIVE_BOUND(strm) || /* hook for IBM Z DFLTCC */ + s->w_bits != MAX_WBITS || HASH_BITS < 15) { + if (s->level == 0) { + /* upper bound for stored blocks with length 127 (memLevel == 1) -- + ~4% overhead plus a small constant */ + complen = sourceLen + (sourceLen >> 5) + (sourceLen >> 7) + (sourceLen >> 11) + 7; + } + + return complen + wraplen; + } + +#ifndef NO_QUICK_STRATEGY + return sourceLen /* The source size itself */ + + (sourceLen == 0 ? 1 : 0) /* Always at least one byte for any input */ + + (sourceLen < 9 ? 1 : 0) /* One extra byte for lengths less than 9 */ + + DEFLATE_QUICK_OVERHEAD(sourceLen) /* Source encoding overhead, padded to next full byte */ + + DEFLATE_BLOCK_OVERHEAD /* Deflate block overhead bytes */ + + wraplen; /* none, zlib or gzip wrapper */ +#else + return sourceLen + (sourceLen >> 4) + 7 + wraplen; +#endif +} + +/* ========================================================================= + * Flush as much pending output as possible. All deflate() output, except for + * some deflate_stored() output, goes through this function so some + * applications may wish to modify it to avoid allocating a large + * strm->next_out buffer and copying into it. (See also read_buf()). + */ +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm) { + uint32_t len; + deflate_state *s = strm->state; + + zng_tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) + len = strm->avail_out; + if (len == 0) + return; + + Tracev((stderr, "[FLUSH]")); + memcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) + s->pending_out = s->pending_buf; +} + +/* =========================================================================== + * Update the header CRC with the bytes s->pending_buf[beg..s->pending - 1]. + */ +#define HCRC_UPDATE(beg) \ + do { \ + if (s->gzhead->hcrc && s->pending > (beg)) \ + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf + (beg), s->pending - (beg)); \ + } while (0) + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflate)(PREFIX3(stream) *strm, int32_t flush) { + int32_t old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; + + if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) + return Z_STREAM_ERROR; + s = strm->state; + + if (strm->next_out == NULL || (strm->avail_in != 0 && strm->next_in == NULL) + || (s->status == FINISH_STATE && flush != Z_FINISH)) { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + old_flush = s->last_flush; + s->last_flush = flush; + + /* Flush as much pending output as possible */ + if (s->pending != 0) { + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + /* Since avail_out is 0, deflate will be called again with + * more output space, but possibly with both pending and + * avail_in equal to zero. There won't be anything to do, + * but this is not an error situation so make sure we + * return OK instead of BUF_ERROR at next call of deflate: + */ + s->last_flush = -1; + return Z_OK; + } + + /* Make sure there is something to do and avoid duplicate consecutive + * flushes. For repeated and useless calls with Z_FINISH, we keep + * returning Z_STREAM_END instead of Z_BUF_ERROR. + */ + } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && flush != Z_FINISH) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) { + ERR_RETURN(strm, Z_BUF_ERROR); + } + + /* Write the header */ + if (s->status == INIT_STATE && s->wrap == 0) + s->status = BUSY_STATE; + if (s->status == INIT_STATE) { + /* zlib header */ + unsigned int header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; + unsigned int level_flags; + + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) + header |= PRESET_DICT; + header += 31 - (header % 31); + + put_short_msb(s, (uint16_t)header); + + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) + put_uint32_msb(s, strm->adler); + strm->adler = ADLER32_INITIAL_VALUE; + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#ifdef GZIP + if (s->status == GZIP_STATE) { + /* gzip header */ + functable.crc32_fold_reset(&s->crc_fold); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == NULL) { + put_uint32(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : + (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } else { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == NULL ? 0 : 4) + + (s->gzhead->name == NULL ? 0 : 8) + + (s->gzhead->comment == NULL ? 0 : 16) + ); + put_uint32(s, s->gzhead->time); + put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != NULL) + put_short(s, (uint16_t)s->gzhead->extra_len); + if (s->gzhead->hcrc) + strm->adler = PREFIX(crc32)(strm->adler, s->pending_buf, s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + if (s->status == EXTRA_STATE) { + if (s->gzhead->extra != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + uint32_t left = (s->gzhead->extra_len & 0xffff) - s->gzindex; + + while (s->pending + left > s->pending_buf_size) { + uint32_t copy = s->pending_buf_size - s->pending; + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, copy); + s->pending = s->pending_buf_size; + HCRC_UPDATE(beg); + s->gzindex += copy; + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + left -= copy; + } + memcpy(s->pending_buf + s->pending, s->gzhead->extra + s->gzindex, left); + s->pending += left; + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) { + if (s->gzhead->name != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + s->gzindex = 0; + } + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) { + if (s->gzhead->comment != NULL) { + uint32_t beg = s->pending; /* start of bytes to update crc */ + unsigned char val; + + do { + if (s->pending == s->pending_buf_size) { + HCRC_UPDATE(beg); + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + beg = 0; + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + HCRC_UPDATE(beg); + } + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) { + if (s->gzhead->hcrc) { + if (s->pending + 2 > s->pending_buf_size) { + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } + put_short(s, (uint16_t)strm->adler); + functable.crc32_fold_reset(&s->crc_fold); + } + s->status = BUSY_STATE; + + /* Compression must start with an empty pending buffer */ + PREFIX(flush_pending)(strm); + if (s->pending != 0) { + s->last_flush = -1; + return Z_OK; + } + } +#endif + + /* Start a new block or continue the current one. + */ + if (strm->avail_in != 0 || s->lookahead != 0 || (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { + block_state bstate; + + bstate = DEFLATE_HOOK(strm, flush, &bstate) ? bstate : /* hook for IBM Z DFLTCC */ + s->level == 0 ? deflate_stored(s, flush) : + s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : + s->strategy == Z_RLE ? deflate_rle(s, flush) : + (*(configuration_table[s->level].func))(s, flush); + + if (bstate == finish_started || bstate == finish_done) { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) { + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + * of deflate should use the same flush parameter to make sure + * that the flush is complete. So we don't have to output an + * empty block here, this will be done at next call. This also + * ensures that for a very small output buffer, we emit at most + * one empty block. + */ + } + if (bstate == block_done) { + if (flush == Z_PARTIAL_FLUSH) { + zng_tr_align(s); + } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ + zng_tr_stored_block(s, (char*)0, 0L, 0); + /* For a full flush, this empty block will be recognized + * as a special marker by inflate_sync(). + */ + if (flush == Z_FULL_FLUSH) { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) { + s->strstart = 0; + s->block_start = 0; + s->insert = 0; + } + } + } + PREFIX(flush_pending)(strm); + if (strm->avail_out == 0) { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + + if (flush != Z_FINISH) + return Z_OK; + + /* Write the trailer */ +#ifdef GZIP + if (s->wrap == 2) { + strm->adler = functable.crc32_fold_final(&s->crc_fold); + + put_uint32(s, strm->adler); + put_uint32(s, (uint32_t)strm->total_in); + } else +#endif + { + if (s->wrap == 1) + put_uint32_msb(s, strm->adler); + } + PREFIX(flush_pending)(strm); + /* If avail_out is zero, the application will call deflate again + * to flush the rest. + */ + if (s->wrap > 0) + s->wrap = -s->wrap; /* write the trailer only once! */ + if (s->pending == 0) { + Assert(s->bi_valid == 0, "bi_buf not flushed"); + return Z_STREAM_END; + } + return Z_OK; +} + +/* ========================================================================= */ +int32_t Z_EXPORT PREFIX(deflateEnd)(PREFIX3(stream) *strm) { + int32_t status; + + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + + status = strm->state->status; + + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE_WINDOW(strm, strm->state->window); + + ZFREE_STATE(strm, strm->state); + strm->state = NULL; + + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; +} + +/* ========================================================================= + * Copy the source state to the destination state. + */ +int32_t Z_EXPORT PREFIX(deflateCopy)(PREFIX3(stream) *dest, PREFIX3(stream) *source) { + deflate_state *ds; + deflate_state *ss; + uint32_t window_padding = 0; + + if (deflateStateCheck(source) || dest == NULL) + return Z_STREAM_ERROR; + + ss = source->state; + + memcpy((void *)dest, (void *)source, sizeof(PREFIX3(stream))); + + ds = ZALLOC_DEFLATE_STATE(dest); + if (ds == NULL) + return Z_MEM_ERROR; + dest->state = (struct internal_state *) ds; + ZCOPY_DEFLATE_STATE(ds, ss); + ds->strm = dest; + +#ifdef X86_PCLMULQDQ_CRC + window_padding = 8; +#endif + + ds->window = (unsigned char *) ZALLOC_WINDOW(dest, ds->w_size + window_padding, 2*sizeof(unsigned char)); + ds->prev = (Pos *) ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Pos *) ZALLOC(dest, HASH_SIZE, sizeof(Pos)); + ds->pending_buf = (unsigned char *) ZALLOC(dest, ds->lit_bufsize, 4); + + if (ds->window == NULL || ds->prev == NULL || ds->head == NULL || ds->pending_buf == NULL) { + PREFIX(deflateEnd)(dest); + return Z_MEM_ERROR; + } + + memcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(unsigned char)); + memcpy((void *)ds->prev, (void *)ss->prev, ds->w_size * sizeof(Pos)); + memcpy((void *)ds->head, (void *)ss->head, HASH_SIZE * sizeof(Pos)); + memcpy(ds->pending_buf, ss->pending_buf, ds->pending_buf_size); + + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->sym_buf = ds->pending_buf + ds->lit_bufsize; + + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; + + return Z_OK; +} + +/* =========================================================================== + * Read a new buffer from the current input stream, update the adler32 + * and total number of bytes read. All deflate() input goes through + * this function so some applications may wish to modify it to avoid + * allocating a large strm->next_in buffer and copying from it. + * (See also flush_pending()). + */ +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size) { + uint32_t len = strm->avail_in; + + len = MIN(len, size); + if (len == 0) + return 0; + + strm->avail_in -= len; + + if (!DEFLATE_NEED_CHECKSUM(strm)) { + memcpy(buf, strm->next_in, len); +#ifdef GZIP + } else if (strm->state->wrap == 2) { + functable.crc32_fold_copy(&strm->state->crc_fold, buf, strm->next_in, len); +#endif + } else { + if (strm->state->wrap == 1) + strm->adler = functable.adler32_fold_copy(strm->adler, buf, strm->next_in, len); + else + memcpy(buf, strm->next_in, len); + } + strm->next_in += len; + strm->total_in += len; + + return len; +} + +/* =========================================================================== + * Set longest match variables based on level configuration + */ +static void lm_set_level(deflate_state *s, int level) { + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + + /* Use rolling hash for deflate_slow algorithm with level 9. It allows us to + * properly lookup different hash chains to speed up longest_match search. Since hashing + * method changes depending on the level we cannot put this into functable. */ + if (s->max_chain_length > 1024) { + s->update_hash = &update_hash_roll; + s->insert_string = &insert_string_roll; + s->quick_insert_string = &quick_insert_string_roll; + } else { + s->update_hash = functable.update_hash; + s->insert_string = functable.insert_string; + s->quick_insert_string = functable.quick_insert_string; + } + + s->level = level; +} + +/* =========================================================================== + * Initialize the "longest match" routines for a new zlib stream + */ +static void lm_init(deflate_state *s) { + s->window_size = 2 * s->w_size; + + CLEAR_HASH(s); + + /* Set the default configuration parameters: + */ + lm_set_level(s, s->level); + + s->strstart = 0; + s->block_start = 0; + s->lookahead = 0; + s->insert = 0; + s->prev_length = 0; + s->match_available = 0; + s->match_start = 0; + s->ins_h = 0; +} + +/* =========================================================================== + * Fill the window when the lookahead becomes insufficient. + * Updates strstart and lookahead. + * + * IN assertion: lookahead < MIN_LOOKAHEAD + * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD + * At least one byte has been read, or avail_in == 0; reads are + * performed for at least two bytes (required for the zip translate_eol + * option -- not supported here). + */ + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s) { + unsigned n; + unsigned int more; /* Amount of free space at the end of the window. */ + unsigned int wsize = s->w_size; + + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + + do { + more = s->window_size - s->lookahead - s->strstart; + + /* If the window is almost full and there is insufficient lookahead, + * move the upper half to the lower one to make room in the upper half. + */ + if (s->strstart >= wsize+MAX_DIST(s)) { + memcpy(s->window, s->window+wsize, (unsigned)wsize); + if (s->match_start >= wsize) { + s->match_start -= wsize; + } else { + s->match_start = 0; + s->prev_length = 0; + } + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (int)wsize; + if (s->insert > s->strstart) + s->insert = s->strstart; + functable.slide_hash(s); + more += wsize; + } + if (s->strm->avail_in == 0) + break; + + /* If there was no sliding: + * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && + * more == window_size - lookahead - strstart + * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) + * => more >= window_size - 2*WSIZE + 2 + * In the BIG_MEM or MMAP case (not yet supported), + * window_size == input_size + MIN_LOOKAHEAD && + * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. + * Otherwise, window_size == 2*WSIZE so more >= 2. + * If there was sliding, more >= WSIZE. So in all cases, more >= 2. + */ + Assert(more >= 2, "more < 2"); + + n = PREFIX(read_buf)(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; + + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= STD_MIN_MATCH) { + unsigned int str = s->strstart - s->insert; + if (UNLIKELY(s->max_chain_length > 1024)) { + s->ins_h = s->update_hash(s, s->window[str], s->window[str+1]); + } else if (str >= 1) { + s->quick_insert_string(s, str + 2 - STD_MIN_MATCH); + } + unsigned int count; + if (UNLIKELY(s->lookahead == 1)) { + count = s->insert - 1; + } else { + count = s->insert; + } + if (count > 0) { + s->insert_string(s, str, count); + s->insert -= count; + } + } + /* If the whole input has less than STD_MIN_MATCH bytes, ins_h is garbage, + * but this is not important since only literal bytes will be emitted. + */ + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + + /* If the WIN_INIT bytes after the end of the current data have never been + * written, then zero those bytes in order to avoid memory check reports of + * the use of uninitialized (or uninitialised as Julian writes) bytes by + * the longest match routines. Update the high water mark for the next + * time through here. WIN_INIT is set to STD_MAX_MATCH since the longest match + * routines allow scanning to strstart + STD_MAX_MATCH, ignoring lookahead. + */ + if (s->high_water < s->window_size) { + unsigned int curr = s->strstart + s->lookahead; + unsigned int init; + + if (s->high_water < curr) { + /* Previous high water mark below current data -- zero WIN_INIT + * bytes or up to end of window, whichever is less. + */ + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + memset(s->window + curr, 0, init); + s->high_water = curr + init; + } else if (s->high_water < curr + WIN_INIT) { + /* High water mark at or above current data, but below current data + * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up + * to end of window, whichever is less. + */ + init = curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + memset(s->window + s->high_water, 0, init); + s->high_water += init; + } + } + + Assert((unsigned long)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); +} + +#ifndef ZLIB_COMPAT +/* ========================================================================= + * Checks whether buffer size is sufficient and whether this parameter is a duplicate. + */ +static int32_t deflateSetParamPre(zng_deflate_param_value **out, size_t min_size, zng_deflate_param_value *param) { + int32_t buf_error = param->size < min_size; + + if (*out != NULL) { + (*out)->status = Z_BUF_ERROR; + buf_error = 1; + } + *out = param; + return buf_error; +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateSetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + size_t i; + deflate_state *s; + zng_deflate_param_value *new_level = NULL; + zng_deflate_param_value *new_strategy = NULL; + zng_deflate_param_value *new_reproducible = NULL; + int param_buf_error; + int version_error = 0; + int buf_error = 0; + int stream_error = 0; + int ret; + int val; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + /* Check buffer sizes and detect duplicates. */ + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + param_buf_error = deflateSetParamPre(&new_level, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_STRATEGY: + param_buf_error = deflateSetParamPre(&new_strategy, sizeof(int), ¶ms[i]); + break; + case Z_DEFLATE_REPRODUCIBLE: + param_buf_error = deflateSetParamPre(&new_reproducible, sizeof(int), ¶ms[i]); + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + param_buf_error = 0; + break; + } + if (param_buf_error) { + params[i].status = Z_BUF_ERROR; + buf_error = 1; + } + } + /* Exit early if small buffers or duplicates are detected. */ + if (buf_error) + return Z_BUF_ERROR; + + /* Apply changes, remember if there were errors. */ + if (new_level != NULL || new_strategy != NULL) { + ret = PREFIX(deflateParams)(strm, new_level == NULL ? s->level : *(int *)new_level->buf, + new_strategy == NULL ? s->strategy : *(int *)new_strategy->buf); + if (ret != Z_OK) { + if (new_level != NULL) + new_level->status = Z_STREAM_ERROR; + if (new_strategy != NULL) + new_strategy->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + if (new_reproducible != NULL) { + val = *(int *)new_reproducible->buf; + if (DEFLATE_CAN_SET_REPRODUCIBLE(strm, val)) { + s->reproducible = val; + } else { + new_reproducible->status = Z_STREAM_ERROR; + stream_error = 1; + } + } + + /* Report version errors only if there are no real errors. */ + return stream_error ? Z_STREAM_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} + +/* ========================================================================= */ +int32_t Z_EXPORT zng_deflateGetParams(zng_stream *strm, zng_deflate_param_value *params, size_t count) { + deflate_state *s; + size_t i; + int32_t buf_error = 0; + int32_t version_error = 0; + + /* Initialize the statuses. */ + for (i = 0; i < count; i++) + params[i].status = Z_OK; + + /* Check whether the stream state is consistent. */ + if (deflateStateCheck(strm)) + return Z_STREAM_ERROR; + s = strm->state; + + for (i = 0; i < count; i++) { + switch (params[i].param) { + case Z_DEFLATE_LEVEL: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->level; + break; + case Z_DEFLATE_STRATEGY: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->strategy; + break; + case Z_DEFLATE_REPRODUCIBLE: + if (params[i].size < sizeof(int)) + params[i].status = Z_BUF_ERROR; + else + *(int *)params[i].buf = s->reproducible; + break; + default: + params[i].status = Z_VERSION_ERROR; + version_error = 1; + break; + } + if (params[i].status == Z_BUF_ERROR) + buf_error = 1; + } + return buf_error ? Z_BUF_ERROR : (version_error ? Z_VERSION_ERROR : Z_OK); +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate.h b/internal-complibs/zlib-ng-2.1.1-beta2/deflate.h new file mode 100644 index 000000000..e4b971f88 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate.h @@ -0,0 +1,403 @@ +#ifndef DEFLATE_H_ +#define DEFLATE_H_ +/* deflate.h -- internal compression state + * Copyright (C) 1995-2016 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +#include "zutil.h" +#include "zendian.h" +#include "adler32_fold.h" +#include "crc32_fold.h" + +/* define NO_GZIP when compiling if you want to disable gzip header and + trailer creation by deflate(). NO_GZIP would be used to avoid linking in + the crc code when it is not needed. For shared libraries, gzip encoding + should be left enabled. */ +#ifndef NO_GZIP +# define GZIP +#endif + +/* =========================================================================== + * Internal compression state. + */ + +#define LENGTH_CODES 29 +/* number of length codes, not counting the special END_BLOCK code */ + +#define LITERALS 256 +/* number of literal bytes 0..255 */ + +#define L_CODES (LITERALS+1+LENGTH_CODES) +/* number of Literal or Length codes, including the END_BLOCK code */ + +#define D_CODES 30 +/* number of distance codes */ + +#define BL_CODES 19 +/* number of codes used to transfer the bit lengths */ + +#define HEAP_SIZE (2*L_CODES+1) +/* maximum heap size */ + +#define BIT_BUF_SIZE 64 +/* size of bit buffer in bi_buf */ + +#define END_BLOCK 256 +/* end of block literal code */ + +#define INIT_STATE 42 /* zlib header -> BUSY_STATE */ +#ifdef GZIP +# define GZIP_STATE 57 /* gzip header -> BUSY_STATE | EXTRA_STATE */ +# define EXTRA_STATE 69 /* gzip extra block -> NAME_STATE */ +# define NAME_STATE 73 /* gzip file name -> COMMENT_STATE */ +# define COMMENT_STATE 91 /* gzip comment -> HCRC_STATE */ +# define HCRC_STATE 103 /* gzip header CRC -> BUSY_STATE */ +#endif +#define BUSY_STATE 113 /* deflate -> FINISH_STATE */ +#define FINISH_STATE 666 /* stream complete */ +/* Stream status */ + +#define HASH_BITS 16u /* log2(HASH_SIZE) */ +#ifndef HASH_SIZE +# define HASH_SIZE 65536u /* number of elements in hash table */ +#endif +#define HASH_MASK (HASH_SIZE - 1u) /* HASH_SIZE-1 */ + + +/* Data structure describing a single value and its code string. */ +typedef struct ct_data_s { + union { + uint16_t freq; /* frequency count */ + uint16_t code; /* bit string */ + } fc; + union { + uint16_t dad; /* father node in Huffman tree */ + uint16_t len; /* length of bit string */ + } dl; +} ct_data; + +#define Freq fc.freq +#define Code fc.code +#define Dad dl.dad +#define Len dl.len + +typedef struct static_tree_desc_s static_tree_desc; + +typedef struct tree_desc_s { + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + const static_tree_desc *stat_desc; /* the corresponding static tree */ +} tree_desc; + +typedef uint16_t Pos; + +/* A Pos is an index in the character window. We use short instead of int to + * save space in the various tables. + */ +/* Type definitions for hash callbacks */ +typedef struct internal_state deflate_state; + +typedef uint32_t (* update_hash_cb) (deflate_state *const s, uint32_t h, uint32_t val); +typedef void (* insert_string_cb) (deflate_state *const s, uint32_t str, uint32_t count); +typedef Pos (* quick_insert_string_cb)(deflate_state *const s, uint32_t str); + +struct internal_state { + PREFIX3(stream) *strm; /* pointer back to this zlib stream */ + unsigned char *pending_buf; /* output still pending */ + unsigned char *pending_out; /* next pending byte to output to the stream */ + uint32_t pending_buf_size; /* size of pending_buf */ + uint32_t pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + uint32_t gzindex; /* where in extra, name, or comment */ + PREFIX(gz_headerp) gzhead; /* gzip header information to write */ + int status; /* as the name implies */ + int last_flush; /* value of flush param for previous deflate call */ + int reproducible; /* Whether reproducible compression results are required. */ + + int block_open; + /* Whether or not a block is currently open for the QUICK deflation scheme. + * This is set to 1 if there is an active block, or 0 if the block was just closed. + */ + + /* used by deflate.c: */ + + unsigned int w_size; /* LZ77 window size (32K by default) */ + unsigned int w_bits; /* log2(w_size) (8..16) */ + unsigned int w_mask; /* w_size - 1 */ + unsigned int lookahead; /* number of valid bytes ahead in window */ + + unsigned int high_water; + /* High water mark offset in window for initialized bytes -- bytes above + * this are set to zero in order to avoid memory check warnings when + * longest match routines access bytes past the input. This is then + * updated to the new high water mark. + */ + + unsigned int window_size; + /* Actual size of window: 2*wSize, except when the user input buffer + * is directly used as sliding window. + */ + + unsigned char *window; + /* Sliding window. Input bytes are read into the second half of the window, + * and move to the first half later to keep a dictionary of at least wSize + * bytes. With this organization, matches are limited to a distance of + * wSize-STD_MAX_MATCH bytes, but this ensures that IO is always + * performed with a length multiple of the block size. Also, it limits + * the window size to 64K, which is quite useful on MSDOS. + * To do: use the user input buffer as sliding window. + */ + + Pos *prev; + /* Link to older string with same hash index. To limit the size of this + * array to 64K, this link is maintained only for the last 32K strings. + * An index in this array is thus a window index modulo 32K. + */ + + Pos *head; /* Heads of the hash chains or 0. */ + + uint32_t ins_h; /* hash index of string to be inserted */ + + int block_start; + /* Window position at the beginning of the current output block. Gets + * negative when the window is moved backwards. + */ + + unsigned int match_length; /* length of best match */ + Pos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + unsigned int strstart; /* start of string to insert */ + unsigned int match_start; /* start of matching string */ + + unsigned int prev_length; + /* Length of the best match at previous step. Matches not greater than this + * are discarded. This is used in the lazy match evaluation. + */ + + unsigned int max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this length. + * A higher limit improves compression ratio but degrades the speed. + */ + + unsigned int max_lazy_match; + /* Attempt to find a better match only when the current match is strictly smaller + * than this value. This mechanism is used only for compression levels >= 4. + */ +# define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not + * greater than this length. This saves time but degrades compression. + * max_insert_length is used only for compression levels <= 3. + */ + + update_hash_cb update_hash; + insert_string_cb insert_string; + quick_insert_string_cb quick_insert_string; + /* Hash function callbacks that can be configured depending on the deflate + * algorithm being used */ + + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ + + unsigned int good_match; + /* Use a faster search when the previous match is longer than this */ + + int nice_match; /* Stop searching when current match exceeds this */ + + struct crc32_fold_s ALIGNED_(16) crc_fold; + + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ + struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ + + uint16_t bl_count[MAX_BITS+1]; + /* number of codes at each bit length for an optimal tree */ + + int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + * The same heap array is used to build all trees. + */ + + unsigned char depth[2*L_CODES+1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency + */ + + unsigned int lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for + * limiting lit_bufsize to 64K: + * - frequencies can be kept in 16 bit counters + * - if compression is not successful for the first block, all input + * data is still in the window so we can still emit a stored block even + * when input comes from standard input. (This can also be done for + * all blocks if lit_bufsize is not greater than 32K.) + * - if compression is not successful for a file smaller than 64K, we can + * even emit a stored file instead of a stored block (saving 5 bytes). + * This is applicable only for zip (not gzip or zlib). + * - creating new Huffman trees less frequently may not provide fast + * adaptation to changes in the input data statistics. (Take for + * example a binary file with poorly compressible code followed by + * a highly compressible string table.) Smaller buffer sizes give + * fast adaptation but have of course the overhead of transmitting + * trees more frequently. + * - I can't count above 4 + */ + + unsigned char *sym_buf; /* buffer for distances and literals/lengths */ + unsigned int sym_next; /* running index in sym_buf */ + unsigned int sym_end; /* symbol table full when sym_next reaches this */ + + unsigned long opt_len; /* bit length of current block with optimal trees */ + unsigned long static_len; /* bit length of current block with static trees */ + unsigned int matches; /* number of string matches in current block */ + unsigned int insert; /* bytes at end of window left to insert */ + + /* compressed_len and bits_sent are only used if ZLIB_DEBUG is defined */ + unsigned long compressed_len; /* total bit length of compressed file mod 2^32 */ + unsigned long bits_sent; /* bit length of compressed data sent mod 2^32 */ + + /* Reserved for future use and alignment purposes */ + char *reserved_p; + + uint64_t bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least significant bits). */ + + int32_t bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit are always zero. */ + + /* Reserved for future use and alignment purposes */ + int32_t reserved[11]; +} ALIGNED_(8); + +typedef enum { + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ +} block_state; + +/* Output a byte on the stream. + * IN assertion: there is enough room in pending_buf. + */ +#define put_byte(s, c) { \ + s->pending_buf[s->pending++] = (unsigned char)(c); \ +} + +/* =========================================================================== + * Output a short LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == BIG_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a short MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_short_msb(deflate_state *s, uint16_t w) { +#if BYTE_ORDER == LITTLE_ENDIAN + w = ZSWAP16(w); +#endif + memcpy(&s->pending_buf[s->pending], &w, sizeof(w)); + s->pending += 2; +} + +/* =========================================================================== + * Output a 32-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == BIG_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 32-bit unsigned int MSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint32_msb(deflate_state *s, uint32_t dw) { +#if BYTE_ORDER == LITTLE_ENDIAN + dw = ZSWAP32(dw); +#endif + memcpy(&s->pending_buf[s->pending], &dw, sizeof(dw)); + s->pending += 4; +} + +/* =========================================================================== + * Output a 64-bit unsigned int LSB first on the stream. + * IN assertion: there is enough room in pending_buf. + */ +static inline void put_uint64(deflate_state *s, uint64_t lld) { +#if BYTE_ORDER == BIG_ENDIAN + lld = ZSWAP64(lld); +#endif + memcpy(&s->pending_buf[s->pending], &lld, sizeof(lld)); + s->pending += 8; +} + +#define MIN_LOOKAHEAD (STD_MAX_MATCH + STD_MIN_MATCH + 1) +/* Minimum amount of lookahead, except at the end of the input file. + * See deflate.c for comments about the STD_MIN_MATCH+1. + */ + +#define MAX_DIST(s) ((s)->w_size - MIN_LOOKAHEAD) +/* In order to simplify the code, particularly on 16 bit machines, match + * distances are limited to MAX_DIST instead of WSIZE. + */ + +#define WIN_INIT STD_MAX_MATCH +/* Number of bytes after end of data in window to initialize in order to avoid + memory checker errors from longest match routines */ + + +void Z_INTERNAL PREFIX(fill_window)(deflate_state *s); +void Z_INTERNAL slide_hash_c(deflate_state *s); + + /* in trees.c */ +void Z_INTERNAL zng_tr_init(deflate_state *s); +void Z_INTERNAL zng_tr_flush_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +void Z_INTERNAL zng_tr_flush_bits(deflate_state *s); +void Z_INTERNAL zng_tr_align(deflate_state *s); +void Z_INTERNAL zng_tr_stored_block(deflate_state *s, char *buf, uint32_t stored_len, int last); +uint16_t Z_INTERNAL PREFIX(bi_reverse)(unsigned code, int len); +void Z_INTERNAL PREFIX(flush_pending)(PREFIX3(streamp) strm); +#define d_code(dist) ((dist) < 256 ? zng_dist_code[dist] : zng_dist_code[256+((dist)>>7)]) +/* Mapping from a distance to a distance code. dist is the distance - 1 and + * must not have side effects. zng_dist_code[256] and zng_dist_code[257] are never + * used. + */ + +/* Bit buffer and compress bits calculation debugging */ +#ifdef ZLIB_DEBUG +# define cmpr_bits_add(s, len) s->compressed_len += (len) +# define cmpr_bits_align(s) s->compressed_len = (s->compressed_len + 7) & ~7L +# define sent_bits_add(s, bits) s->bits_sent += (bits) +# define sent_bits_align(s) s->bits_sent = (s->bits_sent + 7) & ~7L +#else +# define cmpr_bits_add(s, len) Z_UNUSED(len) +# define cmpr_bits_align(s) +# define sent_bits_add(s, bits) Z_UNUSED(bits) +# define sent_bits_align(s) +#endif + +#endif /* DEFLATE_H_ */ diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_fast.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_fast.c new file mode 100644 index 000000000..3184aa718 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_fast.c @@ -0,0 +1,102 @@ +/* deflate_fast.c -- compress data using the fast strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Compress as much as possible from the input stream, return the current + * block state. + * This function does not perform lazy evaluation of matches and inserts + * new strings in the dictionary only for unmatched strings or for short + * matches. It is used only for the fast compression options. + */ +Z_INTERNAL block_state deflate_fast(deflate_state *s, int flush) { + Pos hash_head; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match length < WANT_MIN_MATCH + */ + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = functable.longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + } + + if (match_len >= WANT_MIN_MATCH) { + check_match(s, s->strstart, s->match_start, match_len); + + bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match_len <= s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match_len--; /* string at strstart already in table */ + s->strstart++; + + functable.insert_string(s, s->strstart, match_len); + s->strstart += match_len; + } else { + s->strstart += match_len; + functable.quick_insert_string(s, s->strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_huff.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_huff.c new file mode 100644 index 000000000..b197e24d7 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_huff.c @@ -0,0 +1,45 @@ +/* deflate_huff.c -- compress data using huffman encoding only strategy + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. + * (It will be regenerated if this run of deflate switches away from Huffman.) + */ +Z_INTERNAL block_state deflate_huff(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + + for (;;) { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) { + PREFIX(fill_window)(s); + if (s->lookahead == 0) { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } + + /* Output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_medium.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_medium.c new file mode 100644 index 000000000..47796e322 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_medium.c @@ -0,0 +1,293 @@ +/* deflate_medium.c -- The deflate_medium deflate strategy + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Arjan van de Ven + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ +#ifndef NO_MEDIUM_STRATEGY +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +struct match { + uint16_t match_start; + uint16_t match_length; + uint16_t strstart; + uint16_t orgstart; +}; + +static int emit_match(deflate_state *s, struct match match) { + int bflush = 0; + + /* matches that are not long enough we need to emit as literals */ + if (match.match_length < WANT_MIN_MATCH) { + while (match.match_length) { + bflush += zng_tr_tally_lit(s, s->window[match.strstart]); + s->lookahead--; + match.strstart++; + match.match_length--; + } + return bflush; + } + + check_match(s, match.strstart, match.match_start, match.match_length); + + bflush += zng_tr_tally_dist(s, match.strstart - match.match_start, match.match_length - STD_MIN_MATCH); + + s->lookahead -= match.match_length; + return bflush; +} + +static void insert_match(deflate_state *s, struct match match) { + if (UNLIKELY(s->lookahead <= (unsigned int)(match.match_length + WANT_MIN_MATCH))) + return; + + /* matches that are not long enough we need to emit as literals */ + if (LIKELY(match.match_length < WANT_MIN_MATCH)) { + match.strstart++; + match.match_length--; + if (UNLIKELY(match.match_length > 0)) { + if (match.strstart >= match.orgstart) { + if (match.strstart + match.match_length - 1 >= match.orgstart) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + match.strstart += match.match_length; + match.match_length = 0; + } + } + return; + } + + /* Insert new strings in the hash table only if the match length + * is not too large. This saves time but degrades compression. + */ + if (match.match_length <= 16 * s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) { + match.match_length--; /* string at strstart already in table */ + match.strstart++; + + if (LIKELY(match.strstart >= match.orgstart)) { + if (LIKELY(match.strstart + match.match_length - 1 >= match.orgstart)) { + functable.insert_string(s, match.strstart, match.match_length); + } else { + functable.insert_string(s, match.strstart, match.orgstart - match.strstart + 1); + } + } else if (match.orgstart < match.strstart + match.match_length) { + functable.insert_string(s, match.orgstart, match.strstart + match.match_length - match.orgstart); + } + match.strstart += match.match_length; + match.match_length = 0; + } else { + match.strstart += match.match_length; + match.match_length = 0; + + if (match.strstart >= (STD_MIN_MATCH - 2)) + functable.quick_insert_string(s, match.strstart + 2 - STD_MIN_MATCH); + + /* If lookahead < WANT_MIN_MATCH, ins_h is garbage, but it does not + * matter since it will be recomputed at next deflate call. + */ + } +} + +static void fizzle_matches(deflate_state *s, struct match *current, struct match *next) { + Pos limit; + unsigned char *match, *orig; + int changed = 0; + struct match c, n; + /* step zero: sanity checks */ + + if (current->match_length <= 1) + return; + + if (UNLIKELY(current->match_length > 1 + next->match_start)) + return; + + if (UNLIKELY(current->match_length > 1 + next->strstart)) + return; + + match = s->window - current->match_length + 1 + next->match_start; + orig = s->window - current->match_length + 1 + next->strstart; + + /* quick exit check.. if this fails then don't bother with anything else */ + if (LIKELY(*match != *orig)) + return; + + c = *current; + n = *next; + + /* step one: try to move the "next" match to the left as much as possible */ + limit = next->strstart > MAX_DIST(s) ? next->strstart - (Pos)MAX_DIST(s) : 0; + + match = s->window + n.match_start - 1; + orig = s->window + n.strstart - 1; + + while (*match == *orig) { + if (UNLIKELY(c.match_length < 1)) + break; + if (UNLIKELY(n.strstart <= limit)) + break; + if (UNLIKELY(n.match_length >= 256)) + break; + if (UNLIKELY(n.match_start <= 1)) + break; + + n.strstart--; + n.match_start--; + n.match_length++; + c.match_length--; + match--; + orig--; + changed++; + } + + if (!changed) + return; + + if (c.match_length <= 1 && n.match_length != 2) { + n.orgstart++; + *current = c; + *next = n; + } else { + return; + } +} + +Z_INTERNAL block_state deflate_medium(deflate_state *s, int flush) { + /* Align the first struct to start on a new cacheline, this allows us to fit both structs in one cacheline */ + ALIGNED_(16) struct match current_match; + struct match next_match; + + /* For levels below 5, don't check the next position for a better match */ + int early_exit = s->level < 5; + + memset(¤t_match, 0, sizeof(struct match)); + memset(&next_match, 0, sizeof(struct match)); + + for (;;) { + Pos hash_head = 0; /* head of the hash chain */ + int bflush = 0; /* set if current block must be flushed */ + int64_t dist; + + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next current_match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + next_match.match_length = 0; + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + + /* If we already have a future match from a previous round, just use that */ + if (!early_exit && next_match.match_length > 0) { + current_match = next_match; + next_match.match_length = 0; + } else { + hash_head = 0; + if (s->lookahead >= WANT_MIN_MATCH) { + hash_head = functable.quick_insert_string(s, s->strstart); + } + + current_match.strstart = (uint16_t)s->strstart; + current_match.orgstart = current_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + current_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + current_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(current_match.match_length < WANT_MIN_MATCH)) + current_match.match_length = 1; + if (UNLIKELY(current_match.match_start >= current_match.strstart)) { + /* this can happen due to some restarts */ + current_match.match_length = 1; + } + } else { + /* Set up the match to be a 1 byte literal */ + current_match.match_start = 0; + current_match.match_length = 1; + } + } + + insert_match(s, current_match); + + /* now, look ahead one */ + if (LIKELY(!early_exit && s->lookahead > MIN_LOOKAHEAD && (uint32_t)(current_match.strstart + current_match.match_length) < (s->window_size - MIN_LOOKAHEAD))) { + s->strstart = current_match.strstart + current_match.match_length; + hash_head = functable.quick_insert_string(s, s->strstart); + + next_match.strstart = (uint16_t)s->strstart; + next_match.orgstart = next_match.strstart; + + /* Find the longest match, discarding those <= prev_length. + * At this point we have always match_length < WANT_MIN_MATCH + */ + + dist = (int64_t)s->strstart - hash_head; + if (dist <= MAX_DIST(s) && dist > 0 && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + next_match.match_length = (uint16_t)functable.longest_match(s, hash_head); + next_match.match_start = (uint16_t)s->match_start; + if (UNLIKELY(next_match.match_start >= next_match.strstart)) { + /* this can happen due to some restarts */ + next_match.match_length = 1; + } + if (next_match.match_length < WANT_MIN_MATCH) + next_match.match_length = 1; + else + fizzle_matches(s, ¤t_match, &next_match); + } else { + /* Set up the match to be a 1 byte literal */ + next_match.match_start = 0; + next_match.match_length = 1; + } + + s->strstart = current_match.strstart; + } else { + next_match.match_length = 0; + } + + /* now emit the current match */ + bflush = emit_match(s, current_match); + + /* move the "cursor" forward */ + s->strstart += current_match.match_length; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + + return block_done; +} +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_p.h b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_p.h new file mode 100644 index 000000000..dd2021a0f --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_p.h @@ -0,0 +1,116 @@ +/* deflate_p.h -- Private inline functions and macros shared with more than + * one deflate method + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + * + */ + +#ifndef DEFLATE_P_H +#define DEFLATE_P_H + +/* Forward declare common non-inlined functions declared in deflate.c */ + +#ifdef ZLIB_DEBUG +/* =========================================================================== + * Check that the match at match_start is indeed a match. + */ +static inline void check_match(deflate_state *s, Pos start, Pos match, int length) { + /* check that the match length is valid*/ + if (length < STD_MIN_MATCH || length > STD_MAX_MATCH) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match length"); + } + /* check that the match isn't at the same position as the start string */ + if (match == start) { + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + z_error("invalid match position"); + } + /* check that the match is indeed a match */ + if (memcmp(s->window + match, s->window + start, length) != 0) { + int32_t i = 0; + fprintf(stderr, " start %u, match %u, length %d\n", start, match, length); + do { + fprintf(stderr, " %03d: match [%02x] start [%02x]\n", i++, + s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) { + fprintf(stderr, "\\[%u,%d]", start-match, length); + do { + putc(s->window[start++], stderr); + } while (--length != 0); + } +} +#else +#define check_match(s, start, match, length) +#endif + +Z_INTERNAL void PREFIX(flush_pending)(PREFIX3(stream) *strm); +Z_INTERNAL unsigned PREFIX(read_buf)(PREFIX3(stream) *strm, unsigned char *buf, unsigned size); + +/* =========================================================================== + * Save the match info and tally the frequency counts. Return true if + * the current block must be flushed. + */ + +extern const unsigned char Z_INTERNAL zng_length_code[]; +extern const unsigned char Z_INTERNAL zng_dist_code[]; + +static inline int zng_tr_tally_lit(deflate_state *s, unsigned char c) { + /* c is the unmatched char */ + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = 0; + s->sym_buf[s->sym_next++] = c; + s->dyn_ltree[c].Freq++; + Tracevv((stderr, "%c", c)); + Assert(c <= (STD_MAX_MATCH-STD_MIN_MATCH), "zng_tr_tally: bad literal"); + return (s->sym_next == s->sym_end); +} + +static inline int zng_tr_tally_dist(deflate_state *s, uint32_t dist, uint32_t len) { + /* dist: distance of matched string */ + /* len: match length-STD_MIN_MATCH */ + s->sym_buf[s->sym_next++] = (uint8_t)(dist); + s->sym_buf[s->sym_next++] = (uint8_t)(dist >> 8); + s->sym_buf[s->sym_next++] = (uint8_t)len; + s->matches++; + dist--; + Assert(dist < MAX_DIST(s) && (uint16_t)d_code(dist) < (uint16_t)D_CODES, + "zng_tr_tally: bad match"); + + s->dyn_ltree[zng_length_code[len]+LITERALS+1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + return (s->sym_next == s->sym_end); +} + +/* =========================================================================== + * Flush the current block, with given end-of-file flag. + * IN assertion: strstart is set to the end of the current match. + */ +#define FLUSH_BLOCK_ONLY(s, last) { \ + zng_tr_flush_block(s, (s->block_start >= 0 ? \ + (char *)&s->window[(unsigned)s->block_start] : \ + NULL), \ + (uint32_t)((int)s->strstart - s->block_start), \ + (last)); \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ +} + +/* Same but force premature exit if necessary. */ +#define FLUSH_BLOCK(s, last) { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ +} + +/* Maximum stored block length in deflate format (not including header). */ +#define MAX_STORED 65535 + +/* Compression function. Returns the block state after the call. */ +typedef block_state (*compress_func) (deflate_state *s, int flush); +/* Match function. Returns the longest match. */ +typedef uint32_t (*match_func) (deflate_state *const s, Pos cur_match); + +#endif diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_quick.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_quick.c new file mode 100644 index 000000000..df5a17b9e --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_quick.c @@ -0,0 +1,129 @@ +/* + * The deflate_quick deflate strategy, designed to be used when cycles are + * at a premium. + * + * Copyright (C) 2013 Intel Corporation. All rights reserved. + * Authors: + * Wajdi Feghali + * Jim Guilford + * Vinodh Gopal + * Erdinc Ozturk + * Jim Kukunas + * + * Portions are Copyright (C) 2016 12Sided Technology, LLC. + * Author: + * Phil Vachon + * + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "zutil_p.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" +#include "trees_emit.h" + +extern const ct_data static_ltree[L_CODES+2]; +extern const ct_data static_dtree[D_CODES]; + +#define QUICK_START_BLOCK(s, last) { \ + zng_tr_emit_tree(s, STATIC_TREES, last); \ + s->block_open = 1 + (int)last; \ + s->block_start = (int)s->strstart; \ +} + +#define QUICK_END_BLOCK(s, last) { \ + if (s->block_open) { \ + zng_tr_emit_end_block(s, static_ltree, last); \ + s->block_open = 0; \ + s->block_start = (int)s->strstart; \ + PREFIX(flush_pending)(s->strm); \ + if (s->strm->avail_out == 0) \ + return (last) ? finish_started : need_more; \ + } \ +} + +Z_INTERNAL block_state deflate_quick(deflate_state *s, int flush) { + Pos hash_head; + int64_t dist; + unsigned match_len, last; + + + last = (flush == Z_FINISH) ? 1 : 0; + if (UNLIKELY(last && s->block_open != 2)) { + /* Emit end of previous block */ + QUICK_END_BLOCK(s, 0); + /* Emit start of last block */ + QUICK_START_BLOCK(s, last); + } else if (UNLIKELY(s->block_open == 0 && s->lookahead > 0)) { + /* Start new block only when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + + for (;;) { + if (UNLIKELY(s->pending + ((BIT_BUF_SIZE + 7) >> 3) >= s->pending_buf_size)) { + PREFIX(flush_pending)(s->strm); + if (s->strm->avail_out == 0) { + return (last && s->strm->avail_in == 0 && s->bi_valid == 0 && s->block_open == 0) ? finish_started : need_more; + } + } + + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD)) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; + + if (UNLIKELY(s->block_open == 0)) { + /* Start new block when we have lookahead data, so that if no + input data is given an empty block will not be written */ + QUICK_START_BLOCK(s, last); + } + } + + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = functable.quick_insert_string(s, s->strstart); + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0) { + const uint8_t *str_start = s->window + s->strstart; + const uint8_t *match_start = s->window + hash_head; + + if (zng_memcmp_2(str_start, match_start) == 0) { + match_len = functable.compare256(str_start+2, match_start+2) + 2; + + if (match_len >= WANT_MIN_MATCH) { + if (UNLIKELY(match_len > s->lookahead)) + match_len = s->lookahead; + if (UNLIKELY(match_len > STD_MAX_MATCH)) + match_len = STD_MAX_MATCH; + + check_match(s, s->strstart, hash_head, match_len); + + zng_tr_emit_dist(s, static_ltree, static_dtree, match_len - STD_MIN_MATCH, (uint32_t)dist); + s->lookahead -= match_len; + s->strstart += match_len; + continue; + } + } + } + } + + zng_tr_emit_lit(s, static_ltree, s->window[s->strstart]); + s->strstart++; + s->lookahead--; + } + + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(last)) { + QUICK_END_BLOCK(s, 1); + return finish_done; + } + + QUICK_END_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_rle.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_rle.c new file mode 100644 index 000000000..cd0850994 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_rle.c @@ -0,0 +1,85 @@ +/* deflate_rle.c -- compress data using RLE strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "compare256_rle.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +#ifdef UNALIGNED_OK +# if defined(UNALIGNED64_OK) && defined(HAVE_BUILTIN_CTZLL) +# define compare256_rle compare256_rle_unaligned_64 +# elif defined(HAVE_BUILTIN_CTZ) +# define compare256_rle compare256_rle_unaligned_32 +# else +# define compare256_rle compare256_rle_unaligned_16 +# endif +#else +# define compare256_rle compare256_rle_c +#endif + +/* =========================================================================== + * For Z_RLE, simply look for runs of bytes, generate matches only of distance + * one. Do not maintain a hash table. (It will be regenerated if this run of + * deflate switches away from Z_RLE.) + */ +Z_INTERNAL block_state deflate_rle(deflate_state *s, int flush) { + int bflush = 0; /* set if current block must be flushed */ + unsigned char *scan; /* scan goes up to strend for length of run */ + uint32_t match_len = 0; + + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the longest run, plus one for the unrolled loop. + */ + if (s->lookahead <= STD_MAX_MATCH) { + PREFIX(fill_window)(s); + if (s->lookahead <= STD_MAX_MATCH && flush == Z_NO_FLUSH) + return need_more; + if (s->lookahead == 0) + break; /* flush the current block */ + } + + /* See how many times the previous byte repeats */ + if (s->lookahead >= STD_MIN_MATCH && s->strstart > 0) { + scan = s->window + s->strstart - 1; + if (scan[0] == scan[1] && scan[1] == scan[2]) { + match_len = compare256_rle(scan, scan+3)+2; + match_len = MIN(match_len, s->lookahead); + match_len = MIN(match_len, STD_MAX_MATCH); + } + Assert(scan+match_len <= s->window + s->window_size - 1, "wild scan"); + } + + /* Emit match if have run of STD_MIN_MATCH or longer, else emit literal */ + if (match_len >= STD_MIN_MATCH) { + check_match(s, s->strstart, s->strstart - 1, match_len); + + bflush = zng_tr_tally_dist(s, 1, match_len - STD_MIN_MATCH); + + s->lookahead -= match_len; + s->strstart += match_len; + match_len = 0; + } else { + /* No match, output a literal byte */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart]); + s->lookahead--; + s->strstart++; + } + if (bflush) + FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->sym_next) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_slow.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_slow.c new file mode 100644 index 000000000..9f1c91346 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_slow.c @@ -0,0 +1,143 @@ +/* deflate_slow.c -- compress data using the slow strategy of deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Same as deflate_medium, but achieves better compression. We use a lazy + * evaluation for matches: a match is finally adopted only if there is + * no better match at the next window position. + */ +Z_INTERNAL block_state deflate_slow(deflate_state *s, int flush) { + Pos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ + int64_t dist; + uint32_t match_len; + match_func *longest_match; + + if (s->max_chain_length <= 1024) + longest_match = &functable.longest_match; + else + longest_match = &functable.longest_match_slow; + + /* Process the input block. */ + for (;;) { + /* Make sure that we always have enough lookahead, except + * at the end of the input file. We need STD_MAX_MATCH bytes + * for the next match, plus WANT_MIN_MATCH bytes to insert the + * string following the next match. + */ + if (s->lookahead < MIN_LOOKAHEAD) { + PREFIX(fill_window)(s); + if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) { + return need_more; + } + if (UNLIKELY(s->lookahead == 0)) + break; /* flush the current block */ + } + + /* Insert the string window[strstart .. strstart+2] in the + * dictionary, and set hash_head to the head of the hash chain: + */ + hash_head = 0; + if (LIKELY(s->lookahead >= WANT_MIN_MATCH)) { + hash_head = s->quick_insert_string(s, s->strstart); + } + + /* Find the longest match, discarding those <= prev_length. + */ + s->prev_match = (Pos)s->match_start; + match_len = STD_MIN_MATCH - 1; + dist = (int64_t)s->strstart - hash_head; + + if (dist <= MAX_DIST(s) && dist > 0 && s->prev_length < s->max_lazy_match && hash_head != 0) { + /* To simplify the code, we prevent matches with the string + * of window index 0 (in particular we have to avoid a match + * of the string with itself at the start of the input file). + */ + match_len = (*longest_match)(s, hash_head); + /* longest_match() sets match_start */ + + if (match_len <= 5 && (s->strategy == Z_FILTERED)) { + /* If prev_match is also WANT_MIN_MATCH, match_start is garbage + * but we will ignore the current match anyway. + */ + match_len = STD_MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current + * match is not better, output the previous match: + */ + if (s->prev_length >= STD_MIN_MATCH && match_len <= s->prev_length) { + unsigned int max_insert = s->strstart + s->lookahead - STD_MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ + + check_match(s, s->strstart-1, s->prev_match, s->prev_length); + + bflush = zng_tr_tally_dist(s, s->strstart -1 - s->prev_match, s->prev_length - STD_MIN_MATCH); + + /* Insert in hash table all strings up to the end of the match. + * strstart-1 and strstart are already inserted. If there is not + * enough lookahead, the last two strings are not inserted in + * the hash table. + */ + s->prev_length -= 1; + s->lookahead -= s->prev_length; + + unsigned int mov_fwd = s->prev_length - 1; + if (max_insert > s->strstart) { + unsigned int insert_cnt = mov_fwd; + if (UNLIKELY(insert_cnt > max_insert - s->strstart)) + insert_cnt = max_insert - s->strstart; + s->insert_string(s, s->strstart + 1, insert_cnt); + } + s->prev_length = 0; + s->match_available = 0; + s->strstart += mov_fwd + 1; + + if (UNLIKELY(bflush)) + FLUSH_BLOCK(s, 0); + + } else if (s->match_available) { + /* If there was no match at the previous position, output a + * single literal. If there was a match but the current match + * is longer, truncate the previous match to a single literal. + */ + bflush = zng_tr_tally_lit(s, s->window[s->strstart-1]); + if (UNLIKELY(bflush)) + FLUSH_BLOCK_ONLY(s, 0); + s->prev_length = match_len; + s->strstart++; + s->lookahead--; + if (UNLIKELY(s->strm->avail_out == 0)) + return need_more; + } else { + /* There is no previous match to compare with, wait for + * the next step to decide. + */ + s->prev_length = match_len; + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert(flush != Z_NO_FLUSH, "no flush?"); + if (UNLIKELY(s->match_available)) { + (void) zng_tr_tally_lit(s, s->window[s->strstart-1]); + s->match_available = 0; + } + s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1); + if (UNLIKELY(flush == Z_FINISH)) { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (UNLIKELY(s->sym_next)) + FLUSH_BLOCK(s, 0); + return block_done; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/deflate_stored.c b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_stored.c new file mode 100644 index 000000000..6160896b3 --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/deflate_stored.c @@ -0,0 +1,186 @@ +/* deflate_stored.c -- store data without compression using deflation algorithm + * + * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +#include "zbuild.h" +#include "deflate.h" +#include "deflate_p.h" +#include "functable.h" + +/* =========================================================================== + * Copy without compression as much as possible from the input stream, return + * the current block state. + * + * In case deflateParams() is used to later switch to a non-zero compression + * level, s->matches (otherwise unused when storing) keeps track of the number + * of hash table slides to perform. If s->matches is 1, then one hash table + * slide will be done when switching. If s->matches is 2, the maximum value + * allowed here, then the hash table will be cleared, since two or more slides + * is the same as a clear. + * + * deflate_stored() is written to minimize the number of times an input byte is + * copied. It is most efficient with large input and output buffers, which + * maximizes the opportunites to have a single copy from next_in to next_out. + */ +Z_INTERNAL block_state deflate_stored(deflate_state *s, int flush) { + /* Smallest worthy block size when not flushing or finishing. By default + * this is 32K. This can be as small as 507 bytes for memLevel == 1. For + * large input and output buffers, the stored block size will be larger. + */ + unsigned min_block = MIN(s->pending_buf_size - 5, s->w_size); + + /* Copy as many min_block or larger stored blocks directly to next_out as + * possible. If flushing, copy the remaining available input to next_out as + * stored blocks, if there is enough space. + */ + unsigned len, left, have, last = 0; + unsigned used = s->strm->avail_in; + do { + /* Set len to the maximum size block that we can copy directly with the + * available input data and output space. Set left to how much of that + * would be copied from what's left in the window. + */ + len = MAX_STORED; /* maximum deflate stored block length */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + if (s->strm->avail_out < have) /* need room for header */ + break; + /* maximum stored block length that will fit in avail_out: */ + have = s->strm->avail_out - have; + left = (int)s->strstart - s->block_start; /* bytes left in window */ + if (len > (unsigned long)left + s->strm->avail_in) + len = left + s->strm->avail_in; /* limit len to the input */ + len = MIN(len, have); /* limit len to the output */ + + /* If the stored block would be less than min_block in length, or if + * unable to copy all of the available input when flushing, then try + * copying to the window and the pending buffer instead. Also don't + * write an empty block when flushing -- deflate() does that. + */ + if (len < min_block && ((len == 0 && flush != Z_FINISH) || flush == Z_NO_FLUSH || len != left + s->strm->avail_in)) + break; + + /* Make a dummy stored block in pending to get the header bytes, + * including any pending bits. This also updates the debugging counts. + */ + last = flush == Z_FINISH && len == left + s->strm->avail_in ? 1 : 0; + zng_tr_stored_block(s, (char *)0, 0L, last); + + /* Replace the lengths in the dummy stored block with len. */ + s->pending -= 4; + put_short(s, (uint16_t)len); + put_short(s, (uint16_t)~len); + + /* Write the stored block header bytes. */ + PREFIX(flush_pending)(s->strm); + + /* Update debugging counts for the data about to be copied. */ + cmpr_bits_add(s, len << 3); + sent_bits_add(s, len << 3); + + /* Copy uncompressed bytes from the window to next_out. */ + if (left) { + left = MIN(left, len); + memcpy(s->strm->next_out, s->window + s->block_start, left); + s->strm->next_out += left; + s->strm->avail_out -= left; + s->strm->total_out += left; + s->block_start += (int)left; + len -= left; + } + + /* Copy uncompressed bytes directly from next_in to next_out, updating + * the check value. + */ + if (len) { + PREFIX(read_buf)(s->strm, s->strm->next_out, len); + s->strm->next_out += len; + s->strm->avail_out -= len; + s->strm->total_out += len; + } + } while (last == 0); + + /* Update the sliding window with the last s->w_size bytes of the copied + * data, or append all of the copied data to the existing window if less + * than s->w_size bytes were copied. Also update the number of bytes to + * insert in the hash tables, in the event that deflateParams() switches to + * a non-zero compression level. + */ + used -= s->strm->avail_in; /* number of input bytes directly copied */ + if (used) { + /* If any input was used, then no unused input remains in the window, + * therefore s->block_start == s->strstart. + */ + if (used >= s->w_size) { /* supplant the previous history */ + s->matches = 2; /* clear hash */ + memcpy(s->window, s->strm->next_in - s->w_size, s->w_size); + s->strstart = s->w_size; + s->insert = s->strstart; + } else { + if (s->window_size - s->strstart <= used) { + /* Slide the window down. */ + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + s->insert = MIN(s->insert, s->strstart); + } + memcpy(s->window + s->strstart, s->strm->next_in - used, used); + s->strstart += used; + s->insert += MIN(used, s->w_size - s->insert); + } + s->block_start = (int)s->strstart; + } + s->high_water = MAX(s->high_water, s->strstart); + + /* If the last block was written to next_out, then done. */ + if (last) + return finish_done; + + /* If flushing and all input has been consumed, then done. */ + if (flush != Z_NO_FLUSH && flush != Z_FINISH && s->strm->avail_in == 0 && (int)s->strstart == s->block_start) + return block_done; + + /* Fill the window with any remaining input. */ + have = s->window_size - s->strstart; + if (s->strm->avail_in > have && s->block_start >= (int)s->w_size) { + /* Slide the window down. */ + s->block_start -= (int)s->w_size; + s->strstart -= s->w_size; + memcpy(s->window, s->window + s->w_size, s->strstart); + if (s->matches < 2) + s->matches++; /* add a pending slide_hash() */ + have += s->w_size; /* more space now */ + s->insert = MIN(s->insert, s->strstart); + } + + have = MIN(have, s->strm->avail_in); + if (have) { + PREFIX(read_buf)(s->strm, s->window + s->strstart, have); + s->strstart += have; + s->insert += MIN(have, s->w_size - s->insert); + } + s->high_water = MAX(s->high_water, s->strstart); + + /* There was not enough avail_out to write a complete worthy or flushed + * stored block to next_out. Write a stored block to pending instead, if we + * have enough input for a worthy block, or if flushing and there is enough + * room for the remaining input as a stored block in the pending buffer. + */ + have = (s->bi_valid + 42) >> 3; /* number of header bytes */ + /* maximum stored block length that will fit in pending: */ + have = MIN(s->pending_buf_size - have, MAX_STORED); + min_block = MIN(have, s->w_size); + left = (int)s->strstart - s->block_start; + if (left >= min_block || ((left || flush == Z_FINISH) && flush != Z_NO_FLUSH && s->strm->avail_in == 0 && left <= have)) { + len = MIN(left, have); + last = flush == Z_FINISH && s->strm->avail_in == 0 && len == left ? 1 : 0; + zng_tr_stored_block(s, (char *)s->window + s->block_start, len, last); + s->block_start += (int)len; + PREFIX(flush_pending)(s->strm); + } + + /* We've done all we can with the available input and output. */ + return last ? finish_started : need_more; +} diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/doc/algorithm.txt b/internal-complibs/zlib-ng-2.1.1-beta2/doc/algorithm.txt new file mode 100644 index 000000000..acd099c9a --- /dev/null +++ b/internal-complibs/zlib-ng-2.1.1-beta2/doc/algorithm.txt @@ -0,0 +1,209 @@ +1. Compression algorithm (deflate) + +The deflation algorithm used by gzip (also zip and zlib) is a variation of +LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in +the input data. The second occurrence of a string is replaced by a +pointer to the previous string, in the form of a pair (distance, +length). Distances are limited to 32K bytes, and lengths are limited +to 258 bytes. When a string does not occur anywhere in the previous +32K bytes, it is emitted as a sequence of literal bytes. (In this +description, `string' must be taken as an arbitrary sequence of bytes, +and is not restricted to printable characters.) + +Literals or match lengths are compressed with one Huffman tree, and +match distances are compressed with another tree. The trees are stored +in a compact form at the start of each block. The blocks can have any +size (except that the compressed data for one block must fit in +available memory). A block is terminated when deflate() determines that +it would be useful to start another block with fresh trees. (This is +somewhat similar to the behavior of LZW-based _compress_.) + +Duplicated strings are found using a hash table. All input strings of +length 3 are inserted in the hash table. A hash index is computed for +the next 3 bytes. If the hash chain for this index is not empty, all +strings in the chain are compared with the current input string, and +the longest match is selected. + +The hash chains are searched starting with the most recent strings, to +favor small distances and thus take advantage of the Huffman encoding. +The hash chains are singly linked. There are no deletions from the +hash chains, the algorithm simply discards matches that are too old. + +To avoid a worst-case situation, very long hash chains are arbitrarily +truncated at a certain length, determined by a runtime option (level +parameter of deflateInit). So deflate() does not always find the longest +possible match but generally finds a match which is long enough. + +deflate() also defers the selection of matches with a lazy evaluation +mechanism. After a match of length N has been found, deflate() searches for +a longer match at the next input byte. If a longer match is found, the +previous match is truncated to a length of one (thus producing a single +literal byte) and the process of lazy evaluation begins again. Otherwise, +the original match is kept, and the next match search is attempted only N +steps later. + +The lazy match evaluation is also subject to a runtime parameter. If +the current match is long enough, deflate() reduces the search for a longer +match, thus speeding up the whole process. If compression ratio is more +important than speed, deflate() attempts a complete second search even if +the first match is already long enough. + +The lazy match evaluation is not performed for the fastest compression +modes (level parameter 1 to 3). For these fast modes, new strings +are inserted in the hash table only when no match was found, or +when the match is not too long. This degrades the compression ratio +but saves time since there are both fewer insertions and fewer searches. + + +2. Decompression algorithm (inflate) + +2.1 Introduction + +The key question is how to represent a Huffman code (or any prefix code) so +that you can decode fast. The most important characteristic is that shorter +codes are much more common than longer codes, so pay attention to decoding the +short codes fast, and let the long codes take longer to decode. + +inflate() sets up a first level table that covers some number of bits of +input less than the length of longest code. It gets that many bits from the +stream, and looks it up in the table. The table will tell if the next +code is that many bits or less and how many, and if it is, it will tell +the value, else it will point to the next level table for which inflate() +grabs more bits and tries to decode a longer code. + +How many bits to make the first lookup is a tradeoff between the time it +takes to decode and the time it takes to build the table. If building the +table took no time (and if you had infinite memory), then there would only +be a first level table to cover all the way to the longest code. However, +building the table ends up taking a lot longer for more bits since short +codes are replicated many times in such a table. What inflate() does is +simply to make the number of bits in the first table a variable, and then +to set that variable for the maximum speed. + +For inflate, which has 286 possible codes for the literal/length tree, the size +of the first table is nine bits. Also the distance trees have 30 possible +values, and the size of the first table is six bits. Note that for each of +those cases, the table ended up one bit longer than the ``average'' code +length, i.e. the code length of an approximately flat code which would be a +little more than eight bits for 286 symbols and a little less than five bits +for 30 symbols. + + +2.2 More details on the inflate table lookup + +Ok, you want to know what this cleverly obfuscated inflate tree actually +looks like. You are correct that it's not a Huffman tree. It is simply a +lookup table for the first, let's say, nine bits of a Huffman symbol. The +symbol could be as short as one bit or as long as 15 bits. If a particular +symbol is shorter than nine bits, then that symbol's translation is duplicated +in all those entries that start with that symbol's bits. For example, if the +symbol is four bits, then it's duplicated 32 times in a nine-bit table. If a +symbol is nine bits long, it appears in the table once. + +If the symbol is longer than nine bits, then that entry in the table points +to another similar table for the remaining bits. Again, there are duplicated +entries as needed. The idea is that most of the time the symbol will be short +and there will only be one table look up. (That's whole idea behind data +compression in the first place.) For the less frequent long symbols, there +will be two lookups. If you had a compression method with really long +symbols, you could have as many levels of lookups as is efficient. For +inflate, two is enough. + +So a table entry either points to another table (in which case nine bits in +the above example are gobbled), or it contains the translation for the symbol +and the number of bits to gobble. Then you start again with the next +ungobbled bit. + +You may wonder: why not just have one lookup table for how ever many bits the +longest symbol is? The reason is that if you do that, you end up spending +more time filling in duplicate symbol entries than you do actually decoding. +At least for deflate's output that generates new trees every several 10's of +kbytes. You can imagine that filling in a 2^15 entry table for a 15-bit code +would take too long if you're only decoding several thousand symbols. At the +other extreme, you could make a new table for every bit in the code. In fact, +that's essentially a Huffman tree. But then you spend too much time +traversing the tree while decoding, even for short symbols. + +So the number of bits for the first lookup table is a trade of the time to +fill out the table vs. the time spent looking at the second level and above of +the table. + +Here is an example, scaled down: + +The code being decoded, with 10 symbols, from 1 to 6 bits long: + +A: 0 +B: 10 +C: 1100 +D: 11010 +E: 11011 +F: 11100 +G: 11101 +H: 11110 +I: 111110 +J: 111111 + +Let's make the first table three bits long (eight entries): + +000: A,1 +001: A,1 +010: A,1 +011: A,1 +100: B,2 +101: B,2 +110: -> table X (gobble 3 bits) +111: -> table Y (gobble 3 bits) + +Each entry is what the bits decode as and how many bits that is, i.e. how +many bits to gobble. Or the entry points to another table, with the number of +bits to gobble implicit in the size of the table. + +Table X is two bits long since the longest code starting with 110 is five bits +long: + +00: C,1 +01: C,1 +10: D,2 +11: E,2 + +Table Y is three bits long since the longest code starting with 111 is six +bits long: + +000: F,2 +001: F,2 +010: G,2 +011: G,2 +100: H,2 +101: H,2 +110: I,3 +111: J,3 + +So what we have here are three tables with a total of 20 entries that had to +be constructed. That's compared to 64 entries for a single table. Or +compared to 16 entries for a Huffman tree (six two entry tables and one four +entry table). Assuming that the code ideally represents the probability of +the symbols, it takes on the average 1.25 lookups per symbol. That's compared +to one lookup for the single table, or 1.66 lookups per symbol for the +Huffman tree. + +There, I think that gives you a picture of what's going on. For inflate, the +meaning of a particular symbol is often more than just a letter. It can be a +byte (a "literal"), or it can be either a length or a distance which +indicates a base value and a number of bits to fetch after the code that is +added to the base value. Or it might be the special end-of-block code. The +data structures created in inftrees.c try to encode all that information +compactly in the tables. + + +Jean-loup Gailly Mark Adler +jloup@gzip.org madler@alumni.caltech.edu + + +References: + +[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data +Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3, +pp. 337-343. + +``DEFLATE Compressed Data Format Specification'' available in +https://tools.ietf.org/html/rfc1951 diff --git a/internal-complibs/zlib-ng-2.1.1-beta2/doc/crc-doc.1.0.pdf b/internal-complibs/zlib-ng-2.1.1-beta2/doc/crc-doc.1.0.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d6942ecc09a3f8b2d7e4b6fbecc5955121e8e7cf GIT binary patch literal 776142 zcmbT;V{~L|w>SJ)9owmx9ox2Tc5K_Wla7s!jgHx|ZQFL<-uvA9-204kzvJ1@Qy*%~ zvBtXAy6V&X)xYK{Qh8y~uMD)zFr-s+14}SW0D6F}p#^}O8-`BW*v8b!48Xw3zySF3 z1w$ulZsla`0H71KGH@~$Ha4>TW(>p23*+eIU~FIwGlkrNu9~7PF|qJ|pS3ODlxa4bFFunvyd8J@@?^hv*esX*(S09* zL)M~NzIq-}o@w5v#<3`kZs@F4=_94{i=7?Ss|LeiCMy%xVTk4w-FWUhdi-uH=yz$}^_D$DvcNs;CdwNIqNug!&Yv}uHjga}IwgRpJUmYSP!&~# z;Zh8Lj53x#>o-Fa+p~Ug0(`AZ0!hC&wIARGq_7`~T zjt#C0N9wHT^4e!#2n*?NdGWIo-_Xk=(=@{2}; zJO>YDVTMPcW3`t@&au_D6L<}TwjKfP^IE4q$c4$ATMl&N7O-C&D06{gRW~+y8`8HQ zLvTt5oaV2zNi_jO-myPMP}hLVR0EYH)KDQOH`;T1@=A1y2tuj|#MPVcM$>Y8#_76d za=DYEV>K}V+ff!=9zX#*K#4pp{-MM^Gh0qB=d=vPb;Cf7_snNaPha3K^Skejv|IHn z$%jEDiOOj5sK(4yV9Ic_Mf<^ewPggkk{xrg7L@2^Uog)D`cPkIDdnjmL`Md1S?E2M zTMU5cL!et(UZC%1GgT+eU|tWPexXcfakD6(B@)cZMuxxjQ$vtWk-4K0CC>&!#YY5v z;UX2#ZSRIwT@SQuj(Wd0g;uvh8z!71~9D=p2Yf)w}Dx&xYXohU6!{ zo+&<<+mV3?rsi%rtrUjvrZ!${3PP5bGG{;0T4*sLmRo{Js59F`5VI`TYtH`d1c?`6MVQlXx?p z^2c?=B@ki>rnm6j26z`)5Yl$Cn;KzJtr*bA;niGurUylydVJaxjXK_H2M)WOgTB&B zT6U@zIFA%O9{Aa)VWLU#0_oQvS>5i&y|PM5$eF>P>cJdwAdY~-DMlB8W#KUG?Z1dM=!EI55LTaRJ6Tfz6=Sm-%-DdswuRP$19(2OUTyzGox-WxuF}I zUpbdYJ;???1sV8{s=&9Jg{3@P;EL8Jy>1Q_R6SVFw@$Rg0+?)gq01BYVzWHW787a_+<~T_gwV)=$P>$ zhr}4PTQb*4W+ONG`04vUMMZ|*Pa>Ac)NJFuxncn}#<)UQj;<*bS>KK#f8(>R+DX0bH z4oAl@R4WEehvp7M-O*JJDb7i80RCBK&MXB`F#YgwwDQ}?cmX-Pf|+)u%h}JP_)amg z$w$X4lN3C8IQpotdhfZ|A0jiO2Fxm4(zFUHB)GM5p!b##x@v8R5{DI%v$kkII{6E) z%+czz$1~HLWhH%}yU|e6&d;-_BJ1<~W^eyIu?rZ;+WG~?*yh{6y2|hBcSnL@{99*I zcDFMI(8(K^8pF^D+1fZ6+c-G_{%Bo_Fm#H>j<(JYM#hc+hW|PsWBkqBK+x6=phf@t z04oC{fQ^Gu2j=&3hu`Y}3@m@1#>)%%*Ny&I_E!rO{eAJ@z3_L#`+XYoA1D4%vI72G z^GC@BVExxoMh*bmUnM(${a+;$J%Hn{k^#W*#}59u1QQG3cT@dW%?kLvr~j(i0SteB zj6W{@`}F_1~PpN>#!LT8$f!VYm`u0)D^(qbqt{JWTB2 zdE%6u?Q$(4(H|Z^yLh{E=r+83t4txVB=*mCEJRyGBc{?&VHC(rFv^#^P-33E1n7%~ zHCi{$PAXcm=`eSPO*(U_C=Zp%n;qHf=NEYNCEQs)CkObt_{hIeWMKBwXKVxRE!7!4 z+W580T!7Q*zy_=Bw+3;w1cMI3T@X#a^s+0$#DHNsDf-xSj(nth8vNM^PLbzVer0rETttZP~Jmkn1=%TI!UY9{! zUK(e+ngIhOG)qOd7DKOuL%Q{$1b0%VDoL$=o*WsTN7am;S|!Flv^K5Q04gEjdlNXd z`Z#|KTiP^>Nr+JxN6utkY-SUTTCm(-euT#zpapV=G_1-67~lck)sqoJIW<AmSy6h%-*`5ih)4>u{&9hg%I;YZk?~7|e<;DGOVtdV%1Anrf zC+j(91{KZ_vQIHJo%lOB7;Zku>;Kcqkq)C-dI zD33m5Y@!nZb%A+z*_2E3GhpNr4k%a$OMf4?Vts3_elt@)=?Pd1Oe;NEo0jETR^RtF z`nern3C_b;9a&ZqCXp&pK`J3FOL1(D_oy^$Y9_uIQ3(K<&Cos>Q27zd-ft|#IAKAz z#6Z)hKV0lWReq^vzDx0890(KDPPeCFoyIYIlrph>9SkLBwPf$PuU%E(I~}%c4iU6n zesiG(L)@Z89}SXR5{3w}MpStFh|6YQvwOr2B}TRHxrn83%Epq}GwAVx1FYESGD{LhcmE~Uv}RWx zB9MtQnL*Kngd_lJ>`RD&UnVq(S%E!=gUp6(1nWl8=vx)VqQ)v%)4tMfr;YCPL{_&W zX+w{ON807QCbg%|vdKJQFQI&~Qr)k7qmV#&1nqBz{)GIl3vhkm2s_7Z-K3-mgURw> z5|r@2;&+u9bA!GgzzQm^G5KPAs1R$~qhdx&28YSh;U~W|l+Mv%C3|Hmi8IqY4;>LJ z^qi0f?GwX_ zurAGNsruL>akbgNBOJ+b;MQ*JZq{O7tKaqF*BfHJeIQt(=Unl{7e-bVQu?n!Z-zBT zZA0av?cO69M@pUMYrx+(IJ!VBl~zcQeNQfN#|)zoBF;=h1!B9WAoXGECdJ(&po%AJ z)<5+XID=RY`IO?JeEwljX^DZ{l*`j#vV}uRge_5=%bLp4TD&*%07#eK8##7 z)Q)f5=%tSG!aW-GdB@p^hXeRe^YFcbT(3Rn@slX&1bPhu zW5MEiZwy@mEN{f74^RZTMcHd>im_8_5a(q)K7M~QHXXfl)25C{@=+#Zp9@#8Jui{_ zx<}G>t8_Mz6M8h9i1_{vl_qzLLXpZB1(oIEV+Qog#0(LuSx|1|C&34DRx?b`%QeO~S+>Hi z?4}-Nz}GyT-VlDaKfMC)Qkp@_p8vJyW(xf ztKj)d-HmZ?1`i&s%OgnTpNPDSUg2m+30J0yrupNwa6z;ajkyLl0jqM3AG7I$AN2`* zKh8L*Rc-3ds;bHy@FvziS(`q-#N|t4x<F3B3Iz>Iddc6R?5IrK$Z+|52zw7V51{Haq zeh`jw0F7P^3D1Iwf=8K{s!B>ne-nS$?zxL{)Z#~ zBpwXi|1~84Soasn{w>M>XuRJf{2K%R&OU9o^B8*^CRvQ52*cz$fnvngEL9uqo=NtSyOk}$|Lz9Ptl{S`*PA11bmQDLmVrD9gj6q+zOE-y64WoV)k=V{?RctVc|_8 zVj3lz1a$%5&18Qd9^37u)iFwb(x~5UA&i`j(WPt+dbJiwky;Kc!2&sxCLX@%&fsxX z8!Qw?nlfhR+zbPUiih*b*6|UY;$rW6m(MUrY;dDj0Q64v8Liwx#S`)P2Yo7LLyFvt z)Eyc((+BqPJ_-342__DJJRhJt6 z>yj0!82l@6DDoa^IR#Aco&R%?CQ@&Ne8f|0vOw>A^HWq{ zW1D4WhT{`+)C_~hBs&x4T0gOnYGsaxC2=na!{o)5<06^n@k+{%b+YmU5M<=|6yIDJ zJ8)WSOmOov1y#`)ApVoUxR*q&&^=aU#_)w-nW;EiQPNRyk&qPRyj;4|0xD|dlT|;` zyt<-x0o1RckF9fx!0-x_IpX5^ZM>HJsaw!lj^}o%6tadka~Usy;FxtqK9JGW_WnI(P>xhsQY6vc4a0T zN3S9HR5zY#Z=g93Xu+GJtDIuXg&gnZ$Eo?JsNV#Untm;$YB4xy%P)&Ki7_t>Vm4Nuo6O z=J|akX3Jgkxd__W3WE{mehTlM9yA@OSA;2d4!2f#`a7nnB;yHp4|Aa18sn<335h0j z>45t87Bu3{*u!7P@{!juo0I0y7fECc#V>PZCHe%;PD_*l$Vh<%llSM+3gI(KyCR7Z z)WBtwLh$sc#uHhHP?=l?^z04`zEqM|`>Kf!LCi3?2Bhq|y%U*vz*)YgMD{DAV(+gho_~j|w$SIJ`wWH8fQ4 zBQ9fh^!|&2DOv;Sbx9E7FbP6y)K}2wO6p*TQWTk&I%&@ENI)d#p+z8h>9L28=z9sQ zH^rVElcOM2h<*N->p!a(G?Fjv;gbz^9g=R0Mo&x4bF?)VFck^nf`KqP>xGCH@%KTT1GAOtm&$oNzb7{6TD@bBsj;JuQLW4L~hG2I1szQY%+E7>*e= zHLIZ&h2f8JA|VqNHBzs`k^@Ax==*9pGzh^>`%bIIGkVp^?}uzc)IN2SNF8;1rV1CO zMS}?yipjj8g^Z`+Ad%nF=}SS2%-Hxin>-(r+&rWV{5loZ61$ughCe zuvlP&UZz$U+`HhD>jDp~Sbm~SgpzBo@W$Z!lC4v1NunL2<6>?Wsii1c*9Yq3i5bLaeY5bF#TdTUvB1>-ar1W2uhZ{N=iBh=el!BZDl=_r9R zX4tEWmZH`yoyQIH<5fKejOSj41;v>$Eq&$>d&uo$hV)cReL<&MOkz9XQe%8R*-`WV z0riVb#-EaWUg5f;On10p5z+nUFJpQzG}WWz`>6bgCIoR;VKK6p~ohC6i$~ z2toN>&u8s!U23d2Af2~@QGO?&>OkcN8yB&(8<-M^{jKDtYDs{I;+<&!Y2lLXoDKFE zK^Nzn*)#a2kF=a2%Xk=HDdcS&mU5I3fhhMfOQO>y7Q3qk7&lbl$V@WfVOS3J0T4!% zyj5Nx8+f9ZkwIWHSoR3fZJTz7J9YkPpSj(VcP;(|cEE@56D_r*A;VzFVitk}6E665 zmWoEJZDh*u8YuP!u#9|b1?3}m$gNk!eo(029I`Y}iJeCNGdnw0WI(LedA-iyg1>est{Aw8IB z!@!L;LK82-fbtxlmqmA9Qt&%3zYMf@gmj4^W8+(JUm%CYb!Z#q$4wZ$gN6+zJGE^Tfi%)E?^6zFpGJU`S z7lvlXaSLutI=o&^1i_VSdZI0Qm{HPw-`(t7zB)Z{!*gV{Kr*Ea086#j(%q@1Rc@6G zh;nsmJKlbhu$7&9v5PMTvo&p`;Bl)IODXgKiO|;b2R=QODh`-0$+P265{u4;I7~Gh zeD&5h`fdo59j459jLGy;5j{D*#BM-yz=cKP_RU-tMs>8I*AeebR!rvnhN31DM1jRe ziCSy`G#WKF{kEAww?_)gE&E4I<6(;Sy`eTNS}ag@bL^LRrl@uX5bSjYzjf{e{-Dik0A9gBL7E@|0&e}5$iJknTr13 zbNtVBf8FapbNuhV{>#ySPhx-9f2a1}2>v&v{~PcBjNpIh{;zHQMQ|2&`hQCBb4{tl z)fS}ASG6PYWHId>8LN@dZzyUUDpit22TAw%?8t+CI^mgNbL{n9yz6FHqzcH!mV-a$ zbV-1~aH21&^}s$HUJpVakH-d89eLV1au^5=3ue<)$qod^ZPe;>3LLofpsI+!Vz|1? zoKIHStyWA#PR{ve(z#(LpC0C~?JfVzpQdxf91|qpC}&>wrh8x_OJ`>Ftu1j zh{0a2@}X!RF9(0`$|)goa9!1D^41;mZGC^GN&AW!SqW3&Gu9+k_&~2GZbXz#5~8V5 zn-5X*jazDIS%nssjr*zfu9?QQo4#?>^X2n9U9+*u#^Rj!T8htR`FdT|&NC4U)r)+C zF%P#;i1aS~MyY^}qLb_miWk$K|n zrtRwmYss|*l#dpbGk1N)CPjFx)_XxYH>aGhmKO5}8ml)58h5jN@h@`B5glv50Aw~%-7BNbLMI=_D=U4^L%69UqNm^-isJ$jO8-L zlUYAp!4>_Xz<6`kjl>dI$Y!6HR2p6Po!aX$?Fq9_*#Ngqq zg27)K3XfS%mv|=Df|dGH#8#i9?%ngbU~wlX{zs;mjl*>0_9U&CJ5Z3^fZAFS3cd@9 zBk_w4uo%~ry|&WPxzmIK>!9TTliN}|z0w>EceuQht)lG2RxDtJnkjF-ZtET6pwCKz z?wGJ=xF*G3czE{?qk?5i>|k;zg11ZSq!M(EU(@JC=gMvi$e^as59bk9sFFQbT3R!3 zRn#Xu-*}Z9LRO&A2vK#djDv0kL{~;B+CRZTG+N8eO>{1XvO!zPstVR=Pw`;zAk{Ro z)}t6ax4s41iRiWTeo^zYGtLiiyw5`*C*a3~xRm#poTH7TpOq?@hGzZQU(iee=7<*7 zjW5Q2@fCqLDFD{*!``)dqC6DQ%hwHo63tISe4Jqw1Umq<0i+OYDBYgUv`2gbF!EKH z>F8tOse`Cxk<+(=Ge0{ygaX5UL>Pcw&;KA)yXKJw)R?Z!Z+UIFbH9)|LNiMK}%p3^uOpY4^8TcL2p3koc9c+&D58yZbU|unMDalV5|=!#-RR(IRk?X?JII*KerC{r~uGa;L?p|1uKR;U>ORQEi2lE{r{3(6Gj zbB1pwoK2#I?7&H-XkkPt{4;Wfpp8?x>Xv}H1cg&q#f==-w$kXh?uZbYW+@aQXS z)EeT#SiYRRvq(#NB)ZWwY@kGkbZFWZJ~E+Df1!{tv`WMV)Xxgr`!X})ZWr?ekGQEW_$&kPoCE7~%b;gDGZjJzuv>dmvq+E_)mD@<`ENB%Adm z2fIlOAjGMnQLN=&d3~HWT|)+QfUH-d2FOpxuZ@>D0MjTkhjSsh;Fa*gPw*_6*;9Ey zptFYQ@K~`bfe~`ha-tn&DjOCk$-4S}N>)1~*E>OVzudO1g+DGH>}u&=WAeF;*=|nU z*PYs+XM$mQtaI#Gp{Mxp9fv&kKa7}-+H1e!&{f#{Yg#Vf>})!6hgRTJj2U+vuFm zp;NMqq#L_bY=x<7HxVlk0IXopS^RTj6#YT6Nllr$i@)+v*csw#vBHd8OVmL!NX(10 z%}TE%vncI=di+bPBrUi!KlCd5_Csd*-H!x3bZEjz>~C7WEz_gtGII6>FZ1W;M83=e z-NeWg%12+`UbiaC_Vi&6PIu5c-@N$r7|y95uW;9h z`z5#J^i9%Oe{HvO82b)IOrAT3URbT1;dS$kHy&ll#NvjtJyYRtN_ryugG^bJ5X;L5 z=RWV!>_JJ&E{FgOc@Y6REFfsA`-2Ljphgo!z6xPgRHX%KXvpZdNm;FB`c=MEmspiY zT^(@2sdB;5SA$gz#oqWfC#otw&G4QTea0LUeoftp;x)LxfBGZL#Mt?Y;|Q{Xy=Gqq ziFLrnsm27pa+aK1Ihe;YgnQHug0LxcK%ek*y`-PKnsHYrnmd6lfNePe9}Se$F~UbG z-BM{uyS1b5YDvpba(NCEhHUddePy5;is3r(MY=1h`we}?({c%GO^Y~jN}>X#(bu0j zv&eO#+jaD{wvQ0Yad<*!zV&D1M{R51-lfM@Yk~|dCwl_Q4CJ#lq!=juQzG#+9ZhV8 zoUP(#81%>6y*N5vY`3}m;WA!v>V|a>UIa>>?VVZFEi1yMTyO=t_Ue*poww*}q8OJB z#xJYsC~@DbVb~M=sWa)U)}vdEe??=mOmT1GE1=9Ppo+{b$Df_tcy5&uNDL z2WJ00VgHZJ{x^{Sr>*~H=>I=v|2+X`1^gba_}4_nUs(S~;%53IApc+D=J>~<_qn!= zBXKiQ$7S`Fy*j)Bb7!p zn>r$SfRHb2cEQq%|LwjO+ddJ*BQatq0#MtjcJxA+F+MhEQrrE6P! zx!(34E(eb-rs~xM+pM=%dP@o0}0c z*M-`V2A+ah3G2)IqDLzFDSruVxg%^c$H5O^fetzuc8pqJ9tiUG(Yr8S6BnHiWm{N^ z_@f|WaNGH#c$oKSN3WV7MjY>Qb?y($IUqlIb2cI-O+o)#Jkg5UPmB$E!>GKO_nZ)h zEh|m3@<7CJivm#`@ZDrG#h&icsEma;MpI)6IhJv4ychA%swc6*qV<^*)!x#bVcAM* z*>Qg4z@Pn)hCS`-B~?$L!SML@gld&L(I;rORW{zvr{!9D&qtQK1raUN=N9Jzs>(2n zsm2b!0G38p%iqM>Bk_)f&MAPQ`XRSZzO*7Z-x-wlA&BB#MEwlm750gVIX5N=h8(_5Tmx;c$3*k82#n7A`&)3XQlntW4rL6U#YkKQ zm*#4SGfu8by{*t!+V#oGq%jp7hT-Wq229fwAhkRya@=vm?=&{(x5I8cS+R@t177Sq zn&^?QR~T7ALiY7#2x%{GSerBh1lN#)Cx&Mqr91XNHKX}tm>8)gztErR;s}JJW+= zR{$VrL1|MMz%}iUD{BU+N>+T8i7@`zi-eP8tVVgt3(*xrAaSC3F`9puG$W##)+weB2kf*F|7bXG+@C+qIxVHJtdMp6Rz;XHhleNN z^nIglLeH*297!jK*k-_FStl4-RuqCLu8`6(j>J86?gt<(I}GV;j;8_v}AtA9y{CQcG-i~#|}JZG$(1`X`9j#9spO1OC@DYQvwKChDXUi%hN*D zq2XhzC!T05Sm_Bc&e(g?&p4Sjj@SBHQcmYnn=QLgznSGMOVD}F8=E?Nb+!3yIOKHg zd?BqFh7JM^!i_afFJ8(Z9=UD7rBDXmP*Rb86E`jrN%zhp2*Jiq zs0^!BT5rx>)C;^3GB|9m+Iw@kZlDc>E{5s@CL!z4<(ARb$}zo_I~vKvK*>x5>A}|{ zx_ad+zZyuSqK&veG}3<3FuteroruWckv9MS4e zxkn~gFVxFnUktZ)VW~7wL>;$qAyJ2nluwokZE4zDRl{PSwv4C=D>Q9xJk;G)VEx3_nH*5*MNkQX~NPm%2L^+ zeE^#=-dfVPdM7}w)OMXyy4@1Vv2a@9D?5R=JEmMQA>H9jByL38@+4}1A%{KNjn9P- zqSAN@_eK{zug+vm)0b6q21kf!FFVzg!`X04v*)kvE(hDXbR{^;SNrVkuZ+4Wd=FR% zUbE7!STj06AGjIOkj$ibqBc44VTqZ&VC!0qjbpT9FNdV=M$SLgdU<@G z;CpVs^}#p2F9*K=;yG9F3PDS`vYFnjvop7>>D8> z`Ff|d@^Pq_g<=X$JCaGqYNpM@K5UO$IN-@<|o{o zLQmPD<#ii%KCMj-4EZ5DYvWTbHkK=$CSbpl4fk8#U74m}v;B+1t(l^lxBa6gb3^wo zl(ty6JMP-(n8&KZ67*m-+J#>Vwjix3_aaa9g?%zOJ_CibXDMB7(kG+NPX^zU2$y&? zi`=qQ?FiAdVLMzdE^@PxPZ335?chFgvkk7uwD&m&NeyUt!ZmL% zVEL-{RZdj-47hU8HDWDai(**c?g!E?&xfpSYUXlQfS*Y2%h~^6(vH0tnSCVFGE=H6 zT9nHD#ji{Ea_my_^Ve$hO69w0H%>FwVBA0-<>*=GX^3Y)<)XW6HbF`>?<0r1&zY}| zSr^ee(L(qHLtuLq%BRt(u*cUF2JaNl{WGV%WU&(8G-Y9|=~cY@Q@8@t7K1q~j#oIP z>a*8~GV*#`%K?ecpWSmG&OP;YS2mx7gv&xT>=NidYI=uh$OV2{*nYUY9>{GBQJ(#8 zgERe~2bllY1T)kB;|TMg>;4k%e>C{tA^q=3!z=J-D| z_w*Z~6ZotF%sqpqjV`1QVd3>q69_2ZAVAVWB5@rpIFL@-Gzc^5;SP5LL&Pd(z1@ ztYq1)jpLWnpF;}%u|kw54$NmBc|?p}OS)~HjHxeoTf-aAKU4F1YKvZUU9j?)*0WAt-X@IS51v^4SUh9OL*2npj7EH5Ta+SWkJY zOqJA&;B!02Qd;>nSXf1@BZ;a*WIn0|@oKDWVZGFnCAy1(KEE5H7Obo}mroMM&`!T6 z9$2SPT2LLP_1q_6((y6VzW;o-DW{E(iz#f6AAqU}59KeuIi-Z_DRSyz{d1O(^cq8= zOH4DzZ5np8`TM5E^^Lu%9c|0a@iFTe3nin+{&MZ2hUU3Z(mNzFemwEB?APT)fU>Q;Xr`=!;7#M_MF$5*DbQU4-pirr}PvwX^ zLmPgvH1w%rl;7Rj__}-@Nd~Q>Z-$P_^O~M&BE3r@9s06!=L8o-rA2@5#S!__DGixO zV3?Kgm7{co=5XSw{Rm6#Q~!q*JW(bQG|?Jp4z8*<2QV*(2r7qx%s!Zc@L4~(KGpXI za5GC=?XW#ooY>piu1>nL@U9o8oYV(NvQ!Z?id3fZ)3Wa`TBZXJhAF1EUJAiq+Y!Ue z&-0O=;`B~uKCWx)RI6naC*CjL#tZnbgRc*?$}effQ7+ zyD2HF;AfjgUY+`)KNF04v6iK_MYP6%p*Bf!e8#Awh$*J0cT4riHVed~&HPK*|B9wyTvqwhs9niLSxDZrm(2w`6Q(=Z2P5v7E2l*61TZjcb9N1YtRnWM)~ zP3BfK<1IRSrF)tlTsuQsI&;Qkyj03ZO1hc6#0W7sJdWOyr zIMLAlrhRwmrg~T8QU#(+vENCBmCCdLHs4znZGTLytKgx$!eNefKhD$*ZENVoc&tb} zir1614p%36*4$jCe*o1Kn*O9O#+JcKU5>F|^^53w3Srbf;eJa;`vSvJ0S$c`UFVI} zOWb0Es5(dV? zE^OejD+)YDH*i3{HmRfGKIp|S2It3$m}NL1f7tZ*jkk^~`qDc&#_y{j#QXIXHtEUl zN8;a{<8Zg2Zgn=&BDWCB37scBSiMHu`1saM9sn`wnpW`Ak8D=p~{ zK?e#SgC2@W@0AXj0w3CeFgRsF=ooau?_g|h*W$#y%J=uWFb5dH6|egvxphM| zG4g+%tj@Q*Ggm*0TySu02*@O)+MP>84y0!Zbqarg6%8UHRPRcz`LSg-5p_EWdlmyi z?||WVoZqJ(7blxEPJS#IY`v8mXZS1A`DvzSwS0nBCu{xg^lTkBKkOvk+gpD?Ubw+k zaxkZdJQk{1uL<>+EoHzDQDLZ_`0Yh6?e10LCG-O#66lUoAe9PtTtly4ln>mHj}bHo zmn&{`MyC{GlVKn+?4Zy6sJ|Y{bZRE6Tzawzr>A?zTscE;94Pdc@g{G6tY& z!`XI7;waOv4uW)ybw>BBkKGxyuf$!qG;HJPdd=csW? zDr;~;@ZdzgG2O9a7zXqnOQZPLJ-ufez>VtRi*C%PSFb0$*^Z26Y-$1_&qB4O0s4_} zrrTg-bXQq=pG!qn&fkFpTUhB$nXxcj2X-9NU$^~G7Tu=+4rR^sz~PwHM3I)DtH-vC zq2uo|ptEO+Y7d2@GqaUIRMj|BDZIX=H)(u8uzj0!VzY*src9so8M>*r`RQv zTXLaPcr38tuV4Z6KzJggM0RF79TA zHg*Hea1}vRf|OVPJ&B);G}G%g63ANx>gmSiZn>|&6iLRTCVp0KkeY|Zf?>~3uhF>| z+R?D=^rRvaN2c|^Q6g_bS_!UF4z{X2$YqPigu&WLLZ*4VM`0ODL#0_?U8}4rb7|&Gjo5<>C!N7JeV8c&#sgNIXA$q z?_-QV^x1sVZCZDF$%k+xj}JwGTtSC&Z_HSx8Le~VMRH_EQVNFaj07E-1pqJN&amB& z0S^$=h$7#1TL8beRgah>c|kS;q3t0zr=9#J<_L3MfbyJ?GJYK1fJOairMw?93C4+{ zV1cZF@_8U_MgW_Af)K~!h$n4;!t=2Sz`AEnyqYvmJREkgFr=o5EXc~1*;6CL%|p#` zS6K4yCpLKE8f|2nvo9rNmu`TAf-ql%EqNu}n_l65-Nv1|M&rjsBoqsWVC@f-d#=^a2eKnArCdOC?E<>PITB%tBgcB^DQyFOEjLk!7Z6jqK z?%G2Sf7Qq+Qb_97NM=%J+Un9S&}VUQBk6pa^<0rFyguPh)T4uyu`I*6A}H)(|GK5Q zwzA1sVLKrTegGoxtg6CFirOqG-&zi`ttj}kn0M+?CAz`2L0hf#rCL9qeohL zu_Uz4ji{kPm^Di^CSG2{uNf>*qT=C85mSgW2TR)`v;%~Xi<>CcOlxu;0=wBMYz!rK z*c(!ql}Q;M%axnJ=+L{{Z4Q=QD1_<6Oyv>#%7^>@;@PF;ZPx_jEqJiHntwmGdQ(i* zlQs`Q6JwgY)Jel%Ez3PHMv?Io7-zQUG~$fvdY3aOG%w}KojexYsd_Yj~ zrik<|4V;p;ICCos6zPIF$#Sk%;39LsIv@c}jA?5UBOFwEK;9WWADE?UNquqfEXtGR zH|8J-;_iU`PPr!baqU3K>eLWoe35_w1fOC-@^ZYd?( zTQA~UzIw`71kxZo`d!^XCdutl4*UD7RwgDVKDWQv@|0a*aJ7p8FBe?kNRP-JM1-$< z8y#D)8VddS6YAY}a^Pn1Wx7JBM5Zibj41#n`zhM~M6{>1e1#4)%L>|Q?9iqSPx^Qs zc#=i&mjpnHIn47lglx?(33QhI@rfdFkHw1-OTPZVZAUO1KOZF}(Z)Noa1;F;ku|zx zu_?`w#3Rqi((l&sA}ssLt8U&qmZm{FU}Bc`-&QYnl#d>$Z;{Lm9R- zR$rQb=_mxRASKhY+yPeyG^4g2WrVlstZVMHz-rn`&-?oVEP$d|lqC&ZEF?nd8y;)< z^dZn>hRsPsNa_$cJz-jOv=dbM5g#XF&Ot(Skdr~lK8t6>YpoL^dItzh=4ds0Cvc@;o0u0g_rY|sCH254{d9Y`0(#qkFsH9YzgB2@U$az>DoPWg02^noIqT(- zi_!bdcW|h}k{$mm(BBjNKuAFul1ja`NIaN>14Tmt-+~EBtpk;cTkoq-84#A3>xD1m zWs!>;KS|q59%gRe7{0v*lL((#z{hmlk$1K=`5Hh*KIw}%A46#BXR@;(**}dMw3u>( z(WU!i60bAs6IE z1QbpCWk&^vvZ4(g@BV3Z)8H!|!v}b+-U%XB2vci?-62riSDU>DFibz^B^2E?Ik!ny z9C)U-6Clvo*J#0&4IF{-2X($z%W4|>_Ij`Ea&hnLI247d9{y?=8kwX)FSPOTrX;+lW}pOchrUK&}N|I07>$T`UdGR|5i8_@&!5g^*pc zuvH6)*ItYsz^Ms7AWnWH( z=YlCAz69MXS}$fwZ0^a-FO#i2&JmDMlw8!j{gZor|ocXFuVQ zv{YRlx!Y8ff(NBSFvbu^ zW)9YuejLFa=x2vx4)Zf2M>3xbj%)R1LN<)GlhVHYM!0BoY=p*St(kO~=>Bj5@(I?1#%nBuM)XE!BQDq_w{ zkVWI6A*MFB`Joz%zCQ1cG}MG-aH8R$H$A`V3KJY?FGH1h#{>#5u*O%DSKnhz^n`KUD_WEHt;c$3 zh>Iu?QwF43Q^7Ie;`6tUCvlzRNH%DlTT1O!zR|>vz`MjF0L`TBDjv=ntI$Y`A;Y+1 zQs8|w=1KPqis4*|2>?qYcPoyO?>iec`Gd7;L4b#Zh+hg!GQd=zQ*ewbwoAT>iIc{XT8>{CYqU#m{CFDNUrAN>?2^I+PMxR4u z^-e3f8SzhZE-p1>=u>~xk+f+SjUC*Wy78C2Onu_#NKnXrI#_pL8YF74`T$@`k{A>v zXVsvHUX&Xd?W}{e43?1a*hNLoft`S)hAabcWClvH?X;u%P;(_D+T&ORJ4{g7$hglx z8qt8)VUtYMBRuf{X3mcbRhPSMz8}T8a_T6OE@~+~Y3kj#yTF+v$Q{v&g1v&{8zgGu zAfy0Y5f(5^2bo+p@#3#YqD%3!+csH~SG+~P5Te;8nF?MD2{5RQ2q1L;&_7wo6x5=Y zg(VQ<1?@3tyjFiNl1I9IK{8pzk8r|?V74LSBH*6xm-Cm!I}NsFK&F-RC65nHRpJ)l zVcvD9EfdmmTT#&KO6o@*9z%wCNv!H2`my@N#)2wlrJr`a$G=}Gy24Nhp^L?4= z<3r7ml)TXDiE_KXeR+E3^W__u0svEQc--mO@8Zm3gu4fq&;}mxl*>KCO-z9bUFC1% z2dGwLY~##S;}@I0osewT5sf$g9Isv+1$4ZkJ~pU0!*F1y5~H6qY} ziG7giCDO*gjIj@AVrW(!tEIHEpWE?U9xQiqg;79F%~I1AlftOQPHh;u6QTfCM;Sr` z5nYmD1HC~?1&%9gBQp9ryHf2Cf65TMu3(X!YAq_VZd}DC^kni4TI-WVYs?CpBQGPHj?MaqO1mz`htF z)*+6BRl{G`RJ2ho6?a${Ib-dD3#4R@VEl$QW9N;_f=uXE(3gW=#T%KI{lZ{bWBU1# z40f2wsro1#OQrO*+88r%4P=51V_7dD+*+Gn zW9Gjw{d_wN$yLFgiCTLzMBp^Wu(v!du=RDw&ju&uQ(IChe|O`<8NYcdK?{nQans2JmZH1Rwi+KczGb=%2Y;0@)JkJ3sKO>@u$BW0 zf`sQn`%OEr(>xB{s#CpWlJS65XeKyWd~s-{TE>+&CG5uPjZ#;~Y){HGFDEmgyiS3Y;$`g@j{XzIMp2Zi>ss4|{>W^) zLB^e`WW{dWF~(}bt5S+3QGkVR*ZO8>_tciF1GNHF`EFo&E5+yr-^Q|@IdVvwhN0+s zqy-zEixW*b1)NB&%xYDedwnvxXT%W2NRRJLaEXFKWEgf>&vxR8%>SNr7UUn(?^Ty4s2Z z1;C(mRt*=;Gu`UC@S@MWytiS^9K&)0UF4D|w{q~Qd{w_mgh`}z?A#~^YS&X+qY+*N zfYcK1Df$-2He}OwPy5%Gjec}}`o0$#2~MSN;BtMv58ZSzNBSKeGZ2wZc6VLBn{Lvc zoaD@cY!&ZIkV}^*%|t*xtbIvQ%b+_~*p4`Sio3i`3bo~BLV2?2NAS%30Zc+~b-So- z_2EKqrFq!MrT#J(sb3kS1Gs#g#O`iybO(~?ASn)Q#xfTC_M z!Ug+VCTfo8uN4=~gIa3(gR64f8HZJZ0dVX|EvLrS?bLQz)H6hJw;8APUB!X~SX#rA z`5N|Q$(upp<@3O1qr+H<8FMif4}Zc5HZsGJ0ZBhV=c5mgg9e8(jsN7i-n0F2CL$Ks zI(PV#I>=7NI*TZ{s^L@EzJ!}yoKuBkTs&4TImWXino`zySAtj9nI7t&A*cPqCiHzn zA_#$z(cAWZudeGRFW-FL{#n3&(X8{FMC?8#@Y!&*$qKbJZ83UxRs%7d*#Y{FU5cdx zJK>#5TS#d`jH@+(M}Y#jiL;&-GI&7}htsVyK7yb(5U2G_Q?vSagAUV?3h~&-Le>GE zubkyYaq$nk!e>oJhQaLzn4lvhOY%@Ptx&l z1ue>XX15=+DtL6oR$ld}hyZ0&dw~BgBC9~zu3hGC=D{IV-8^wcUgFsUN z2r4&Z&8mVsfMd7`FiSb(`S8toQ2fc2@zg}O9l_>`GXTu8UijgW5 zuUN zck1sMS&mPa(_cUTb1m^NZEHL2ABdmeM|d8#ixq*<6&h>Of}idjaIrYpoRJU4rY+EH zs@`6o)KtXtu=E($As^9}K(*rFPY_OVs?@)ewlj{Y^!`f(hT}aVKp|6-9DE4UECgR? zJ@fUB8DD32#|>n%gFWcc;TZOv`VbekI0#?<-SgO-eimFO#paG`=%d`VQH(=6I=XCucb!aU zOIcbW{BW5YdKbE=rn1iNf|%kEnlem}`QH3DC8v~hutR6Md*>tzRfjCkhIyT)?2}Tc zbVcj%NTo{Z$(ep{!@`JsVfg&-^`GelR(B01q=1^h6nhOg%ms#9n- zk9Cs&ecRw@geTD?Tl7?v`iCAhp$vs2M4F{OBCo4bDAczoS0x}D!9i(2MU-}jl0XlX zVkQ`;nACdp&+9I>Qw@jyBvDu=PcO#2uOW6-e{1~o$>9p>W&$rnBH7Nnz zj^o-u9UHYsOp#i5`BiCjm(s?>1Vz}=OL1Kh;k>B9Z@5>Pj_JQyY>&c@s5)blmTvjm z9+9n%whJml9<>)?APSwA0dfKbg%32;NA#|TfF>~#2?3M<=5?1B4QT1v&WfxIYD`oE z6T(2}z=^6bcps&Mbi;iptJ-@v)>6dHH>Oc9)*Y3mcBDVpFw)hLp*l_dhQQU|LD@tuAR)IeaRsg+vOf9PC2kye`>EMEnb`g0BIK*($ z&LQalL{GT@rO~-I_NYd3C!Iibq4ACoK=n1@cmkE?qsblv5CS$)in?r=D7h% z3(3Kj!cXXouVWbRqECS;Tuf~9*1s^_zkU0u zSY5ZkNylLLOV3xeMRMu{S)4W9B4`4@)DiE+S}!y)QmdySP^rA4jx{lMysBwbf?>ud zUJASzFRvLFBB6f_P$ZeHN8wV0i-Hkmw4w(0UFw+{ryRn+XaB-YcvRMC3YRA)pm$Kev~p2pu3iDiRF-{vLNbt1Du|OV2A1 zJ0#|nk7&DZz!tm91q7cQJR7aRDWUE8OP|~=YUG?N6S_=@58_vlel~4M)X3V&zENZ9 zxcSM-D^=6jijA)qbGn=_zJ9U1P^j~u_iqQb?zC^ky}3bzhP~lz!eD^X@eB4_j(U?) zKxI*ec`;}66JfLkb?oVci_vTw%%F~PzpneU{Q?+yS{nqQ-@8E=>lclHx%m9iV9oz)Ji82|T#*~RM1WV)QxJ5Kgl0f}=X`gr+ z;IA|?3V4#S1Mx{IZ=;vSb@~lr==ZneC&x04h(E)VWbA+Jg1H(X_$nCB>*b~)v^B8g ze9KGF+x*gTQ@%^%!konzW0id)Qb`>ul=g;^42YeXw|3V zILPY=D6l6pe24c3(q^V0Tt|SYqZ4N`9gqB|!jd%mHZMx+{(6C?0FM{2iU!EY??s4I zp)SAD55q5vOsoMN$z&SfDQtqk^I&&24geYMmsp@6b)54Mc_yR?%$xMq%_R*Vm>$G% zg=x_A3(jg-`3mPMOaKZIThR_b#@ojM8@7T_n!%OJEA6hnCdp!+{>wv$heTJ9;!>=>24lVX(N=^f7RsCIu z<0GxN&ZTFpI~o zo&}6CT!ugJ{uoBWhX6d4mbN^wNk5;31-Qqp;$IY?P|h?Lwo^G0Ba_Wk*+c3fGJLoA z@9`3T!R@`Z{5vN0*n`u$)^w=6YST0F$JX4Jm=xg?Fk}i7kb4*Xz|AAHJE3}OAPl&o zqKCnWr;D%7ypx7_bat0c!aO%RX?Xb@-b z5o*($zHU#(K8}X4qOfkYY2T=OGk~6R8n@>>=V&N?`p&gIvo`qg3`Lkopp?EoUcuo=Uezrjs)S-)`E(4)Z3fy}ED zFr!$){~Fd#RHWATk?eo(Bj z>GjW@XOsBCPHs{GcHJ0d_R==U;45Q}yPRNtnLgzXungyN_w@ci<`bW-d4t2^`=I?= zD4mAv8JgO`D+uPjGa1>?5U3T{AnpYdcyEkOzimD4=Vva#TdJU3h_o`|{kbcz#j7yG zGAc+6y_kO485^bdaR`HI96~8d#I@?9~8|=@iFj#*MXB-Ami`BQLu-ul6`- zp+HINZk_f!o%ZSKCAy2-4p)zC;-OiFLBUFt)$+ib1v||Thz}mTqJL!**1u^mf9HjN z%O-yf;Qz!Xtbb`Z|6@G(U)bcYb$>tC{}*iX2VndID(J=jkw*9glmA_$;lDZNKSPs$ zqe(Hbe)byur)Z)h?X<^+^jY6?C7~(KSNXU_rYV^s+}kL&5E|PxgIwh~D}Z{3 zWLULi%Wy69(_;2GZ2OCmt~d^2AKMz3M#`+gmov33_ur#ks6L&bWxFJ(w_UI}xpe7i z{OF`MJOqt0C8xD%lMsjsKYtFpe(oF9PuK9tP@BS44?z|$V?umW0S@TZ5o16TzT*o` z%=iMvnqe*}w@7mbBNKUHtYrV=YvE3lXc752A_@*$Tcf`(ck` zboU0PCd0$-9i68G6qc;*wx!N;GE)Gqy-^|{-!@S&xvor%Lezdpg zlk`8|y&I}RY7VwsDaZCTi5+;YKM_ujg5OTbtunn)<3rr%h6RL10C1%YT4l2l8wcX| z{nd%$6b4vz_>!cI7>*q}ZhBKdlIN2JL0B9t-|&6xqLXOA3T=U4uJ5J&$`QPS1_JJw z+Es9a6q}mFJ@r_0)3zQrIsNGsi)NVDi`&2oP6-tK`C7|?YR9#X861{zN!_v!qC}L& zzJ|vyEcsx^bWT9}a6U-MdkwGMal~YK^~y_tymfpD^W%`ZnWpm3*cKVl3ddqsauAG~k(XVOL zHQJnKfJ9^^EY#HfZjOX`0$i1}&^L!71VMo#g04e(YKln4b|cVlL#-}?n({ScS`pS> z1*`DL)0tEcVarI7F6v6&zR4F_Hj#BjNUP6V0|5 zK@YLW{7y5VqX?Qhi5Z>6vABO~I?ZnUi&}m8ORC-6_r#1zu@Q7~E*IiS?#Nr;hE$ez zV-RVtF?2bkZ5GLB2(TtW0Z=e9Bvq{gD=q((0>Q%IFLpyCL;*`O)p^__{rh8YB)G*D zeN31GA%)fDW#6wEG>e)KoOnt=^Q|Mf(ytFHK|tP4W5XBy+;HO0!2GOR!2ZTyI{a|HK&ol0Mgx=1RTYp#3~Q5s%d#H^`SEaXK>|-@3&-Io z)hTG%oKDgn{i@%!5bZzcfKPns)1JCSo3M~7s@MSi^3;rDb36zrM-16qUJas0`k)J{ zTeI9o0VRY;MOkrB8h8(#ZUpH85>KsRPc4FX1C_ws1ULuj?^qn3=CG^#>1hUU`-7qs ziv{KE2od%4+k4($Bg2VZogV>`X~iJqHODLgPL}e54h&FyI&Vj(S-fObbKZob;7=j# zD=-3Ig4ox9N*@6R{l*H0z`#4iW(S!Rmyxm5kY?o#M=K%0_CZxueeHV!ps5ra#<8a) zxszNMQT*NBW}64h?yZ-%%kaVqJ)*7}6Qvi0ATzyQ;p+EZKEc_QyxF!H4hU>UpK+po z!O9xEYJ(B0Fh0DDUGV9A?$xCATmNc(5!})8Y)(-ta>#wxgQ!wNM4=G7=i2KI+J?zX zZ@qQ8{Aj0Lj?3quHTR<0pB_t|oNEhP@zLrn8~R0v zSR$FJr`4%ZA%(D+l0&r^Zc^)W8_16XUqQXk=hC8?nvZ@(Eb-9Hu1!YX43NM&(8?hB z`@2dXttHyLz;nK>AslY6A!N)xCqWZFM;yZ5*QCM@lh0jzTG|0Nbd8IgxEyhQ6to*jw`+*|hV%QIjjh75d$$qtZM{4uLmTdE;F#Hv5 zk*T)pfi1>!V1A|-r(GmpdvsCJ{fQxM`4Gp7l42*^$YCb~dQ0c&u#X+R%LCbaPH*8Z zps-*GVIj3pmPC97%OFfgUqAfr7n0@FnTV+q!$OF-e5`nci3_jq9?fG)*hqU#_m+8X z`dUynIlc}hl18=_-HhV%sk2p(R#$K0Ts~=jy;$9ldX?2jaX(7}k?mk0EuhNu*;ObC zw9&q6n2GSAENZk1EBc-8}HWlO)l%^oo5eS3}ERy)&{KGq2|-voft zc8R5>c;d945bX4+w!MC*IrIR6`9?!eQophrxER%Qb0;KrH*_b2?TPClU0D(cY{Vua z2JA2???vhsSAJrhYWYQtYqA6*v%nJ3Fc?m_hfQo1|&l2cs3rO^kUo3`5y^SCC zLL`}6!>N9K&){qGD?i$HB*Y6p&4u-wom%Qk1}eeRt6RT^UTMbUXwDOr4&@cZJy%gW z9HmjZUA4W7wHWw)f zSO!1-mkU!x8hHM9tEexDA!bV#Lt*ZD_vDYfSz;b)up;pti~}!{OcPsV%BbY!T1aiq zZuR~nldnzG*v(6o4prDo#g191dntiB`>M_dPIj)AjYCaaOBi}c!|-ycuK1RG$L&JB z&%a)s66m1S?P3?fW{a;&0OJ#s@l3)lBDS5TU0Fi*irn|?yxARP|7OtsA4LGxzm1ds zJZS&F6aiTOw(egC?f+nh|Bs3K&j|3J`}_YGssFPX`AL;Ycet_@ap;Jt$uG4=QN^9S~Cd;4}tls z5Gf4}x33ek&u?iM_D}LK!Mie^jJ0YE^I-Z z2e>EO3t01fK_2Ipf=!Q1XJtKE!3i$DznYNXawnnv1^xP?e@FeQ zoULEqASD++p^?ex2~JIl-+P5v>Pm=oLb9GGStORB7ZkKIs!xRzdxqeARfz8nNBYxf z#c`rBoN&yU+&GRnY^+NT&IlM*n9;jD!Hg3KIx%5>2t&2*lYt&G3 z@(pxOZ>jI?`)#5BWIT+r&b)PX&jA=#ZftN_O%hHQMs$#BKhgvH%zVg<16T`3g3b=o zr3z1@Lkay54LPGIG4Slnu|`Yckp%v{^mu^VIHw>|ErwJl*jseS z0Rm_qqWdX ziAWDxO@uBiK76R!(W3&!0kdVTzInX0`ON2`K~I@EP!J-g5{g3$q!(1fhG|2 zN46-E`c|OduzmJ32BP6@h{3!%&|U-X;LNbFk>-5!T@*k#?lL6Fqy#^ye-oFH2O!ooplzs`{Vn}C*iP2LXDfdEonSh@{;*pTx zvS-_ctJJNQsG-g<+{hOI;)y>cfsvXV1*rV_&anK=g^*AjarAsJlrZ;F56JT_3MB7v zzcE)KpQG(ktpB1ExQr%q0cX9lqS7F!KGPeto&sd$kmMLk-u)cz@!})2By{3{+6`w6 zqtNp(lXv<>O!;{$L7OREAye%NPz4KULLw5JrLYLue1Uths|=HoS!OabmsvoK)>Cwn zmrbWBIER7n+cfG|~uw zjt1y$ej^C45=WRWUiJ#<^g4h0)_Gai(zA*C?k!5lC{$2NBO-B$m4#Wzj>a<}@YBZ` zU_q5mW9dBSiI&gadn|5sSVbnXwu4fXm!`;^XCC34{|q6E#?saoX>V-vS$-rOZd!~2 zDPK6x0gTuy*gN!93=6*eI``@p7pFMl+5M~KSt;Fpz_qS{7ZwTs=k5IvVq~x-`SMUW zFquacPmUTOo_NfOp+3IKHPEh%lmeIRaUl0&Yq1wdoqWR%Uud`YCXf#qliV$L6r{ShY!bi(NIn@#V)uuS?!V$vPyf1v(<6jpi?pCyeSIjx4VHUwzJ` z=v4u>RYEematqcxirg>n!vpJY2aTKg$-EAJ0ZX&kwvx7hwn*nEl$2dT!I1`0@7r>X zVyKE?bW>5Sk}89nH>0#kg4OeYc8DI<2!6JtCix zZDXrID30?;vS~I4Ga*^k7!jFZM3ufr8n zZ|XHjsT%Uzx^clXve3;NYAB2#g1W7>%26~ zho!mljXw~Y)~89gs!cljYNS?HFA5RE$wh2v zW?06d?-NL_(K%{g$0~Ls)x-?<<|fImXIME7oo|!YSM#(Buy%EktEIBBti=qKbci%> z=%PNfY%1Xu|W>=|G;OR;unk5f@ah6NGOo_sr zC?3XAQCLrox{nm2jW-Skd1Z^{1AFn7pr_*+Ck5FYh*f1xlT&x0idgMk_2tk6iBP>^ z)M<5>{}syXz5^cH(3<9*N&q66Hpqf?!)tlfuoUMnNrMCeH^76&VM1||`bdduby)ij z8u#qVnDv?D0A~fy=Ua=`a>tNx=G!pw)=j_#Kxm2De1m1wp8@^OlmBCSK8 zZ|CTYn{>q$py1vB27`9r$R08$IXp!@_0y~@RAtwGtzcs$`iqeFaK#Mp(3DDl_ru&* zda@J@nwpc9jwcO8`e$fZE3PQ$ZyBt4QAysl-85#5GMh-gGG27*5n4R0(hg>fMNS~Q zEr!&nqCDidCa)QENCQ7S9K>-U=QV=6miNYmY|k%fjK9E1^_qPA7I;DTki@?RFhD_a~H9c~wQ*yj9qX;1WA> zbW^G;2A>Ijl(CEiS1D7;i`m^UBzkqGkyR$Ty8?p);}APIcvgHT!m-e-<6pN7XrI-_ z7kIE~8Kw90nf!6|{AL_vL{wtKZ1rb4NCCS=K?-wPiw0|xzIAR)BySa@g|P|KZcl@~ zri8Vz?6tO>yj#R1_oY_HlEm%CL(3pVHZk!xQ8d0Y32DxZhwy>)InK`RkaQkq9_&aY ztt777O5uL9>qn|sY64}TKYM+Y92R(rE^*;%a}u&}zhV&vF^NoC6IeF8T#IH!!#Z7` zqTBiFJ~Ej|_iQI$b4OIM&t6M_bdWeoVDk^*m?E_NK!(1Ai(54YF1^qhwa@u+vy6XT z?-FGFr5>535^u3~#Hv-l?PV@76r%!O7P@M1iXW43kiT%U2;Pub0zJX9;I~~zUq8E^ z>)B96A~ryOTXs>SUO_+MJ#)um9OyDKRoET!K4-g@H)rX`N{M_oh@9b}> zbHqX$6!s}fQE3;Oh1VnCzT`6B@5-f#?*_-$b96vk@9I2NbFNAjCOdcSi@0OTS+aqN zY1@O3h#o&TAHeXaNz!%WPNvY_lVv*>4bm2*U>g=oe*BVx&Mb~V-#TLY?zA&9XQqq` zG#R~gN_fa~;W7mQkn)U}Jktf@d@WJS>hV@s^|}LFo}8G`S2gTd|A+?u&>2qSe-kPR zc>6skpu*iNr}^=FKq^}mAs|63c{U+eyrK>wFEv_GQze->5!lMU?;H2o7^ z|3RsrBGBJU0{$alW&2YQ`-k6*{XZ6UHa^>_{`N54rJC(AHAPe>rbn1ecYKqY#MSfa zPQ9XYsx^27C{2o61;BK@>&L6BJiLHEj?`Tdg@=MejM$Wn{NoZtZsJ_QWzKKKAtvfy z$9LW&Nk)^u<5^=QO~pzYX3nk`L={no?c_h+-;@b|4`fQFM3W^jpAr3dFb@LpE zINYPd@3&c;0D*VFj>V55?`yjzs&mLowP$N`S}K^8aawSEq3a!DBD9gds@b6BHv9Gx zD!ygN*s2!48mH9eR}t&V8Gwb!@g3n?Mx`m4@){crGeJMz4j<_cJ1(PUcNjJq8J6`b zqWqM0=-#{{rvk~?)Aj+ayoKuTN+MI44}R{v9nr%RyFLkh6qG@rjlWnJ@+Jv*cS5mR zHE`t%@u!fu69YZgMy@?_Uw}>kOid>4@B#@?@}T^m8{pr6!<@esW^6S>J8Tbr7GC&^ z{EVZyT@efR8c1c#Gx4i}FAIXY^n`dx*Q)YjNp`qoXYqQ-u${Ng(i*lMe_HbdPVD%Z z@%_$Bdx5r92GmVb~EeH2YTR|Ad@GPr76urlLsi@>Y7LpKs_Oy=%Zm**2}UXyCRaDCCWB-aLSbp z!8oB>4n@&WO2Dm^Z>J9JsJGtS@hOhqy}MdRMWh5L{b{;bMwEA2oe&$2#Cmy%(DJRON5CsE_i(_4AOsmMGEFzL?!L5qcHD=pa0j_68 zihkC0N3tPvLFTI)X1?rdw3M^r)ESldrGwXWGrlBF*rA*@ovw`GlEcE5ipMi)EQ%D6 zRWg2S$)KU$I2oO|Mxx-zNKL~BBiwSb1|WYJ=4+8bB>8z2Q$&{*oyo}99h}@*bLaI9 z>MJC)4%D;!*;J6)$vbB}5;%u82Vqh_9Fk1-gD)n9MWPYsU&k#0r*gv=G_mi&#G5HR ztA(x?514mHhx89U1sUyi=I{^k_2#r2L)nTyMh6c%G(^q>oCG2}ibpgRkAerk-D|`y_+W+qk711gO_zcGTSW|ephuf_kD+HGhyGrq$v~a+}+6V zKtF{b#H@2X19&}8eGlSzK!5|?&`v;SC@do?5S;Gzkm!c9WDDMXKfkS5@4J3-gU9*! zD42z=4`akVV0F9a;rKAbe~$gkO463a!9g7uu4Ob`x&mnY(AC#AM zqU7g(z8BJ+x?JV^0ch4B2$5E=F>0QPLA@sBvhF~tHP&c}GRz@zdv*{NeaX^3#A#GV z8_XWL-LWY!$1fV3OKs1Q_z~r`P2bZNxqaO`!9c%XJ10Mt5uEo?56BRj*$)|B9Ss0C?0#Ovhz- zFi##1lZj!(`HO$wi4gd?4G+n~XmRO{fj&U*R-(Ha1jmp$b_W==@~Q=uo~CC$D$?8X z$jU{7?stS`S9OpvRvAp72fMdlNa=w>VNhjs{hl58d zM`7ierk+<9d(xw1apKQ4bhrw3@GYpmtIKBO^orS1tavM@!(V$1%fzkwy#x$XxnPW0-PUu-8zvWT3>$P=)4$$;J zfIpzwkL`#~c~U!EN#-`dfzS45q)(mOEiP3OUS2`u$p`328bvC}ErSls2-#h)qsE-0 zXCn30)!NG(j2pPbo&(-blK}_uv+$C!kd92n5WDX%vvsy`vJ=+i3OVV4I z=bSnN$1RlU12FWr$+jtIU4v;Ilb zxtcIePz)hX(Xe%S51jYl8F}S`s5}GrmdIvk`;-ho88(Ah6_Iv_pX&aAj@~?(eE>ni z%DfOCwUA55(Z^V_?Csyj)~7#FO%GI#Jg=sWV5%44++sB3Sv+fsIN7I<5I`*LXnU)w zUGt>oNdow8qIUB~>U(rbom&83%m>HzHa>)PE_fy(A$8#fEu*R5pAy`^zVRI{(~+3u zC`#C~`&`bf*?nA5p&&jjb-S@@kT?-tPrz;s?>EOXcm=NU$&jxn79!sc!FC}@ksKkH z0hS2(!zvS@&g|Y#wRfp2Y@`FVbIQ%yQkqHm60lTi6FhXf^{$vWip0sGpvF(WZ=_^4bUe zu~JZD4xw)Ni0Z3~U;DU|g1^1g59-S~*&*;WnrekiNvNIm!aoXnKlHD_!uB_x+20}J z-vY~D!}>oyY=3OfH)o&e-KA^Q1m3@ow z*ItQ{qa0DcMujMrnB>sdrih}+NpUdOH{=ElImntcE6+0y6wCVXb+I}-V$@emT5^np@IZ3j=x2g1{66>4M#$@~< za&3q06Vj+}6k_{=lHI+NF|tUuZ1=x zCw-KRHZmA|2-3FD-IMi5%ikGxFxKfb9tPv*xJ7vzNs%A6)Six;fa%dXd`{FLd!f)G zZ|}zBv@7_?5Iq+HxJ^`}^1BMh=MfhHhA}$i>SlhO>BjIAiIgBjmj;XPITuZ!yo3w* zG!1X@)#B_%su&iAw71+za=`)7UAZDIZ(PFr4}bv0y(0lgE`S6MnE}(U`BZpL>HHq_ zgsvk?K?Whe8PrnGr4LG!=>cxnB&Dgl89&;;rGjKbw~D1EZo)g>g~>|!t{0Aj2+RGp zj7#+8_#WVSh^odT+s=n(U?YvVE_7s!D))sAvJ0T<|7;PEsL;efbf6Tmt<6EssE2{f z#ZqU8GxylT_@-$;u8y7-OOQr=K(o=3tzBYRyg#oR>>L)T3Ou7EIDxt5ymMG?0Uej3 zB!~+bdF& zw3qWnc|wGk@W@GVsXHvoqdt?au@0DRTxrPeoJPAGw_Zc5Fl)f|Y;nlR0l8BJ3p7B- zqnD)#?Eb#wUXg#8ai{JvHE^~&n^;Yr3++4qB4Y5WD)E0<`{p1^mUr8>ZQHi3X`9nF zr)}G|jcL25ZQHhOPV4nOS99ZcUflB{-u|m%M^)~stlXJveYw8%5#T{U;*kv-%a4Uq z+W3Hloy@y+-^*hLanpMk5obpCN?Xc$7-;&Tyg)734&1g3e45YzgcYc%UP?$hH}`DXxUn}F z;?UAWyU(jAuRELR6E99DbxWD@>!3!w(qGReP~u!&K&HD=+RUJn$*RI;dlaAGJ9MxS z9ckS-O**3C1zoSJ&$z2n?e%JLDh}8kVskoWLFhp?4AP$~pL0IAElAKjHXlud%U$nR zrY&e8sqbb6SI32JqD*N|dQXBcBNYLAAe03hj_1uI%cbg8kw-1|TDCkrP4<;J(bG zWfLC5=OfRxlUirZ*bSaW?V`J_qCc0c30Zvr$br6OZ@j38uwF=J(}}eZV5qlb!U^4G zt?(A3v_|P7MMo42T`mmpxtIPb-1Z8IDYvg^0oaodIKFaCQ5qGzl;*6~_Q|JHXDTp7tE5cP5D7Tv~bl+2yU4X>D?D12~674gYKI#g*1{?6dk5?J0rK zG@M0&hAe$`f!!0h>tO)ej?`zPMu^YndV?a3SKLzNR9~LpM#L zGgp=}MGXQCN)-mE@DAiotPFX5KOm_^r07#W6sR1%tC0(%Y?nGnCc04b^o^D&T^aKy zm+Cmbv%NLW=Q22p?=~x#h7)}q!ijv)8TXs`I^B=YH%b;8uPn1g(j0t4f-R5A+Hb!DF)ntq@~jG<%@VQqPMm> zcThGrhIu6?04#u1oXt7ozUX><^IF-ki;M1>!)+_rB~SJiD{`bWgSUeUf@4Nn8DK47k8c}c>sT9hE*?-y^*w9jqias{xh>j*5?uvhm>N*{v8 zaYru0J&!A9DHPM352;~v!~w;GMnp;0&T~#^Q6|Yl51U7t`nc_NGESr4S6o}Dpd8Jc z^($%0@IUq>)$G!3mBieA56^)&vQEuiyOyA&b|{w zUQgsEjcniZyLMCh*uuomVc~Wj8XPdfF(SnTsKz2i@z0B6Thw$$AxQ(NcEf-@25<{Z z^7c7qFtpsl0qMJGSB13KjqGK2no{nk76?rj&JqmzXX9a63Cd|&U(eI>qA9rOEFy$e z@|9k)DZAVmH)ky@-)umZ^S0xk8eB~BRTNmUo{d;t59Mx@<3WsxOWG3Pboxh7|9s-u z(h$~0`IZ<+?&lJ&)NKN)RlsFD?ZzY3ucT}%q<*lr5fL>v#xmoQhES*&Ci`@TkB~5_ z<)51;R>aPMftV+hvnLq-!O==>37gW$A$~$2?*wdwK2o;+PL405=H{Wn0P1d>Un|=W z>8VykQTcG!*Xw)Wrh4Tb zcs*!VfCVo2lKj(((4YxB0}kkT8~dD~0o}AOCHe|0%G+I9ScvJ|K5Qn@O#GQ~Dj{rv zSaVCm0}(&&b*HwQ#vP4=_}JSRdxFsl(sB_k340(aU-n`wb@j77gU9_+eZkYWR6!Bw z+HM!0*^&ekUAqvehHPA~asVD-QXak_sZxq}i!Q$rjcSCk7*U*@CY$SlBtrDp`ycnr~XDV>?@Q+IEyYmZ}Tt0z9>CDL>Q5 zTyAKa}P~67<_Pj{HK~(snm7nIJdI+RT<>`DOO1daru64Q%|x+x7Ha1 zXGsWY(0;T+uVggR9Z3K7u`Fu){x@9bPs!fjbDjTiR8};0uyL|CGJcU4j&(Zv9-|`or3!7y8q-=f6sOP;5Uo}Ulssg!o;u4{Xe|`{ySIZ>-#?l&L14; zzq!uWDI5fBf9V_ltr>QLe>WibXB6m9X7-;Hi23WG{`&my1^@@&HEj03D9}=M>Nhxp z2WPd1v_AOqet~liUtCP4nqjdxd%+tb;qD%-oeB-Wz-g^<<|i%y&gMj% z!qk&(2apt86o#I-&(v;Rk2~vos^p~l;kH{-#`ac4Te3XQKcc=e;J^1o`9DEzLS%>c zRMJoJ``lpOTyi_G5Qe*+u6>Yb%6{1M4H`NR9*ELphvoI?KMuC$Ur7@%puA@GagwGr z?+1a>1zlE7Zc;bT47hCPN^Rs^tM9-`JNG#InAP~8`+~m-jXNDymD0@$MEh~h-Y^QE+E0&3u;tTg&#gW8|~XsABGJ*YX1IvLXW#}`~k3yVa~)?+XBbF0gi$gi6D>tq~rlC|?KgMvYb3q|yhN{#FE|LmlNx zOQRa&n0{lOU$*J&#?UzjQT1khL9r{zdvYI$^k7-Fvy@q@6@6owjG!<_^dl`I{|kAh ziYsh!2`ot6o(}rAGFDsDL^ju+w_PnU(3lDP#(TApt*BI@7eHffj2$b`sWEv`7Q`_9 zRuzNKpvB+6HB~5??*J;e5pFvb;TF=vcrOy6-w4~fLd7KV*5F0NlW6M9!+jH?e-#N4 zLI+noZ#hWx((eem?i@k(feYB0vml`W*{LcjKydg*pkS;{@fy{b{h;$pKnPQ4yHXEAEvRz z72yEi@}1c-@VtPooQwhf>5{}Mn0O9d48Tl+%U$Uw&F=8mAc*c)j))nJV>)c+ecNL6 zhs*oeMyfl^#~_BzOF))4?sFD@xe%GONuW__Sp>BkEkVMN>!_0GB$idmygk-Fn)OzW zLQ*++RL6i3XJyyF=C*X}5Ag*%3+7decMr=MT`)aMO>31a1lWn&?-xr$?Cl}nookuJ zb+*i+xr_-VV;5odZH7ET7J7<6y3&YY54@-!Sub&%lu5+jTxdw~2%u+**fxopWW6Na z-`tW4R4$;)Gapp^d6SRi!WIq&-HajYwXt*DC2c81qJaW-Zd^l(vW_jGx+7jeKjFB5 z36~M;%3g!Eek7yn2K5x4Q%s1y!j5YrGx-q;GONVIMoYzRQeY+?429&c!|)S=b7VhhB+`u-qY7)` zY}?Q8a8%-)Aah-6%nqpYgFQid`246dF}SFi^3h_RszWyR%v@oC3tKb*dNFPL_uIw*;ti2b zvvT&n)2q(ffWEMdTRmBe1tz7(yh#vLt~7SW&{E0j4HVF@#<+-!Ywp&w#p zLPk?KF%?jK=Vh@_r_hdIKt=)-gb&&-hPeXUVnD^ z+H3~)^2e$4q(zj`vR=!x>^p0yg9buJGR$nL`Gl)DqPR zafqG7b_F7sI#(#L9P>7Vb3J;S7aKYsKP*b&wk_$3+z=_wKgy!!xqp=F@SEG|QZ%bw z|J1B|Z(84Q}qF*@z zPF!zG1aF>yn)oW>lMqQ#yVM8K@VT<aaTfUZ(s zuOMwnmZYqST9zge9fTO-laS0QvDJ$^ENJF%Di+@q@99NAV4*?e7O-`ZGX(tZ@KSb_ zniJ4=pMF@-18aN7^PJ?(%Z+daCE( zyL`La5tO&d+1TQ1-=fR$qOIIuPE*!}N_lWC`sE$FGGyvPFryNjN03Qqf+SS6mf7_% z`vLDR0mSh)IQ7qbj=#sL{}F-z1E>Boi{gL9secNV{u`(M7kvEkulnD-to{+gWdB=> zsV|ePe~2&_uq|zHe%-Wr4|q|w`V*&T?$lSk_gDk7m<6ynp8-Wf4KJ=B+9%V+YXkd%rtAVuhk0GbTZqA@Rlff|xD}1nDSuf)qS5PSzk{awE^m z-xqh7Cn9RYuz&@TE14G zCUJ8(K$bT6`6Omda$2vc!j9Gpc3BII!s7P7*5xWGbMWIfWdX{*knUh6*y!9Fv>vyp^7rzg! zXrg@YNjG&ru>wd;Rm)w#cEeZte)D|4!v4+2i*0c97(YCLj;13xk2nvoqj zF6j|3FrxE%v-F@t_(Vr>$O*rh7$tu)sbOh$mIk8pHT+nR#^iLCJ4L#tw-8E}i*M{3 zp~F-VQ6M}Ol3-_SkAWe>-P-!AvE?BrG4z*6i*VxFesscfA1AS|4v|%huh)-^-#xf(;#?tlNjq`30uM30C{ymI|gnesE#nm@qKo zIw+v}@(}|`Daq=H6NGS$dLtVpgZaKA8$3mike@jlN;OQnLiYjbsFC!~31K_keBBu2 z&5CbCtA!j(=)fpo-o=)cFU66Fd9UwJsKUX-2x)XKGC-v#a3V~Ybx{)IcByhC>AZpY zmJ^!FDfonJYx4z5m3HD)4l8rRuJWiJQe#5eIT!dCT-rxM7p);|yQ-60VO#_XIUX3)|CVDQ*r)J+ZZ0zVTl&>Adg2wQkh2q*MMFA`ws*p4IPG& z)RgG)Im)vdtt3tK5xM^2EICny70w>%GC}8TzT`EbFnl8Gs zP|B?>6!qoGn&Pv;fuwK?UE)-g5>zu_6w1O(l@#V(O<;p7c*d+4h|0{$eu*ND=1Ua& zip<4vPg*2V*pFrh8){<@w|$6ecYiWfcf>Xarmz2wkAm$C0!vU(Hq)yl?4*W;n)AI+ z6c65rjT9PEx*(Vl?@(5zS0Ty2FJ>)ulk}G2o39{^tK6?!rr{2R9EValU|K3IS7SH97)l;PlI_VT#LF1*d?($#>s+MEa-{5V zJA`yI22{}?h%}zd+^KAmt`*QpH8i($EOxf4^nK7|tJp5$(vz|TGeA_|J(D9r&~ z)h&u(g1Qb6K6Eb;^(G<7y6xzQ>efY~#}!O}ab&jLShyt2cV-el_I)x3Yr+I#eiLTZr&az6U0>m+cXo6XeQvq=I(^%rEny7z` za80hsC&1Tg;_AeXgTiVZmECr~p|azVK0{r&UsxIU1%tD3z)nd)`B{#kh3|8lA{AEt zH;RxxBz=Fb&QQ=LJ#j0Uaee-Nfn5xhV#WGYEOu$3i+q?83SBwjM7j@g_fT0PA!oL8 z!X8hv+}iU8-VNO4kkcirrS%V8*|m&Bctu^bs9!&B*1jgEs#UXYctEX}@e=p(`r>Ja zi*i0L=Xpa6$ML=xFNNRjy&99wckq*$*9~^4zsVTE;_=qJSC8V8fq&+aA1lCF;J%A1Y_HANJl?f(SRWfDIFRxg^vyzu&Mv9 zfv`0)R3FZw3bCRQF?3MsXT}sYHYCJ`3VV%uk&AS-pRr`1W|xPtMjiGNUXHS}uQjCa zc2!0W4wIa1>4g+U`<`VeT5So%g`^$q3TX?0;LHXeXqyuvC>SvytOYX*O(vui ztj81{-tU^tZr0TuO+2`z6sc8V*YXZVfbR@yXBz1ldn25VxmvOHZ&N#gwwh!Pso(R; zg|0ISmr&KfEJT>Hkkaf|6Ig=kdcW17kjOtO&pzy6JYN8{OaZj0z$^59NkKV6#N=XL zPJr1zcP{N&58i7y8cw@#sp9Ehz%R zH@r~ZXrpWNRYp*RER52KH}J2aVEo%pV=cA6@-Ya!RYLLdZA?TsG6}uNd>t-K1RO^` z$wYq`eRXB1j%pFo_7hq_>{D0uI%PboSFZ_+C1CnujwY=-`O|gO;~`Y`>Gs9q_*rF7 zMD5aN$BqByy5iLa6sxZi;)dK)H|wIz<-=D~tq!p5XB(C)Q_0ecmpHVM3lrVsBz{l+4!}h5;tLe#Sn?TFQ72RI)Jo(+=E1 zpJMkK^Akff0IG$qE-8JuP?Bg2mr!C~)NjnFSOdSMEsN<0EBDqDk><;bBfm22 zU!k-ALQk=|pJaOr^XWovy{c*?IYEVXb8)Cow{>%Jvv;EDip?|e?%>d*Q^W7ny4IxG zoPTrd3n+A?f9N|{c~~)E)MfZ3sv62kt`!0n5OL8<0Qm_nhRi(muMC3yPl5g4GKjzM z`2SG#u>Uj1sefS*e_i*lk?#Nh4B~H{puTDu{!<3=eIsG*uS$V=-z+Q$`@sRHvw7yN znfAzJc`uCP)0*IU!d-@HMRX)iCuKihE)4{s5^cE#T+CO=cMU;l(Av7*eK)n*pHDU0 zhBc~!bhNZ+o9o7HYp2ung-jwM9(J!r24otwN~Oups??z})^*WHz4;$m)^&E&NcvC&pLjuzs*ol0dljG>OJdZ!iR9xpvf>Bl#{ayqC%dNj$^Q1>abW&t!%@^ zPJRU)^?ksQO4kj@N`KB>{jO`pJspd}jvbkveJWeN&n~{-eL^9{E7|Z3Wp{#ae}K9kvaHja?dzISq%z!_o;>uM8HaWYi!hNqnPgLi(Z8+`UCxnZ>N7-xF< zp>ro1aEp6>wCq*7qxiUWF%A6THLu*JgNs>Sg>pF7wu*#T_tko1`boE~>>FindSO}u z7Zl+XGNquMiDZ7*kCLj(;O&$NR&7Nw!zcC!Gk*`%<=x?;E;&w}Ahi&?##W6bmj`z> ztDpGU2SwzVWpGvJ(N=cK8P3pbVA8}TWTuk-i9vdbb_T!BB{N@7HS4Eo*k`$>5yy?t zCI^%+ZHP(B5YkbUOb}z=h$nbZj{wt*7Aa!m3tk-Cr3W4PCi<{&Q2WSq=S+8FN&o|Z zyeI211Mm%D4ojb-I8caQ0(7ZFEGP8b0e{E(zwva48%iCf&1HmLs_B5J^;o0>T1~;H z-wq235+vi}u&hVJm0=vkn^}oGB7HZ|+P4|{R!;-mt5P$%h^-b#{8dNKUhAUo#v&LK zJM_b?>gssYEG)osZ%C?A#3T*H1aNQwMM0-gJCIUrPXa*AL&o6->Q>|$9`@+j1tbR~2v>%KosYPqdTG)lHPcg+16`=} zNenZ!+~NqILR>cqqGCUnebx(3KWW)}3w zDGJG%C*pJ_L)y6%!wUvnvpx^=aL(wwG=BHnlM$FSb-wQoA}g}c73%e{_zjm8nSe5Y zA!pn>&W>49uZ{qy0RS%S1^qg#NRsTgH?Al>&TpS&BxYPbAfqamwLJXIJuQXN)z@u5 z3!9T-q(*ThCGqrF_;m~iC#~XQ5T^mex`!qcPr`IWvrbe9DiNrHAqaZ4AnoZ+H8Q0_ z!>5d>O4_BokF`xaKo$JRJyGujp>l-+pe559Hg|mPPMnoe={6T8U|8XPGvEz* z2_gC!WY^yxr-r0Z?2x3Nk?RsQi$%R%p=SsrG~efj;j-^+H&rf$X7+F%SI`z!V^|pa zBnry7=}YlS3zz8!x`%WoZ$SvEFw6}haj90`_AsriN73Gl3e6b$!FT7E}y=N za5EJYorV%qv)2Uy+oiJpvW>-Pn4(9UZ0H#)Bu&)bw22ZBL&&8IwyXv_I2$1Mp1(+^ z(FDIGiOxo9+#dsw7s#Ajgja~aLn;VXAs8@09G0r58oEWUGJjMU{x+_BBh}uMr@u_k z5NVi$wLT_nJB}Z+muSZ^N2NZlhVnbvajY~WKo+`|ik(hev4Qu>GNsl zbi9o8H?5?XYX<21XXK2wHmfSY z{a}CR%m0lKVpbqmxQftnkdUN=iqQ_{8_9BqaYQe35`Jb;QCD8L{vvNjg){4_`?;&B z?4?!$huWjXP_0Z2<$WK9Bo2ltF0fa?@Js)pw4%((r@O{5k`5Wi01P|_cgBwTcHcvG ztHuIOI}n{x^}E*-n8Ge;6x<%mg5gG6z;H=pae0WdLbA%%Yfhs#ACgs@8;^8_P&*x% zXKbuN@sH__(^cBWeMyDAixB)$1#dcbVq7=ZxNDev|CISEwuh#{c;2K;QK4#@>1I;y zn)&@zF2pfm#lu|DP1p5*~atjZeVGycq0&Oh1?{M^zhFxkah`+YzpQH_9pYJI<2FS2M^`& zx(<;Ar;CiBaa*DxwN-S=C{y>Z+SFe<$sCFII0x9QpsT%cV|_G7dlq=TZadxXrxbiU zcCh0Wr}X)u_Z}yV2OT#&;MF z(hsDx?T$O+B!14g%~^T+s)pGZ!zOrs{|r^~lLy4jc$^kl3}+kl7DMXHmu)P2oT!3m ze;n&o;VbQx+>!gR&xGb+1y5d8GHkzOFX}6_hQC-zXNf-`kh!M|w=qUd;q^&X2P;4v z7{o?{*A)ZyOtv?bJ)R9$dr?937RYsENa%bSzjr5W_1cesZGX)$=*`FMdPvomVwAZ% z1EeRf4f&i!o+Tc~_u0Y!&Fi)23=YJ_HI;x){boMW#1lbKV3>)XuLJLMrQ55KIe>-x zGe;%8zTzb=aK*c)d_Wkop4WV0);Ix&DaTVaKXc25u5RuS#v9&{c(MUUD!5jXu6e2t z0M3%KIwQ0+Z%+0ht(t6isXaZj=2zeJgNF5?#N*?#SEiv2qwrYiPrOi4RoiI@R|F@j zQ1#{|lB&4t0d{oy4`3fp&BVV!!hedp{~ihdizO8MKeL4TS0wzWzU04S>3`_k{}68c znQZ$%bRK`mLjG5MJH6OfRdB|?Br5-`(gXXSTMPdo^kC%p^0NAeAo@a6#s-@mq2oyH zCp+XY)7wXAoG=!P05(ZTuP<~1FU9RDnuSzwVZV%zSMXR;@_Lc8xm%IAgj^kog~a5z z#~p|8r{~A{fF>`)us9X?k=kEws&Iw!p-hY%T{v%?Z%)pi=B%R_hJ9_GEjYSI1zl4< z9yiGdS1F1F=JxLA2qYp`mfypoG8QJf!+$z}F_&USSq$ExL*av#FaApAtKwyGWr+pU%V2$UjQ2X?mtIA?Zb6bks9lIGC&=p1UEkW=fq1)nnVr#leJ$DI2^$ z#CU?a4B_hi?omt@=cdP-zIb?3xp%k|im<3&-Q}hl*)8|jR`Hqznt&miF$IB!#8Wu7 zk-gJoeb`4qtPV?01TiNr{AQf(1f{nOu;45691gkM^rV8zi~&i6Yw|o|SPY42fk0-` zVU2f}0)$OvDO@|a81fUehJjl|ZUSf(s9_BVhQL6^SBBFXjoB|RKZ}h*Z@DhmsL1Au zXig9hSQx#cXX$a00zZ3#D3omR+F~2l+K*MjpH(izDJQzLFP)^@9eGRpQrz!Blv#*C zoiN9L4Te_urX&@ffe2$4_!igX^jhaQfgpQ7h_<~Osl6L{M1|Y_0I)@|B9^K}C5^@Y zA{Xu5(SAcdViUQMB{fJWS|MhCk&oGdxa}GR*s3l_;~+!^>_m*)L<4CP}u92I?Mx1&3=54W)uiq~SC`_a3}Y3!jnfeIKk zr$nZVI;@zFuC<;4)E-AVH4!+(TYE+wZC~>OREoF^5~`rvFZ3r*QW%WRlPsi%8|ESdBui53ik7NVzaJ0YjV*5g zjgsukscO;rl1u|Sp5jZa`q3r6p$R;}*RigA3*=+W^(nCSrU%VN%XLAclBgfp)Q*1h zzRE6C6!6dx3f6!9Jcz}k3vo;$os>KowcYWJlgS<9qdjU2 zzS`5dl88^A5q}5^-gV`GhNvd8vdJ9@%$RFT36xxm9O@qs(Q$}UYI@~}s&IZmwX4&n zL{rI~G@rRUw48|qE`-gQ=*)RQEk&rx_&lR?tA~X-$xRY}3XNP>y~ZGsqVGH)QpmKU zpu6NJ`e3hj;twa~8@&R^)pJOkR+exP&6IX?Z6%=MDtwM%EsQ6%^?EW-L=a`Kq!{5k zPkU(C+~?6hAFl|VM=nQ8OXz{ff117;HI-632rUW){+S~j=zUYQQ(lcU}9!xl7BpB+%6|x;xUTvlMn%&D(t#!r@uO>`gZJ!PH6PlcvlVlM*4j9VY zRK^`pFNW`3ZXzpJ+3)rr=hWp0Ij(<$P5#__|9fomFJ>X^|I94pU$M!*UH7k1x<9bV z{}qt@z3}wE96!FarvHUg{*e@b279&V&L?9Lk64g z+#OlZ1(94GCKi;A;-h6Z0(`sdYQ&X%{_@O2T21g#0Q zq`YLJ$I-~#PMS!m!RoYKp*fc(LcbFKoyWH#Afo6On6?`maU(2$#KkglH*L=N9Xb?6 zt}NKa7f@&%{Y=8jCd>CG{ulwKjp#lcqt0AOa+~#oi>@f;%}X0UbCOyZw$*CBR2()c zrDs}_EA(zgGEVt!BP@M_Ux6-mD^$Gk7yh?DT_HqCicCkpX_4e0GkNpsB9!J2#t~7? zlVa=Ti1v6`*ek&l!dnnACKyJ7e|I+w)e{Ec3CCRM)(JZwl2u1=jW?3TdP@Z@jer?` zJ>(+tjzUrE@iz_2@u_>S34MO?74xqz;l`5A=ay#0tYk(hQDXiUcz(x?0t6gR%YVfK zh>buII1r23-jytZl6p&GR6~g~S@6sMg|n^zg2eERKgiUmxgj9@$Ng*4aNIt{yWNl8MH@%)E9DMtkEm3-kujdB z&X`=Dpvm&ti1Am|YIycW>U8+6TPvtfN8{#QYDbeL<2Fb3^L=rINg6>5o2k>nr}fBe zVynkRTO&^Ct2g>Eq)@DlSsDg%6MbQ4B5GKYI~0n8Gpm`2FHCK?FyaZ&1r&ECwinIE zG33%+A6Q+S>L=AMHI}SKOc*vN2pqHs98GWn+_MN>JpgEb zMdv;`7)Mvpmc7n)SxyWvL<*~}xzEwSMj`noUAB&{RsC!_B#y6h<$uEV*WD1_u(o-h z0B43%Z);|iy=_1CX`AUpG4hFwoTK>#!Et9?=)8iW6H9#*EUQdoen+|tZiVAH^COKM zA@hA3?9I>bTGe_RE;QXe>a7JkGdYM)s$=S-0H`VQy5)(MPSgOQn`b0>to_GC=An7U zXX{Cj&FP@S1X8Lf^T9n>*`zLzd0A%QIJa?D<+@g|v4gg|$jHW&v%}f`^c~0iti#%Y zWo|%F-RO9MxqV8K82sUiEft2wqOnH9B;7f6REZ|KO6_E1)JY;xwFz_vnmQ`VzIn|A zGF%i}dA9&j@m`{mi*}k?E@HFK)eX}2;HY;*2A1tyw68g?e7OQ)51vidKs^b4L}P8g zXHcdtkmDr|ay#Ca1tK(6tZc_hsuh?*4LlJ*$k{{Y%syI^_C{Y~ECN72n%sazLee2S za}y+r&6-!&5L>O@DmfazJ7eS>5n#77kg$gQ@AoCoIH2A*5;PscR6FN`)6Ueo)@uLO z8+gXZL2*bR?s%hyefh|4q(y|h9e_Mf-ztN(!^8=S>!D6@ccgdIfy%2xpnX?8j zzE0{~r=J^@TU?P>gv}Rq#SU-~hWJnb>0X`s7%9K4 zNH#a}?MKu+BbIsxR^f-Io4F0fneEag!a8aZ`%ywb5yama&f+-H%0)1PX%av&BBg?+ zFDFBCn3st~D-DFZ*(z>Af=^x%b>7NClAkeEKbfk_OaG9?Q{SwVx~X`t($XR!n>$2( zqwu^1G8C)4Bw!5nWGfTki3XtQA@d=vy<8ez3ou#%^J2D3NMUobzz_fS)Sqn}sJ~OB z)X`g$&Jcn{QlvH{*d4-qH*@0DYqAcn5QNz0a?b=SVx!v zTxQwC4YHR14RR?2?&5WH36W4~c@a^9vdYTMZ_?-={PNbQme)YGCEZgya90aBvA#D< z)%9H>JrYm}A8^A>xSEkaPnMZ7{6I8%j)C#kkO2oGs;9&5jb#gCUZ-zr@~8N}g~o(a zhj^xBU27kBs>$xQ?VjCgv*mqZ;z>56vigZ3Py2fI0ZzMA+-IwRAA-J_AwX{~_>v_8 zfP6c@{4L@ks){4GcO%e|pGn|cCdgz%{STq1nB94En8P5?aX656z=aeLo;OT@l#1qd z<8AV_FYc6}b9~-nu`Trt|Mq@zm@n-{*wIt5hlLqwr28F1)86be}+yqI@=aoE(v-O zNcQQZ#L}|kH!8e(grdM{ofF*!Aa&Bo9c3wIasLpg-B4C8x`ZMZWDb`KZn;K4*|u9t zlbm+du;RCR>D5SimMT;vmKi7aslHohG;~4O1umAgSvk6`VWMdur5WHGFb;UXra5_pgL8Iyh_i7 z_K-lCEBY!MbkW{|%hrTE;@aLf!D(+lhJZDrs8z;YSD%IV~K0T%XPS%qQ9h%zudFsN2>c$?NzL_{;PTi zh?Y&sT_?=OFP}7jkWmq*aE2m0fCfy@o3GvaPvDkx2teR2F53H(pk$@2Bs{}gs=X(X)umE)wh**$B| z^Q5ll=V}wv{JEbmq(t&IS49-HKy@gH|G-5x1W(jAiS`-E*k=!Y=# zr)#t0`S9DCL%(^IhszT$87*VvQv*{V^gduEP+a$L1Y>58Lh&`W1b=^zkJ^1X+{_BA~?*zA|7e>|Z&yLrV417%L ziEwJsNCjT3!@HR2LM9u@NCVLT-Jkh!)*!WFXg~PaxD`aWHBJLmmOS}$qz{{;w|=ja zoM3Pt!!{cRLakvlh-HqFKH_D(!|@|CrA_^&k?3=xV!sY=<>u93~$@n&u8`0kK{Nj47WPmyNKY*MyZmgS1lP;T>K(O0H)FqaC5bqF zg!#hKkWCYH?b1qxPjB8>#xqMZ#8JcyrJ6W#ZFj{NyKPMzL_Ho&UrIS5jzKmNX<*(} z8Uo68qz_r8DFN#zoJB5OC0G=n-n*xv%`4!LV}dbzH=}n(-b;|zOg&?w5KB^&_|D%*={6Um|aC<29RLcpZUFMjP}E$dfbaf*%1xRzO$72nQMlgTXJLPgCi{ z!E8P%fvYTGWb|i`Wku^SwpP@17!c^zW2wPI!_Yt;TkVeiOR_8Vg6rjZfUP3tuF_auI+MIvaLNIPmmAcHet0GTd!$G;?_3 zRtUMAd}ouE@|Bft(rOdLIWXzu{DPL!DO8eBFHK#0HpivI34@m~aR*qS&>>Kt;h(9l!m|U8(k?D)#IBm0Pmqt$^8&xp;0E zL)l>EE@8`!epgi*g0KVl3VdM8lQOECzb;Fy5%k0cKE%J#Q(AzVsTWQGysimQ4E4x~ zlSvb{o?sYDf6M5?sa~5Bgt{_PKXO?^L@z`l2TpxEr+QY~gPp|6VL1#ihOVa*rY9W{+&TN0OFwvP!Pi1FON`%z9_hg(*B_ zCn{;Nq|#$$20Fk&T%tyU+yb3^{6RuyG-r2>gIcbwbY9itKLoQaWho5e!C$N~=&RuO zF7z>Mp6Xj*Pb!Dz+RBp&ZIZcAUXm2hr{p9$rRA){@bXkW@?kFIWn3Ga+a zo2p>>29kPBBQ|}o(}IbU%x%9DEo>rNwgW`jM~MMnS~1}ss_3kz?RTVn!^$?A8x1t)kUSZO%tXmP5K8!~mWEb)Y z$HQU>y#t-8fC?)HTinI~^TSWlRC$Vlo&!cV6e-FM+Pnw%AC-RzxzpB+l zwTx!yDQ|SBKhDctKUZP=PP4D(D_$Jzw6z-ohhO~cifY{%MG%It&1*Dweol8dCM3FL z#^}HM@ATN4wevw68E7B76lIx_cL{+Gt(#(lWaAkyngx zc{5Wu3NHeRS8VE~0F>UD%ldpx-O9P;67E#Le_ zB{{`RTQ&h(bs=H796&dGIVY1#{(UPv8hQvBk?MwN3mlNPj{#D{t9#8 zf?1=%)f@i_uRfCV-YOfhs>5KdK}x^p$obvq1!d3=!>IncMf%+m>G@Q+8IXxwkVGiO zNJtPPTs@^EOW`2YH-||y0iUfNd3|bfG}9I4&RbCN?)5rtVsJ%?O$VMlk1&<;?R289 z1$I88k%H%H%f4qQGFUV8)iPaKMe@F#T-Ip|#4l}Tm%)*UdTZ@KD8OsTRtePg{Y^9= z&`1yjNSuj{{)~ZRT%sLMMsMt!d@PO~$RKliWnY>$RD$xc)S~nIvJk8G)7mzK4O|x@ zl@L;|;=~b5U45ji<1UWK58cs2Ifb>^JaK!q>0HgJ2$7>ZBJa|`BSBLr?)bRrn4~Xf z;uUO&oHKp5$&yry9_1nf&EjxfEKcEe4bp;yH1;_tbo!wM-o zI$5#5^GtRe(%hL&Uvf))Nr|Y#I#+7uGp-*kT#J^rzLKbNulPhHhzfiy*Ot_63}-l~ zyN;pU=?dOmaW)EI6H_Z+4kr@;zk#mmOf-2pW$R`gIoM~Lj%0ZOPTsK$pp`gh-@b6l zy}*P|ae`j$!Fk-=Q5%V%jQ?f|0S>3PF^mSO*H-iA%4%1T!S9?OE$7wCwb0XZKItF( zDO5xI5>6HP<&x1;n8eD;JPWk7Uvc*+;MI5!vKgpcPg9a^9M+v7uzhn#wnX!*<#6Hp zt58`adIpK*F^12t?25V}NHmB@1~sjH$DJEnOg?N#lVgUA0SwQg`0inncMeH>wVl<^ zDOv9zR%kI&2kE2?679e}57$69XU}+ais!VVm-==Z!ek>5`GO1CdgV}CSlPREXa5kP zB2v@(11j9Zy3DPiX)q#K{k1bWsjN*gDc0uF$VfYEwUMp*&xbpA)b*3ME>Dmke2k5G zVof7^%>F`rL3lAtJih-!+dD>CvbE`=S(%l#ZJU+0ZQHhO8D<#%0 z^d$H>lS6K^@u*R;0Fy1eXdq1N_M`G_bUyO{x2nPX4F>*ed-iY3t^b0E{|y7P{xkVM z>wor;|4aV=uW|oZ<<|dyG4S8Ce;HWV{xOI0LQ^7P{X0!_x_T$BtQM{V_w3<2uHAxC ztTlep@+EdZC(aah+&%K)dgbk`854k5-k-=^INqerA)bsMVCDGp^-MTmTSv?DX~;O5 zb<)ZCf!lx|F5jvs5nr?9+&uOpOD1C7jGl4`+xpJUMqBzjwEZ_zcE{Db+ru9h8?^EV zU8-5m{N3zqfq+-Aa5{^!Hy>FcL@zM?sERdDv4`Buiick9p1_7tp5#Gn={mGP@JHht zM*3i8K};p5TWbe6;V`>A^BHWJqWrCzcbmnhBH2BnF;>$XvsuhNm85A>JHW=v_6a)u z!jZP?24$sbeudjuL9+xW>RjVuO()3KGA?^$r`92ELoMq-^=5McHT$lqx<)&+pl)`; zbMqg-vyv?P(}I<8LB-0Aai)2MQmi`W^RVgiAk@LM@uI}bCYCPXDZ1$ul+g4udE;ny z6jif6#s|*=#gu^~M=ZeJaW54t6nip4xWD#{HNDjb(o2F|%dtYHpK`>ot#5@w4*IoC z10WCcNQRlgTkTIn13`5>wq9?0BwPPbmf9sAgDPs!cS<}F>sgxV_3LLH7mTM802cN` z*Gm6ls;?D|SH0v76;!VLY-B6I7f-ENI#gYm@q1Z)Uo5hw6G*9hu24)X>~IvW3{)?WR zN1$LgN3n6yBXx#Cah6yUIvh3(9~ln=v>|t`QE<0xH{iEcv*P0$z@sqgWU+ym8{j2V z*5y^N{T6;!CzNX_fMB6N?Z$Xx6cWMpXGU7*JVSXSThu72WmeW|)ay$m$+g)x9dD)g zvt;dx9zJOhoT`Q!RaFlaba@dgmBJ`W-0s`~bwsns+bFpby+##4XQKPNK;-gXVI30wvm?WcH-ihS| zNl>^mG?I~)clBPp94{|~3mTQJ5REo58-Xw_?^vn2Jw}#05uNuzK(kRlsH>;jPfQN^ z9jv_i%3jRS*_54LgYt2&s{J1nRMUZ6?|7}2lfXSb`v|gb=KM)?)am99J@%LVKY&y=dJl7AOsdhieV-hj2p zgZX2U`JfpJ#scISZW8X7Zu=*UpkxSg6HCYU1R2=IKa_xv#wfTO3{4gTCLCWvV`X9Y z))Trq{{&?P91e@$!;j9PcJY*S^`TkdgwkZLIZ$NF$y^899%;^^L+kL7KBdAjg`7(h ziD=l<6fJ+mzu@Dg>>{6`5NMc*Nwv#PY|g?#-tTu{C>9DLHSspqi0d_qf39Ctet|7r zNDCnKUJx{kkgixIkw8fP1>=aW;3SP0W~?IOS9$qGi|d?CnY4=F5GiUqow3@qrrBGdc0}r?xG^kU&zf; z&l3l0LUqws%R8Onx3cY_QMhRA&_}^L4Xl;64QWcMRbt!^{1w2!mO0r!Xi1OpFa*>= zr+RbZv(XthL`2$me3aRsa8+P6awU{E_1gl#KsQg7!l=*_N%Or_`1q?^^Ifs)^~B*O zU)7yMr(1X^p^zuB(LpRQe9Cj7Up%)uvufs>XI>qPx|_#?zDaYaI#1IuhFaTzZXGyh z{A{(=j)St<+wgu)c{aTJ2u6$2@8-rq^>!obYtyOx2_*$OSiwVG{lTsXlxP6U-Jqrx z#cxcI!k|ontn)f}!HFdLR#xc#9c7cfK6A9tPO78F1sQc#Pr285hUc#+_lww=78W(E z52fA;_QXD-kgW#ciAP@>JBh2KD~nDV;$r@=0-SLz&fgs)S+5<{>$7x2~RL14?(ylbta#Msh0JddiOa|sZ(yhp`Tm;pf zXz92k+_GUv*E2_0l^>q72xG`qjVZ7I{b{{B41yz%)UfQf7^G$i96VGT&k3vgMYF0o zzP)nQWa0yYE^5-y5_GHZg0wjMB(?`}L2TT75LeqvKIOCtKymNDHkOip~~qnkrdMsM9Ku%q3Uj_**R zH`p@F^e3xQL0>fLTsvF|vKpr!<~&QDG3rq#M#xVH;APswOR+=bLSQl_sh5B_7 zkU(ia?Wo?(Ez-}-(N7l*>{Os-*bo$*Y;E=w5 z*i8q^J6&qhUAkP0V8SD3)0jzW?6kjzgka#6t7G=TZeTah7Od9mL{jP06JwN3;C0j= zRVYOnax`0b+5~X4pI3>UjS5RKEzJqtST-26Ynd8_8fxEqzMb7-yur`iD{Ed^BV1x9 zM4Y!OEEpBwOql5n7P(qXeeg)^nQwg#On0yj^Srk`XsrJ!+He*|JWk4D`4$&_dumR~ z)ljL5+)7Ew4HuH+pJ#f?VcsL6$|Zbb@U1{Yb@8&K(6kp4c{y?Flb-VXtnwX8tuzap zmKn{fCO6Nh9&yF3XQRsz_*>eQSo;=;+~3BW=X zg|`%F#+-p51SA7Lf_vJqU@H+`q2L0FGsq@}aI$}B@b2lW7qra}R1xIb0j~2}SZRSH zBrNBM!6!NzJ!|E^h);T@dl^h3r((BdhKDqf;* z0rrb@@P87ePS|)TT#pXYy{}bY?d({6$k3zy45X>G0mUp@^}@H}icHAa3N{SJ1!O|qnuG4XuR+%PAKauU zTqg}L@9E)UpN9`%6aKz&h-+lLph8>pjNohFqzzmC5|-YEtvIoUVQYon>v!&HcDelZAD&3`Nmlx_&28syts zpmo6(NX_Lry!Zu>uy3yOH;ae=k*mS_Z(I%5f5z4L_r=5i8CTex*dBO}aa?0U@a2V{cS#uiwe_Wi&D zjU^^VCQyqe(opjDG6~-Bn7z1-CfER>hN5k4-)KFUusuxOt?>5x2`TlZ`$L#AvgUe$ z9TjC5HAcH@E&{RbWs$%9_xql5u=b2kzPw|^-QYIv$Hi05px?}$wtSOMr`4D_?oKz1*c1s)J1@D4h-1n9r>2ST? z-I0?3k;T+Tj8+m+NPHDZc12xWs$*_Er8wckd=;$~x&+=4P0;51P+-=T^T%?Vj{3{Ddgrk&_GtpDTr zD8b#%&Dy{eUoxQEd=Eq@feLQ|`n-#MmSj@fJ0RJc&(Iq^|6EF-76s995pPKu7H-(6 zK$P^p6zsYa-^KH0%GY8>paYcfJORg|gYaheoK*N#3kAZ~m6spgZ=zs1r$)NG+E56C zmJD?NGb-u_&sE;_Ne7W8|AE43oFHSEn^?>KZ$|R&Mq)8n`KLbUvVA|t# zk3AJT#I#EZZcKXcoVP+*JoJO4gc)^VE4C?`c^+!T_d}4X$a<}wUrf15ywUS5b_2}{ zOVX{IO)vl|28J-qp+5-M`#>W1JyO&Ec-|y?I&<9wkd*1ZugRQ#%awYe+z;>>-%3Ov z@FejyB%tnQXBa>joCcUJpeExMtfqG2%v|7}YFudGD!{cMmPB*&bb2XaUlKnuFgc*; z+mYswwRvg6A)=-9!Fo(oCbAOYk&rzGwTYBbGn)6WJW+Yn#T3!@0szk#L;$78K+tgR z_Tus#`j-nJC$a_P=Ly*$Lj0*%qxzt%f_)Bxld_A2#5b-B+M1y{f4+e=^SdQw+Fb*d zXBe}?><7d21K-FbvHQCkQoB;}X(J|8!{;U8{$frSqSVigIC`mw?5GUwnbmKeA@={i zl<+M%o>b!KR}sFwU}t%-`o|+%oBND=dUbL%>Xdyo`X4R$D1v{2V^n3dP=2qXAZ@>e zW`-E^vFWuV>j-=xDjRZ@K%i3pXr2n%6wm7u!bJ9;)|4C=6f|EsWg7tsWk>L6<`nsv zP+ zftCf&fjuXmSyN@kRL8iK7+tL_of$jD%rqAI`v+`2gPJ!U0-7!z5@EUHt)(Lv)8@#H zC>#inp=B?WzhP!_3mmp_Kvo$Dc4u7^rMv}++%5}=d%5g0^u!gB9HPH1>#XNEgl#`6 z;wx63x_{7g@ou1tM7K|-!D{`+`;b(U?gU*h#;crU={p(y2e8NL?6x>lMjzEk4RNMi zzhXlNr`C)FWZO^HI|d+`z;=1GNg@gcLQIs}0bO4#&p{@5yOV~ZZKgf%38AXJVIZV+ zWXp|C-se*A0O6`hf1MM6SdXlQK;B-i4WN3Wld}roGj{kUr#{opT*N0j)wHMvps@9I z(6gU@+7&b=*kCJ~6?nJiG1U5UmR&nlo?_f0FTz_8D@+0s_~7I}2tY z^$#DUEL*w+w}a~w@!2@X^J~)l(daEs_Lr$H@aYqSm5~I3?su`@=d?j?UgPD7)IyIj zMnFys(4 zU#IuU%7)yJ3}Ginx03ISCQ7kl_Fvx`DM{@;@t0`}eHxuV!Zf=RKA-G8DTgImy(vFv zSv3=&*pdcDO$lu$iR^V>%zq&ydO2y1PN9XJxodDQqd6Dq5ja&JLftB zBGKOmea|xr#C&F6@R?c5UFSJ&|4bA}@2=QC7OnOqA1wBU8!&c#0XYx5Eyt3||q za^sPUJYhdy9uhj5z0%U_t|qUuMz*asI7U^kew;YC2hgRvA6kuI3@r((ZK66g#+QW3 zD4^*{tOO;|H;H+K?^pZ@KUT*2nN)L)(UM%6*SVuFF6)3 z@#QOHdtcK=s66YoXOo0$J>&$+#y+Z__jJyjuDUx+$SE2K4oO!?>g45OxYxJimwpBw z<^8G7-|>Wszr3HLN;t6sd1s9OOEN8K()>&2sIOEr6?r^*Hwa7T?lXJ;Fn_@uyzSbL znr1cU>Y0~oRbd}4U;lTc%UEkwPF1R)ka8BC423JkA0P{C9HgZmW=~}lXWh6<=)>sw zG%f3rc?4*vN__}R_`vMS0vQ{8yQfgfVm-UCbzzg-1jO*Y44YW_)rvQP=jQqm<>-Xr zozBIP4`T)@aI2DeeH!C`!Vi9>`TgFmS`sX+5F|8{?PnP=&Jg`NxeZ?sz7fVo zzL8DL1P|XUp;`UDTO-ju9^%AMOtNaIj2sb$*E0iOxt)V=Cqfde6c+|pbY$Bqyql7F zBr4302Eb%f*7Q;p!B*%ZL`B?q(arJgsQ~)wC%VomEgzo?B&kl7tA0^_Ng&Qa65lUB zh~B{$gW6_#Y6$w*nn+DH^Iao8i^M#pnEd2ruIK@7>;a+uXGPN$QUd_fe=D z*YtTNpI2(Acti}D~^vbY^lS*AK|M3cCxl%!ukQFeYwRdQ}aczC_{ByJ1$~G+kabodF_Cwf-*o2#f zd|;J=dLgTzZTd;pRF3WVPWgM*${)n<*J>~J3CuI#HsJ*19XH-jeDQICU=Wg*<6xT+ z%gw_7L0Ub`BV^4Sv}Fr0laufi=-Gb*iho!KBG=37r^f9{3~A~!X3VZikMQGdRk{}I z3S;cXy=%sFzSSUh{7LK*M6X?0aF^Rp0dap`^^^<1Q8{Us4&fHRqcmoCGuMc)MN<|s zcURkEp}9!u*sIHR3GYLl)`hxh6RpMPpRI{ok;uV^!;D26jW6Ax+7!fW?^iMgU$cw6 zut%?(o4lM~40X19Ug5r+PpT)-XHM~jpn&#I%5|yW&@%aGT&~=xy<}MgoumvJR=m`^ z|8zzRO`7JUPJ>iue;dSzwdb=1{Yn>`xWjD$^lH%1`teJ!7|_`WB27&3a1i;}Ag<;j zyaeAhsB1j**Y_W6BxI=*IE>XfI1GNQ0hpH0VUSqhj{E1tI5&~=XKHfvlj>+m940}& zs6Juy1>>LAHGktnK6EnOr?dLA^m-Pa`cdY9FG6$+2;;2IU8(W(`SQE@e4rNz3`bV3 zmp~CaeE3W)?aX}>?Yq^@h0NmZo0ECZv*+8ri}v*V^m>Wa9uhBnGI0u#OW%$xHQG!A zt7n$-CW766U$3(Lm1O_7&8~kf=l)x>i|wB|fc)Ef^-#LIVG5+JA z9xqji|A-C!77iTOA=iip`t|Da9v+S;$7{9k4Xmvx60`a4$Ywx;*@E&KviW$wedm$# z(I|y+aaCt|du~QuU21oBP2QF(4yQ7oo?hA}8mnohOeT&-sP-;wex5dy=~T`u9?Z5+ zA1$&=5T0$0GE?Tf)`3XJiEKFwY`T>5TzE)q)kLphY9UQReeY5`hdSNBm{x&AgRTPsu&US*_g+ea<@#uB6p(2G1A%IMx362@oA`i)U`sRUHPj7 zRLi7S5&3FOqlpe|WQh7KjSaON)e_kT)~^c>fJfG)k#khHi9iitPITg{(!UCPEjIc`J6xt9NR-kUFmsHg#2%( z7;!g2q1?Fz=C&7LHWmVn*7C{?H@R&_>YAc((F5a7fo->QY6oXWIS!_`xp8VTR)AII zv(|eB3-mf={3QlRvH(g}-KbFISHu|A%@%*4uTg*hEY%%EyPoe~+&DEKsRg;@A`%`D z61?0JT%b)G_OagGC2`9GW(Hsk{>zWGroQ=Ol|vZ*uo?8TGn98{LS6XP=9An=wfQG9 zB8=wE$ikIa*@0?n{=w|qZ=dq`xUs2dXL~sJ@r5v`?qb78j$Yb<4~vY-M}vwdvs~T0yRwlw!pB{ zTK#Qc^*rC&_@t|mE00!IOB{ST5f3nK+X5S%CQmo+n=RLiz>wV8AaS^Fyc*c~6+0O?r9t0weDBw%ZKu>3~57-K=4 z?peUG917~gZ1s5yjDbXgQ=pc@PDPn$i@49&o@n{>Q(yOCY^E2e0U{ZKe(U^Li&YT( zC7M6#4#WVk-dc~0us86m*Z6YC>yaILH%2!-xOKVni>jg^`QBb;w4{B<>^oE5=zWZZ zh1&h(`BCtkZ_P8fpC1PluiaJMAE{5;33^W0+o%K9Ep-O3n~*|;2x`DR=(Aic+(0H} z7X2o~b^#+kW~jt8_ zm|||UHq}96K)NfT)KM|SFi1?1@^aDWP;Jw?XanFv!b2~v$7TQ43tGt=F}RnpkH*17 z+85)FM`bS|YZVkOYDO6GJ>^gV9h|{przL$^ZZ6GI+*Qjn$UMYj8GZAJPdO@dhevhC zOe*+NJqORhRz>o& zE{jDmKPfK4zb@oC8j+4}o>MxWRRW?>$PWc>BG9|&1dEUp6~Lmfc@FLvI!UFf?%F-I zr8(+hV|9nAl@=icVG8f#VIn0>D(2!x2A!iGW42QDbdFCIWBcGWM2ge&NFXsCvjPfH zzcF=4zBReYv+R*GR}pAmF@Yk5#RB~W%z@;${Tr#-zy>MRw26)S=?XSnGTlkG*s8McKbYM#j0cPR*+aRpIL zA=Kr@8b!trCct%o#z9Q65Bu!_ z2n|WgcJ{f^Vg{=eWY9Uu!Z6IN}S7njNgcF%Y@5Z|2BxLO>Fkl`9O)SQI-z zVx-X**l+k};`R00$vnrPh30WM03<~gCzKR21jWW(;ugKGT9OS=5Ud7=X4id_ISI(M35qx=ig+=ZBsG;l zXPS>{dyf5Zy-y6Nn0GKkc}2kq6g3loQ^sLL5FEa3R*yfG-k3mihoi49wy>Aw8k5(P zXvA@dSb$$S5xs0?s8B*RHfn_!(mMJ6I893`*sDw`U9SYdKXFo7ug~W>hGp;>;Dc%!tyw#);E_3b`M_ z?$eC>OC#ytw8o)A)+&iRN?yKzg*wm7wW=c(jHdOSogy{2*eXF5KwZ!0>F_i}F`FR2 z2bR3@VD=PNwVokwvcl4vI{+mSy+ds4D_;;xKR}R>JX%qgMqViWs?EjgtmF@4?Rlk`2F}o^AZPVeKUF9>a zvpb6T%Y^Q@Ytk>jaaRF45W{mQWcHa`shq_s0c|sCdyPs$H!r0Oa{H z>`Z&QiVgQZYPxO0+Wp?)W8Z*XO5ux8nqh8KLPYxJAa3tP?JA7Y`h9t0#N3Xa(Ou5W zQ1fD%`T^bVOor$HxDVOI##pIxPM*`M1HIdJj*E8Mw9VJta?`P)r~3n(h*SNxxhG^6 zcT?xq*SkX<)Y-wc6x)Q7E!d|;6o#jACoGQH_H*%uy`7mxQ=e+*1L;?rb?G*UV`%;L zOIRf-i9pUyyWOGI`CrzT^g3q_p#n7rv3#9zZ--mT(wYgx~latOC+_tLCY(Q5?d{LS>4dy zetENHr7jdjC-=ChKmnHoc9c*?c+py}K<%x^bLx|Fc6-beq)v7i)6r;nx`=hE(U`0_ zw>Ltm@$jasF*rAXV9>qWku6DR2Z`d9O7S0FG;0-d^f09(QP}F}Sd;RhVi0bAczIN~ z^lhSsrp0EYPF)!%4)-Dm4EE5gbAglLphunZ zA9RcgaFq3g#BI8GBi<|zevNkbpTdhDiajM;S)LMNfMtIQqPTzx(zXlC+Ib2|bC&(( zG6w|RdpXt~uHSg(#5?YRBdUd57}*OBdDaJi1W}Z?vrHC7fzI;OL=|g@kljKd16hQ2 zItglUNWMIvhcOR`fFc7lyfTA+2Hb)A6yLDFVi1KU+u(IU39=jO-5Ec#PD8GDHzP=E zuGhyZ-qFKj>aYZobjZlScv}X3S(XUyF3YNWFMg`IP6Uxa#`Wt?Bicg3Wcm`EVQ3gn z+BOZAYuK7XJ1F{*PVp@dMUNTaR&>aXXr5F5SImlTub^8`_@yCxw&^+Ntm@Rz^QA^s zQbv^eOQKwnuIYobPq`X6+D>rfhHfcCtXD(yVwl@r?vF zazsV;z$hqlW%<|j(y7R7Z}|VovSxPbw!$ z9lPOZtOV+5VUX@Q8wy-3g9<{-7kT<2?OH<2?4GdI>+a~q9Cxere3zESC4$q6dr8ze zu!C-c$rV$==i!--wJk9~at||zUPl@cAX}O_Lz$ET~csmeJZ*F;=dFiUU*NZgKFqeyeg2YA~XoY!CE*=RH0}H zWrZolrl!!Zx$p8&s}C^obhaazmH&nwk&sLqC4H!r2-9`=kPa*hrcSB zxIF-@3H{m9CWyl**d^tcKiu_jBNP_C1CiE}h_LMV<@gx3{ zINqtK0WC*VEfWj;(pYnOnlgL)Uo?~9HDM&{3Xb(JjLbYY9WRWPx~Xz^ z21C+8DAJql)BwXaDOchosT!n0d+<%zZ^qDd~%3w&QiYmFXyYRztJDVtA zx`glE5j`R35T2pfa_>4OxTP-Kd@uox97y4g0GD6X(zHncKbqlKn~D^N*-TIf*NN}f zhyU2%Pv0v%MyqmffyEltipT85wUWUhIt<}SBp|`tj!d*_8Z+bqJ6GUEuDwK5O48NPMyw<{Whn#fG=hmzMW5uCY z>K}-2N9*TRjnnro7CdPqPv{u;6 zq3pqI{|N1zdjq)?L1%bUp69e9cFrljNaEGkic6 zce4h!fi;v&-$F@RiyTYQr7bY((4bIKGQf$Ty(Hs$lj(CIuq0`bC=lGO+xjAIvZ1Mo zrjwyz^lOLC7eWkgB{eoimO{N59owl4xD2&>&?98agGtaM^n&6MD`f3sluP3em2X8FM@PB)4FkvnL(It z53xa!=!Do4{r8`GocD+2zUkI36zaC{EXMDD#sojb1}E-(5iLn2Y7NG9h^zsPkHGcZ zGY0=m-sHp$F(*QT9=ZLJN(*)q#*Cr{;BRZNL54OPYZ%~woY8L(kYw} zsz%ZgGy@b6)h{GEiNz`DOoV9B4%Vh|)Rl?%my4wR*g)GUpxT0^!o?4-O={^&Zb_bT z*8xHbLSkW;7(yCisoyxIths=KE_bso_6E3C2ICV=e{fw;=cnC&&nbcjL9Un*urB() zm2S&GB#hzy3DYGYVR2(dNu!ct#FZ%!9~pJ+6Vux`M#PrcBO}NjR!5k3_8vMnrrJ?~ z*q)U5vML{jLG8?0U`leAB4{cM2iSB%@DrC#G+JK7EuK$KMomLzVx%-@Xtre9RhLht zFttq^+D-bHZ>X*OCDoMCG^zh8d;geQmR000Q%}dtCKZNGhx*=kC@O4+QW>21>1E!ic>kt zCPSxRrJ#Txx24`H7VA%|i;A}98VqR%>p@yE%I`m=p(C5BA_K-`8cA*-5Uq_Y&U;J- z?c#2~%0Mpj8VH`YjhhjNNF@WD5{URQ1#K6Nv}xMP?i0Ea-DJxrGhr;SVz5JHz1QWo zpF2$(ugqWh9aek^yx!eP1 zn33h2wfT_s0BC6^UVJ~2R2#LuKzqJ7BG<=1Tlz#z>WvI6Y9K0)Vr=|I3iINmga5FY zs?ZT`32d*fs&w-)0NN2W3e@Fsq7aH9!`^+~Jt6_mnKG@W4Xna0#KiI3*4;j1UJC^U_X{wgE&I$_0^A zIkJ7Xp_NR^w5z`y8;$B*%OnH?DU^Yi$sQOK3;y!^OCeEj<3>tUihGse>m)t7h+YO} z5=OyG&DWpHUfM!VKH87$4Na!Hi zcpwyrr>XmVMW-s=)J_dppvQi!f44xiphDFG4%^|PgqotU^j%%Q=pjC4(d7!%Ia}sB zv(9gYl(RiYD|5WJg|k-}(uN`eWRDDhuNk7%`~lSY*U*X|1uCu_;5WTq27vqlhf;V( znV*9#WA;#$;3w}LJ62b!SS2_geaPw^v~3-a1yA^6#UK$<VjdJwUpfiKH!xWU`w>&BI^)0$pT4b20erM4z3F-%Lz~s2X2TELJ zAJHUg>_YRvwJjQX)#qK-P#lcqx-WWc<>E>A>hu@qE#OQEvt}>vg381MEjMxRDVKG< zbzLt9jJJA4jY##y{iN6LMsnzf5U(J@2CF0(5z(JsKuwlpmAL!u$!E3&$ zs_^aY_cEBU>H|(j;FoSV#*6{N0!nUYiqn&_T5mGf6yFOOg?(U+N{~Y1%$|e^5+Bq4 z(;vq(gqkYUU8hZW!a$4#%i^f{rvRD;F0#xpMqbn51=2gdhf2p9dI8}pf;5?w3P&4( zLs~&jT)Om2TiMG@6K+z2XKy1E`lxE?x6I1o{!`7~0JGE%Ss-NzZggkIV0p#x1`B&T z1Df-D(!;(MtTiKTa81xe{}m7tn?rJKZSw@GH21#qI&ZAb4^(Pp2J&_99aGO8NgPRw zBfb`LO55@vYS<*CCVH*Kh7fJx+8hXoj%HZGYzO*UeKR#>p+;4i+;;QgSXJEI->?s6 zD|$yg_zp5AEcIXh$^n2O^R@%KQNJ%c;{X6}Vs8~-Yzpv+LGL}gx#d#gfKlOwPq>Ce zbOwCE@d27g5ZO8sYHq@|g2YIBV42A3SeA4L8Vw*&Y`6&+auR8k>2JnzQTjo64Na$Z zGi22}LH+tym1oGd1_tla6`=I61XeWuh)T05cr>k&;LH(=2LLE&Vv-Tv)8ZMyX`-Qu z@W&ly<%EOY6~P{y8>sJsVpLZqUrVxLB_ko@R5F+383#@Eb)K8OX;cVHhClRo4R@Ok8J^gd@} z>DsM-^{AoXWG^ok)4^q++)y8f&S!p68p?G})53ObFO-G4B9tPaN_BQVh&<8ButPt^ zrOU@b3;!D2v4<7#SyKw1=BWbUiB36eEOLs|hEMr}pm~P&avrW&@rzOvqzTeC$iJYh zzZ}~GP8I0xo#dh|D2KBGn%F@p%@#zk@+qL9x_4Zb7`C)T=l*hA`Z7%x_VtNSMYb1E z0e~AEiTTs#2mBa!#+KJJD&&vjzX|1|r~4l*RQ?m{{C9Zv&pcHAy-xY}9x8vuWPhns zetYN9)BQ`S`knmz7Xj&aYy5lDf8TJpygL+;WlMZ-)gAo!d57--%X#C+1K)L$+WfJP> zZ3I8jWEnN4dp?X$SUy#=TZ$|R3^Pk~EcV+pR-4qPa2axP?tGG2hYH<*+^tU4erkSP z2UW2!`EopcF#eQ@b_*w5t4Ze|W@A}L$BWSIVSt%qb!qVI3>9@-Tj$-24*}{+l)ph( z*bHDWlrgKq8P%tAXcPlOhX{>6KOyEIzdcaCMrjq-I$@i}`@~TnPL3jO$8U~d0i1K{ zJ0BBu`js9}7>@)GK-l_KIf&*&D}ez>BK7SEL|W?WRbWPw_ov=QLFz(%P80Yr2b zurs#4;Xq#7<=X3)%OX})ps!k=TWmvmv8TsRCZ-_7&{EcI1Q`YaRDzAc%~2{SArJ!e z?1?^KHab@$Q7Q)~_f|tk&g4J2rM@_U$NUP(gn`y-~1I^5R-Tr($NXi2Ook5t~x+DLZove zI8B!Ixo|r*H>yk2>(I-ldDXfS$lY)eu*)#7Z^(}?$xDJ3aw;cNmf^dRGU+Qd{(iL|EkM4@0Xx!k@&19#K2)fG|k_CSol_(8BpGlFDk!x#c$``5U-zc155O~o+%&(q)a`ObL+#u%AlV8)Lnxtb1Y`<8S)k0=zonk`I?!qah`6-GAen2*4zpHbG7Z zDwh6aR87^@^lQvhxAwkBN)>v92`8p#STFplsrT7dB#yUW?Pydf$@c!-+^je+`Yc{# z=4qQ|sT@XrM@y>AmUdfIZm~B^#EofUC-WfU;q=%~Gjl3d_?anwLQ~eY!Yrg<|1iPT zu)6KZiX8{d+R{!`uu(zw@sdyVkz+|2(c(>V8@vijK^R$r=uqFj+V-ncT1LbIQby*goc-5&7Y9=M{M*{| zdkY2gx2$Q?CB5@)l3pj1Ii&Lq0qpq35FC8E!SYR@^K*s5Y*jz|VHjCFL?2(Y&HEg` z6M$P^yZvEqp8j`mk@eF+VS_mpMFS?(8ceW#Z;le(jyoolI3EWd<*a`}V9S#CDYREE zKOQ(E-*ReGE%Tu$;1Nfwas7By&yC{#Y8A$`)GsO)wK%KhmnIH-%p)Uh%e(WY361t4 zt)}gxK`pb34v-qq#o`l?P%$|(8vxh4wQvg90ze{Plu4?O z1(E`3H>3AA%WiG&zy_{^H}{q1bgxU!$>`w?@Utb35eZ;|X|;9o7xc{dM1^EnTxmvS z;HboGv!7K}pB1Uio4zzqBKc{}m$nE47tU7n_qRCG;SQOGo$x=RjzZyqAA1=vlrg$C zWt14FFEsdYn@npXT#!{#9MCAi zvH9X1&+NCiY6S--0L1C3QID(^vPGIJE+}ap70p33Q=U_Gu{V-syxJYc@PG{%feKJY z(AEO(Eurc7b1}Jri0VzS0-x|&uYL;i>KTHF(%ODnXm*nfSmni3+-#=D-fCfKKNi7g6N2cVT?#}4rH!d22C#ziRO*e z0x`^x?CCn)xwLc5K%?8Dx@wBukBFu!_?jlS%f&&vmvE6rLIX+EL_8dX8durMoKF=m zS&aA^4?l+0c{($vya;hc-oZRAVBmn~Q$9~4-r+qyJ^!4F@q4}? z@K80*k{X+{c%vzyoAB4Ji4{WRWnip>j-QgtoMjxQe5`D1!k@>I*=FKd9SKO;wyP z@*rSkjYK2!w5$e7j>^D759^L4}*X%n)cKe4W^A4pNh5tBOHxp6j+h78v1`&gAiTC!q*>PWEa z)e-Ii;z069&}*V{(+U`|d9E|+;qF;wzDSvnr{s4zYW<4rofDW`3H7vZ6fZ_Nqg=RI zt}TpMZ|&~gb}vI)p6XkdJZnpbQIkWh{V=vDM3Wm~F`OE zeuQ*(wfjixgaX=GQ0|s7oV-k5yJAvz+wUzND#-r!WX>@gEZ=iriO0U$?=WFX_H_Pb zOS&Qce!~E3+J_%1JqhlIzJzKW5=N*-x6f*Y?kDh$xl{1Jm+t84{@VNf+a~sZqO1Rg z4(aLsqvH4d)&F3zNB>EYfw@F?9oA^I+e8DS1068!Omr`OF1p$u>_`QB3o>|_b{6R7FI%#I)kJ)wUN@X zxxuqwcb@!}ILs%@4{u=jle=&xzR0R;pGy=5ISLC1+@%L>RahS1BPE=GMg$zO2q(8~ zlBgS-5WPrrhQ816XKZj|TnFqZfZ0%JJbl#fb7Atglz0MiVQ>ZW0`xQK9Bz^dRw0qF zd4T!jeDnpN1I6Ch68M}9zeZP5S^LcZq_L=x))5>rK19W1K{2stB4z_oh|6Do)=Ifw z?CDxl+Fg+&!Kgvu|#cc;t(B+7u0;U$O#*hp#`)9`0>OC8A!Mr^%*D#6QSLSD#4`gTf3=ArfW z*425#q;fR?bMzMdOQx|`x-@a-u)@3;KD)i|8Vw=L82_(mTlWU zZQHhO+qP}nwr$(CZJq8uZFisPd%yPv5i@`0M`cze*3R5f5w$8~BTd=RUMfjE9tp9H zn5jo|Q`(ZyQo_`;>Bo~qY&vlg#_)n(M3{O)`cDd+l1O*r^rI#weXA~2#k79PS;he6 zgfv|W;LpXB!6RFMqrefWq>sU@CPyby$EzzgoEQmfXkmEpMnIZsT#7E0C1FI7_3zC_ z*M7IUVuk=UuBr47I9)27lIZXcxZywG)D_eCsb@c(|8)F-r~ZI*V4DLt`I82PozT!(1)zRyU7deFZB0ArN59CffUlm zwXf#y5&w}?R5=5yF1y%|<^U55M|@2dl#*#32Z6uOe$m3icKIWqKBo2 z<;mph*>F4%CC1dONOJ+Yo=cTtBRnIF107*u-!2yxpjZcJ#}ksDw58yFZq(qSz?6sx z21nl%9b_$*)1t_kFlmu$OGkO$3Qt=skOYc$ElA8`Rboss(2%L3O%mNshI_KL6bj*> zDRVAOTLLI;Q{r64AZEq}f_0S)b#(V6n}+Eq8IU^@^jZdDlgv<9CgiYACCntL+ew^; zv9(}42n^R+%-E%oA(e*0ark*px=LV64x6iGTu2Y>$-K4@I zh-@XoJlnY8VQnQs!P>a_ItOTez_$lc4Y#8Y&;W<#a=*uaIY==wwUN@w62z^Z<KU+@IcSxgDo3H^&Bg zwA(6tsbPLQZh4SLOMK^1?=Z*;-XXlmlgi(&Ms>W&RBGyc*P*d*eCUWEU5YH_toUBP zE7h;SPJPv*^Wz9Kxxy~FD}T#9`Kd((-Unkt-&R9c^h5035r9woorC zk#pKg&|dtfi)weyd4XQ%Efv|96a`&^F>$kuzXkg&b5LCH<)3Q|Ve z$Cu+n3mFzAh2zlW~W zl|_eEN(j$8Z-r1p$Zx|Y3O8F&M98grqz&aQy`B#}%#f?=zpuyNCjS>g@^4nC|0W3k zcS7>-C;a~;BtJ~y|Cf;b?|k4t^3>%FElrG^q3D!c44pmfO@0oi>>O>N{w@CN&4XKZIgCuC=1|1;I`pW49D!pY8-*525Z;=fSk4a`hrU2F_Z9P$5Kkc6$Nov?+G zGd{yl&We9GDkx~@j<59(y<+=uh+$=5)PbT?G;y+XaWpbS{pc<2%8w$ z8Jqkw%E{T$#J~p1J^M;WB2K5vVHbMduYGDb%4!x^-~E6<00u;S5q_L-TrwONWC!p{ z=G#~O$w%e5!}2MqT9;%HIJa}$5EpJFQ~kK->psu6?|p^t?_Jy9+b*rwr#id7w;emX zyXUgFUzXh?+6Ttf+afQ3Zq67ggq@+(OA0&?)jE3n#v>bpdL4si+lYffy`Dj| zcMch_eywc&&r`8JC^pfU7cU~fpLb0YQ#cSb>*(H4-`Hg+9HKDix-;<_eWPMmIWkzP zbqte9s9*oU@Ic4m{!=@_ehUL!Jq?mv;8gucQKWs4abIgA@WX}p>15iO;!vcrkH*^K z$t7wDjA;j{pO3u{I;5hT*Xd9gk?Z)!T zJ2s7G{D2dBo6+O}r(x>Y^rQe#N@8YPn&KzQ>CPP1-r2$7IHb=O@UVV$`ea-ROZ5k0 zeQ|)R3;Z}*hhH>aHY^G89*f3YKL-@=j8h75m?&j3kU_x;^RLD#=~xS;ivlVKuASc- z@@i}KH(dlK!G(#BbBgw!`PcrKs@qXI_^4lIqmRkSUchGx5ExN6QPpZ;eI)(Tp-clj z8WU{NR3!aPL!o{}Y&YWighxr|==m|#55t>lh6Y!AND_nCe z^ZHmzm$BV(%S!`++J}iG4fb!|vTME(`J2VS7M7!c10Qd2O*O2mqs?2ZVkvGD%3l1W zYNURUz~vXO{>|!`dew>FJ$`!@rg3Hj>Zy07Ke-x#TGA_3iTj=E#Q@tdWot zd@4F3=JK}{>2Evn(RauFr(2t|h>b=HHC4_ff=8z6v9yVg!4*;UuK$*|7r2HB_EEvA z1wv8!J93^;Yv!Wg2vGY^(T(Tty_dy~X0tWn0@^GixPoF)y+YCITKkZsNcqJ;$P{Ui zKU*(Iok;qB%=IKSLI*Z(VBdQlqX6s2MQPLxS;~Nixc;LnF$Rvr)Pb!D9)BC66GVn! zTkxG-gIA2umpfc@9gF(7DJaTooDXV!tzVe*&+AeUFL#^FzI+u_kdN}PO+j9hiO)w1 z_FU~{#Xt$~{h@nOXN$Qy$k>R{8PGVfFjuu`bz==`^x%f7)16{9Q#kIuiLY?YaSLrYFbE>A6*c%!IR(!t?UXnT! z`QcX@!;WondG(OsRF(7+!U=#_mt?Xj?O_KzU*Z0p>A;fgk;YI*d#0FzS{vpFgqZpT zC|8sUQ(y(LJMgE}xuE}srl>(+SS`A^G6#qyoc&X=e zEn1Zl5QZqSiSiaEzCCnb=hIhF4e7kVGYmn2J}iqp(w>~)9@gj!IH-LDD8dS3b>!t| zdv~8|BDn94h$e5tZ`x=}X9i&;hKig=a8jcKt!C>4S|I&{a7fbJLw1A>bM-^-=~uUA zaiuYkkai7C2EDN%lV~}Ys*8y~;YX%y)5U#^ft!Fr+wV#prV#Z^q^$;`Dd~e-pb;83 z>4}twx|NgUs`imw*`Y9Ov0^*}4@wM1^F)$x1`JPPK1K%Nd^|vqyyHhSjKsDDjsT`C zbfb!T3%~8eZuGR~*|2yPob;%4oYDBo-be#EuQgJn6^~L@uFbzs-pM?>ZwWrCe*Ja) zLdH>STvo1Jqw}kHhU_h*-cq*pIT^Ae;O-zAQ}LO)QVj5K;~-c zqvdZlgj{oi61L60pZU;Wid{XVzjn+00$mCQ86z-Wv-kdaIE-7He3;U!^eN;8+j-l} z-z)!1wQQe*r6o()m6rdh4ZG$MSB55Asw@L5b}7sSqGcI520TAFi5-S?v$oy`5$!qp zom4){^qjXkduevX*8(ZkzkI8h0&}ed%l5nY;$YR_NePw?0YwJ3E^ta>F|;Do4Z89` zC71S0a7NIpG&Bu5xJjY%;ARY1c}SO^W&3)5XxSb*sKCRZ#RKwh+i-Z?$lltO3(iyJ ztjm1SR~^k$TT&ORd#~_I)7UYlqh79an8+x84?1_~Ltnu~%fthTZy(mfG#cO&{S8x~ z7Gls#;F$T>T3dIsJFn1#1*-$69=AFz8Yz3y-ILBOLd4(H(lydKv3;GIkwE_ruwf;= zrcsCv(RsH4mgR368akTXx&6-MiidIcHtU<=9XiB&Sia!JzTSh9fd>-XU6z645u%Mo zU}V8Y=7{cn2I+5DnL3$VIt2&FZUc;PrKs~jp@8w$p*VuuI$L*}Tki-rx0uczcM#2B zv@cwc8n*!>_Ydq$-7N0B1?vQNsz76_o^+O+dR63%id~LkY9+x zvQvzZ^MF_`ySGN}@4vNlwYc>T7pkhy3BZVkC1NKEoDh_ELE{e2?94rF?!6;e>lm}y z7{94%{D4JH$-?;CEBSFb;KrYMX$@6&%&sdDz@}i$Rt)R)w&00kw4P zGZcS3{i82Bz-<*}szg)fa>^L{`WgDGAHnOs{}Jr(nnFMa%b>K;$Zlzr?1IicYShuL^Le!HXy|Or1h`9 z29#)oMv;IrH!FuWR}ju=-62warT*C-6Fa3z2!#Sxtumc}7Q-s0ot@mt+} zM`ZENG3~0m)R$8l^o3&B9BScN1U{;Rs3+8^bB%|D*r zhD6~;{^_ia-ZYaPldwTQWC+_UvE%qr9N2pS*~}S}W^Nsd6-?7QSR0`RYuxGC+>GU8 z8OBveKPaYN`sz@jC=C~p=Gbgdj0ejagds63gpry8WN+M-xeYmh21Wo@=MgZh7wsKq z<+)@;5Oye&Jv5{08!^iNU5uKr6LEeJad?*+&93DW+kU= zEYlhWOTlL_!^GK{nG}g$-Lhr)`Le>> z6gx-;$7q8qVjhhl+SqpUguT_{c|4lubuONo>N8X z6oZtO?e9xjzZ2D%Z9i_h{E0Wg&5plEtxXEk6G8YJvb%5-ixWxo2OiC!E)zh^28u=O z@+u%^3x_RcSd=zZO76Y^x>889YP^K6P-Y-1 zgKK)TaAk2KAfCb{7X_dO{iY6Frcay$6obcM%vDpYv-gay$6EawhT5_ZYs82uC6}0vKwM3oH;!zx8dV?!|^4AD@SPt)<+lPbmdHppG z;OKTO+sNs!A51{l?jGD;c0f%h7x~_djpaz*pI<@m8q$5MEXX9wm3`wihnj)X`D(RdfGS6#{>$wrQ`c9r>i)g~G}!=@n805=#9n5BrWGVy z83aspb^7fQXXm@$>{AFJx^F%sv|k1k8>pXl{xxZZJ;JePkb{>Xq-ug^lxP3nD zKfd_BpIy1|XrjEEujYPTPc&{mCz(j(BCQMb?0r7o4blCzEtv7DzIa~xm8RMg@}$>I z1554!L{V<~X5qs#&SWmIOZ(B*2kH0mr!DXM_HO8p-(vcbS&#Ui?IFwMJsjg6zh5dG zTxr@N7wDU1)HjL7?vZBb^oTKNRu64@^oo&APf<76CAAh09deK-C2$ z^D#l8L^R<?~_+9AB|K6AR6_bKSvp3%tQt< zB?8ct$cg*Qg#s$02|*bw1r)YtFAK+QkS>L7Jv0XbE$8w}_yKZS==*6P+i9d+bY(y^ zhcxFM*XECek548o16&DDLHPTSN)c9>efBTyiH!umWy_;C_wbQpwutkb>t+|^>nqWh z!vq_1EfvV;ao8*b1g=3SqM3!4SEhNTZFr1BZD1?W9-WcJ*A?Cn*Hr5)ilT+f zFQoPa*jfnVsq}f&Y4RZVDz@-B3G?g6w}^Y>>pwXN6vL2{62cQ2SyMi()Z;7Lb_P%M zzDwvKz?M|v49Wx$prhh{zlK`$D#h2*N?1zy^W$g~Y{I-3w=+4Tpj712a5hrsA_uy| z;3D-_QG>dXYG?(J#&bC!_m`${2%pwNC0DrRoakVt`5}VtrGV)$AQAevC)eym2WK9tRqU z=&U`$wy6^=YP~fH18qlaeFfTY_(? z;aKP|h~{d6xkzrTl4H|oo_Q%O3NuUOtx394`ibdwI}~Xb$221{|3(e$wQYB+(M`@T^y`; zv>2e)c4T90V%PN9SSk4WTH&o>;Fu&vN!12Tm3*4#B@5&p(Noll;;72(9r>BQCr{+ER^W&yDlr*`#d)mewEPj*}%W z=Og}z4Ei9{L0!O>l{uz>js-W9fGvZkR?k1F|2oV~Ev*{X$kWN-Co9uG2~E2yyCNqN z`-}ki?+WCA#ZoF4f1_p2Nw|F9sCTi&|_WFE|fv4tOA^c0GM>6p%Sr zvP$EZ`;FXOP8E0FdkukOg*RezZiuSsmh{vo*LHI==3kjo?Ui>&M$#Ykfn<>ZairtS zL_{JeW>_`=78YoiLW`BJ7aT=cCb}u$;^b(Xv#>&5-m-3F4~keKob%9T3;~ejF_p2i zq7bVSR!$Inab`1BIOQ4|nG`18WmLkfGDR2d&fpa?v^;OcE6F_SX;2PXStXRS3}&WV zny$e8C9oK(gnd$u7!O%0?bh^U{q1W$?2dhPufjyy%xY|X$)cc!2d4M;?kQg!hKmx( zDb1>ji(D}Y#vNS5aFGq#Ri4;V@B=PVo7@`>S!3I5Ry~_ND+M3wsz)XF!~;6Sm|O#% ztEjV)5sV_89D$2?tSjR=xKgkKm}3xoNy=>#MHUo*A=i@~A`P3z4v<;Bpo`y=npY)D znNbmc(HJ$HQZg}-R<`?<4|+TtmEUf-cy7RgUmsC6ld&!#s8n8%86c6Y)Kmci5gD42 zAI%~~nS#oMuu7$BAtx9;viPI&LpQmWGN`l~SH8wB#kzBkP9>*5y%lZO*)9@_P4 z#;aljrWAJ_a4Gn9v8<>~X-}x-2CWfc>G$wxPnQi-4m753(8-Ny03ARGXKQB){{(zm z{z-X;_d#vx<)a<6Ol6UZ2|;8^C==jtDcr$L!`d*Qm2reNemm!yntb9|p+zzb)XG`w zyYoERzy48KP*?B#4rHK@u2rjwn5g`~Djpa&AO_A3u1t2(M<$+GHt?G&of0c@D&)X| z!v=6dru-(2nUV-z6pNFTvC*sB7E8qSg8Ol^BBk%c<79?}uuVG)wQt!3_DWT9_5A9r z%BXwO(Y4{^Qt#NXvq^8W^fL_^nB0^4Ov2z`>9maQ^U(p=>wEzws2xUli#b@EoeB85 z*ut{G#0M*tbv zC4iS_tVoDK3-G>R^TGZb(`fj9mybEbfUs9^qxjx#^v~fk;Gk;bY2lg8=G#gPR-JgT zQDx|NDu+t8E=mx{OXXY@MprT#BrfNpr^#!T27r;2g-}i;LSi!E{p!*oCei$9u9@s9 zG2RRF^f41ZwTM^;QKc8#(hogt*Q{$wmr?NlOr2d$_U? ztP%)wxR~%Iuw`vHFT61Z0mBYqYBmZ;H;#6yx{3|L5vlELS1?I{m8~I?74{#c)vp9P z5=C(f)N06|w}~XW%8*C`X`Ka$y5IyqDu<{NFZ09L0Ff#KuCzq~ys6J{wyy6V4h)>x z-&W&bURKT3Q{hifS;oaA4Y?VD)JV7iU{oc=v@8@TNCB*(eEuC0FtOaRchPb0v&r2I z`KcQ~s2n*hy{bo`019zBm02Xx;-;*|ugnVyo!kX!!TXn9KWY89vnGEY;IE+ll!ysW z-eUPyx+Z?*ds~VdalG}(ondvn{ghg4UifL3H5QcfQG7B7X!{~n(|0z1Bpfo~Ugv)L z%Hq~NOb)cvlWsv-hex6g3@!OE`o#s8^6b$eVw!bFYXRmH${*S=qzT(0ZB;WL;&@j_ z=@>GL>&?ii2x9t9g9ubS2tH4wl#5Rh+{rxCR^QL04L>>x$%0X2fx$RzwK_Rj2Vj`Y z!?gp`sYr`Zc!jES2#K-sM5*7cMY`NwP??=e#9sRz2)g2_vt)xhhy~g%1RTYGqzsi` zf@B#`RRoRE!8tK}jVGZNZiN7-5YVx^P>!!X;UTt8$8Vf3>86ueA6E6-$ct4vb@DF{DNw=h_&3mquN_)M^N z=o{5t#1(P?MC~m3W#!z9aC)nw1AkSA7MC@YQ?PpD$KpvntEmA@6}hV`ION!1!x7?$lQcKH1=zO zAh301-}}%3@?s%WyY=ozsDg|KOZF;UIH#rw4o*4PCM%)$5z$N>H00#^F3RPzJ294x zii$udLkV;G5&^gFO0^dBEt`9#*d64{G~e-pyjL7QJ&xj0hm|*rVQE)TF06+ zrt;p39X*#$dx;hj6ylok^nJmOd|p3Ei7 z`pRyyUZ%@3+5jG|SJR@0&=s9oiK=4WZkH%!1s!>3J*uSnR(Bctm2+N+XZc zYKMq~^eHQkNMU#b$bd*i(|{5&>Oy@2i80B`%TKYwFD>PRp&Mm_$fH3{B30Rnfg*g- z#tYqsYpBaLwGhRw`b~)IxegR(El0mOd6P8GbY#tWnpp#G0ceqPN(;d9E1jYBTSFAe z8t{goP#J2$qO|bY5eJoBHo4_dS0j8YvGD=E!FEFBE0avJ8yj0GmjO@!u+f!2u0h^6 z5W+;jcOov~(#T2w*urzCEG)ze$@8=sEg{HVCX`uo7TlU3m8QYyG(;M29E=CO0~JOd z{DyhUKVXbeQ zi=y6+)yU|SM(`1j_+ZgKO)addKQKmyEoeJy+dlb~L5F1J2G+@2^AkVO2^Sf~tB7lg z^VVo>k7NZ%yfm>!6BCG^bsNfMjh+U!m|T6U8Isr$-0@;m2CAc4xhvQe-IvQ>ArT#g zx%7EJE;~AaU{S2MK==IJwZaiMaVZ@jWT|?0K&Glwv(5 zqJCHgr$$xNkou@(UO2jGB6hTR(KsjmgV~Ji^8Cv6{BV?AFYx>q-p(PMbCxqbDB5Cw zz60SBNg7bKDUnHbiNNHv(ix<-Or1z+s9=Q!fcRfo*7oVi&XB|X=113q7Hh0r57UZ_ zT%*t`O2#8R%AUby<>ulxy#jv>;VV?VGT;6?+_`0pKi31%SvQM}jE;dZBLH9~W_6*{ zk7NEd%Ta$6TAP!hLM5F$_xG9fRk@L44P<{awuU-iu6fh@PVK&DTpsn*`!97g81MMY?4Bbk^xG(3J#X_{en&Adx5K5+MO;RL&Swv4b zhJbyX{`y9)h?^Mw%JvGA5m=%ie<|)9(TuV6zL{Hd>bo=TzJs>&FO0BSSf!aJF42UH zUjlXDq>gKQ2JWMWGP!^xS(N~2vKR`2EM3_Hna%U&r!H~JZg_|T%?9l>?b_7I$oo>G zmx)qeyI0&3?7BmCJ^iKDuBHsL*{D(SuCEI{n-D~Q1Bx4U{P`>NEohMUGHM&I!8VbA zH=WNJ`|za`5rGAxqsQi_*MQ6BEpTAmq@|8w*s09G2%G}?v4TpE=W%%{4U^;}+>>QD zwjj~r>8u_RxJ0thaNw1fu!`0_5}Ol(1x#s(y67HIkeZnEt(+po8kJE@Q%U5M6pT-S zP@scRYvIno$Cnv_cY}6~`AN}+2DlSOJIZV0tB`Y#6g~E{Q?(Vg0gUXu=Xr-11+ifG zvki06#3%2YHAT45qL@Oh}4cLyR$O><> zO=4G#Yj7p~OMtg(a1wn=iDJeyWahljg)B&sAA6QIewmnt3slMC(wH^9Xz%V81v~cD z)me{40X71Om{DwhNetvc-{;>kv$H{y!(*KeSxTAzFyxTY$UP3nX3B(Z2Vq>EBw$IZ zDGe=+Jq2%e6i^O)pW*Q*U}AbYO@NWfp#uXla~$6u|DiAgxDh+ah~Wd!5h}oEw_*WE z)#!ZlFI0ekfh`564CA#G^|Z;ViC~Tcw;(a$s4HG5!)ZGcU8ZeAxUl#tjEA^px1sUd z)KGi71N`vJ@klZM;A}-`RT)Iay|E!O+~{7F;FgLIz28;QU_ib`8#R6wWV>wX(uIr6 z^k)5IIhKvRG;K@G5Hr>lN@;!QZ&AV9N+NSGBSBD9_n{8h@?*_YEhecletf0^sotA0 zEM_8Q-UKEF)zA=+?5K(bCj(15yWNh&e-A=I$>KSRqU3J`awQVrGnUfwJ(Ob;ShJvU2S1;#s-WM9j^xxPC(3t^&r`U=mF5htR?9!pW9RY{+!Q z23`l65Be{K$uE$XqO(y-Ls$N0^ci$-17?yl)-}f{H>Kt2?Av%<$_fh@`+%k(`+Cao z!BBtCabvN^NH5eCiFv)qV4q;bDs%TGzTJ?}m%K4}7${o4>1J#{E*7-MP4h{i_LJaA zm*YQOJMKsprV?P%Ln%DcZ|4S}Fgrmah9W?Lc$vSr0H28S~g#h@7>KQ z9O*b#vqT#9U6O_lK~NkFv;f>MZ|R29O%jA{Xt~t0d?VKG@=+s*szGc+fewNkt~zN% zx%Y$%a$Sk{5b!RH>o&xlCmV&cnRLhxirRzZqp4}2VKza5EEI-Dph|3$V^x;jJ{%&d zV6+=EW4F5koqkVl3~4_CK_`5rzC`s#=gEkP(-e95J{HJarzUI>jueDg&Zla~Sj!BU z`q+@VFIDGhK$OC8kdFikxy{fKYBZ~kXAHJrg+OgVHWQAE-HzlLIWDzQVtDreB&VSV%#9&Ev z(Wvb&(^;vKlNkMs{IE* z11c&%>OlN(UKvsXDuQqlTUlZrQ-!&C^mdCuB3&a|Aj1gqTCF*o(5Z)Lkn~La$}7~6 zdkdDWNwmBbW*_aF>k6Q}%zgDvc5CtbEG{szyC|)iA7(!A;QJ8c0+6Wis0K}+eh1{i z>DL_v;vl9Pp}saWbH7{mwKnyI%)OQ)!+tPe<`*+5Mq({Usk#PT~Rr!}k&nh}f2__)!^veh73L_!5jYWmItWCD+)eT8QQ z8ZPmCjK$RO38EsP!Ki&C&;g+^jfCdXAZVeu3hof_iQzrf0Xr7tC=kOvPpBZb0q#b; z2RGG_6uTliIq;wcN^Dp$K2S#hTHQPX6tQtTfyNOr#R2$%LD+Cl7jNj8piQ!VS!9wU zlTA!k7TGan+8Q0Wvq69ubN=Q9tBhKa<(nxRVyG^>;sfA9-nnHS9Foh6KO1lj-@zY6 zyF16hae8G0)K#uVC=zx-Q=|(b?r@2^-f(ObF7YoZYt|UfS%`&HitdHpTV#RcN#f54gwEIywQ^l zUGo{@Gt+hWUT>=u%b?EMJ3$wXK7Kv7x6vNd#{JU4?wssfqWVHu* z_J_1G!&z+XB#>&RHIVco(J{`cbvFHOs9jDg!q0sHrHz{I*8B|0ko*P0gZh_wF!Clf zX58F=BFzfNa)Xz;(2!BG2T6`V?=wtHxnjy%4A1%7LNxlI2Rm?Sg0Y??7&sZ@T*=nV zOb3udX~gCn-9t14*dGTJvaawssFnf?!$qgdyT68-Me$ZVTZ$i2Sj-oY46_1-f?cct z2Vq5&4FmG|bih+UGEh)r)5h^}oJ7cQ;d>(;wt{onMeQep@nM`@srD1YccX9HFVY2$ zElPkhNfqZeV#$H7xeJDbeeA?%e3N1quyh4b*prk_M#4ipKB!}c2$O7j-2+O{vyg1YCTw0Il0-aE>&Zbynh zxgV!aVc&jRog_Lqb6;bX3Sq_Fhkd;>SKT>vGh~WPjv^kK0I+#th~axxTVgTp0Dm{r z;RcTHW#60zBXqdFaA`J(yC2j6J@l`VDi*|Yv__?;{{^9h;FSUlYF#)30yLhj;43Jm zmm_1Cz$K99g`Zk)oGI+qD5O7iUu`1!wL!0eINfzxw|RugoBP3Qgng$edYpCCtsV9y zA;EGQB_1+(nCI>O41M z7<;P?b`s@98^nQftL^GCWVh5wC!@`4gD;xFzkr*TFzr)%#F+TD3mH5Si`YjeWfvJc zwJ+oJZH-fR)bE73up5_;F$xRDN$XorfMs#p8}mUE)G<&`AljS`TR<;67V-kxcDC46 zG6EA;=0)3cM30p#^~d!hC0FXDx;a(O_{)V|?xN^-AZ^C)#jX&Gp9~nCv^j7bs8(%L zS(EWQIK-W_Jz9bL!Yn%B0l(~W-<)->@Ud#8>{2UAj;y*pr7+jCNPt=5D<6O~3K1Nt zxM;c0cZ@y0)`~G4)7p*(udLW<<)Kg8nMcca95z5H?QuNzb$oKC=5efU^TBc*OWP1{ zi5;WMjuvl?NpRCbi$FYSZ8EzA=1T5vkhs%EA2i%)7*4)KMLpMbHAaHX)gNcA(P->oS55ymmFAf;iB!GnZd!<1lxWr9uJ)L(^161 zLpN-;0upRgw*xNfZ!h|tdt>%xAzPa~=-01L2k7I@1Gl@p=-a(y!AFr~wgVCZ5AdYv z^mW|ny;+RB=zG%VQf_xPc0vpc_nr;X6@T+iho`P1KgUs7lZhTbJCm6b^NCQ^0&iC% zgDI)ff zBSe`5*4fa-lcciow?l#$sX{^BAksW5L5$q7_Y*J$>;ooan==w>A!7ot|jSUr!ViaU9BN39I%1cfOdRoP+;hFf> z8qb}G+qm;YC!X@+aaE3qDz2 zK56oPFZ- zucSQ{PV#>0{U4v!m5r@K>H-AJii&j9Q}{K@c5jMSD2jOt5x*z$TmHbEGUQZxl4%<$ zx6etWyfBO%dk<}fE>-kkZs+|GJk`k1sckdVz%lF=GAX0iz*>+X5M z*(9o6X@p2=RL@~rK#Uh{&fcL=hjkfM!{O@7+x_U+gYfH^0&#jqzH^!$5awGiYBtMt55h*(kt#6>`_aqQBCC>l`4$ z9_=*}5{{T)+6IMCuZ{8))>J?E<2uyCl7312c27T8b|E!yCP>qRVicm2smdT?K|Rl{ zlGZ-u7%8Rd|C|hd8iyD*-fNS_qMm7MFsX2aFTEtq1iPPek`wy-N$ITpomghvI+IBb7b#h&Kk4K3x$SAW-Ze1L1o-{Kis zQTMfGHAVB}&)M@w2=|B`inyQm^G7I%y}40l7c#Y_>zqPSJ@JbhVPT_xlhgpEDMctk ze=h8j!+c15`LwhRpoL)qu->utu9H4--j_4j}&=(@nPo(Y!~uz!|(>YF8K#t}~zp%=B@WFx(}*8Zrs3tYB3jZncv$ zH!YP2#H(uDbvhb_-)V#ZV{ry|iOIJ%t~T>{E98b?EQMA3_Sso>jekenKsN6vs?|Jg zPK?n==$rxQK=_^3YPZorEH=9ZPyfe0l?a%U8EApjxwnn$BgTvFw8iGPvjqT z6Zp$+pJdmTds9X3sgmpX7%zk#CX~8|)Gj(xz11y&bg{;*@51HBmfPB-A*HdhhACzv zj(nS5X&n?Dcu1F39AmMsRSA!i4k^||(1aeZJit~DO6HpBX zl^B#Vru~kVH>wKnkLKp@F2@a68{jJnsDARUaHotehn1L~veP*fc$B*xN62h$E;nmr zV9-@51*w+FdMo%clOOoxHi$i^fD`C3>ua=HA%d6fUBD(c5zgS-b&*3_DX<1b_15n< zQt5ThWqS5`Fy@GrIMjRwcg{};n5^%VD=!}aNEf>tHH0`vUcX&8^FjF!P7Tvh@w&$& z&1{+BT5$Q7QoDR4(+WmZm%at~gjt z2-KSssuTS|vfKky=;=-Jy@+BfTSSLe#0c}ltC8+f7}Q`zG(SzTL!CuFDZ3m%^Ma4L z-wIvtzPG0ZGM*!pDP1;h&}w0ih7KcHO2*tfFO}(G>=nAR3PDI&GmN!tNbI?#;w+ea zfq`2E#q>2;c4<=6{2rj&9qaUn;o0JRE)VsZFf#|H^j7AJYu$tmT)1L!74p8I#H)7a z$^N!9tJtqf5qI0F#(>Sad>gRkz_?5De3!ML=4-fXX{1Hz1uYcwt!-qayF{`Y?MOZa zq>-iwu4artUoWIw4l9N-R~6`T!6POAygwAn!9WI_BnT5rVi4o6BzRB|Gb~DB zuocFpj0=oOoy9jpidaMmgn4RJ6hnIx&XU_(b0I{kaAgQ{NsX~1J{0OeW=uc<4^YEx zFe4zQSz@fzl;a~u$_#lR7}2yDqP(AA6NLo>8CX39he()dP6x5sYT9<|=&xwRUjt<1 z<7RJORqcZVc}2khpwIFm%0VVV~{g259(*K&PlXMg>)MW24A@btK?OZG%#A~Cy zJ`|JXan!LIm1`mNsVi#DMLap5iILYu01)y|36a4ZNWZ^Nf~KK|p!f^rsw;nb#bm9C z)E=qHN+Sld%i9$v4;JvoG1mNgy`V|TzSW+JG|YB(P%N}w7%2C@9Zb}dS427zNLw>H z;MhR9Am)rcl=jYyj64%5pR`TYE6^;C+H03UsW<=pv?vQSFQ@qvAmDPU%}Xgcw*2di zd>lG0g6^QY@d$G+v&Nw1gu##=GZv_>BExKmHip}YP1QO^TWqMU1^F2EDqNp9sp#KbA8c09_Y5GZ^i{*s zVy;p)67?|#>nDic`}t-%p{SxlxG!W)Fd)cIZ_U6o(njlB9;Re@D5Nk3T7HS096c{F zKSp(h#Ti!Ht(1snx-o+&BuqVZzXkpR!jR@Qu6`YLp1d-opGQ)T5|C+1MjCAv_aK$Q zVP+8M3Uk9TSSLawoN=M0l{!GX&PvmY{UU)K$hZHs2g)tTtJOa3?*(L!1bh;tutB93 zKCcyL6bDlg7MhJo>gNBg?&P=?_pmHEjWec^3gw^#*idl&x8LaCSz4}#XCj#P$6;7M zBT^PI*}vF_7%Gu%W#r|YHn^4hsa;AIY32BMx0LY_oiyDNMy935o^gw7@CG3Md6M

  • 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℞AMkzQ=&V-bWaym-?9j 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%0ARD|WAUa-^)bZn# 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